New Angular based web version #1
@@ -1,166 +0,0 @@
|
||||
using Ductus.FluentDocker.Services;
|
||||
using Ductus.FluentDocker.Services.Extensions;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace WebApi.Tests.System;
|
||||
|
||||
public abstract class ComposeService : IDisposable
|
||||
{
|
||||
public string ServiceName { get; init; }
|
||||
public string ServiceInternalPort { get; init; }
|
||||
public string ServiceInternalProtocol { get; init; }
|
||||
public string ServiceInternalPortAndProtocol => $"{ServiceInternalPort}/{ServiceInternalProtocol}";
|
||||
|
||||
private readonly ICompositeService _dockerService;
|
||||
private readonly bool _isTestRunningInContainer;
|
||||
|
||||
private IContainerService? _container;
|
||||
private bool _hasCheckedForContainer;
|
||||
|
||||
/// <summary>
|
||||
/// Not null, if <see cref="ContainerExists"/> is true.
|
||||
/// </summary>
|
||||
public IContainerService? Container
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_hasCheckedForContainer)
|
||||
{
|
||||
return _container;
|
||||
}
|
||||
|
||||
_container ??= _dockerService.Containers.First(x => x.Name == ServiceName);
|
||||
_hasCheckedForContainer = true;
|
||||
|
||||
return _container;
|
||||
}
|
||||
}
|
||||
|
||||
[MemberNotNullWhen(returnValue: true, nameof(Container))]
|
||||
public bool ContainerExists => Container is not null;
|
||||
|
||||
public ComposeService(
|
||||
ICompositeService dockerService,
|
||||
bool isTestRunningInContainer,
|
||||
string serviceName,
|
||||
string serviceInternalPort,
|
||||
string serviceInternalProtocol = "tcp")
|
||||
{
|
||||
_dockerService = dockerService;
|
||||
_isTestRunningInContainer = isTestRunningInContainer;
|
||||
ServiceName = serviceName;
|
||||
ServiceInternalPort = serviceInternalPort;
|
||||
ServiceInternalProtocol = serviceInternalProtocol;
|
||||
}
|
||||
|
||||
public string? GetServiceUrl()
|
||||
{
|
||||
if (!ContainerExists)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return _isTestRunningInContainer
|
||||
? GetServiceUrlWhenRunningInsideContainer()
|
||||
: GetUrlFromOutsideContainer(Container, ServiceInternalPortAndProtocol);
|
||||
}
|
||||
|
||||
private string GetServiceUrlWhenRunningInsideContainer()
|
||||
{
|
||||
return $"http://{ServiceName}:{ServiceInternalPort}";
|
||||
}
|
||||
|
||||
private static string GetUrlFromOutsideContainer(IContainerService container, string portAndProto)
|
||||
{
|
||||
var ipEndpoint = container.ToHostExposedEndpoint(portAndProto);
|
||||
return $"http://{ipEndpoint.Address}:{ipEndpoint.Port}";
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_container?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class AppContainer : ComposeService
|
||||
{
|
||||
public AppContainer(ICompositeService dockerService, bool isTestRunningInContainer)
|
||||
: base(dockerService, isTestRunningInContainer, "app", "8080")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class LoginContainer : ComposeService
|
||||
{
|
||||
public LoginContainer(ICompositeService dockerService, bool isTestRunningInContainer)
|
||||
: base(dockerService, isTestRunningInContainer, "login", "8080")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public sealed class TestAppContainer : IDisposable
|
||||
{
|
||||
private IContainerService? _testApplicationContainer;
|
||||
private bool _hasCheckedForThisContainer;
|
||||
public IContainerService? Container
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_hasCheckedForThisContainer)
|
||||
{
|
||||
_testApplicationContainer = _dockerHost.GetRunningContainers()
|
||||
.FirstOrDefault(x => x.Id.StartsWith(Environment.MachineName));
|
||||
|
||||
if (_testApplicationContainer is not null)
|
||||
{
|
||||
// If the test is running inside a container (i.e. usually in a pipeline), we do not want to mess with the container, just release the resources held by this program
|
||||
_testApplicationContainer.RemoveOnDispose = false;
|
||||
_testApplicationContainer.StopOnDispose = false;
|
||||
}
|
||||
|
||||
_hasCheckedForThisContainer = true;
|
||||
}
|
||||
|
||||
return _testApplicationContainer;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _hasCheckedIfTestRunInContainer;
|
||||
private bool _isTestRunningInContainer;
|
||||
public bool IsTestRunningInContainer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_hasCheckedIfTestRunInContainer)
|
||||
{
|
||||
_isTestRunningInContainer = Container is not null;
|
||||
_hasCheckedIfTestRunInContainer = true;
|
||||
}
|
||||
|
||||
return _isTestRunningInContainer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private readonly IHostService _dockerHost;
|
||||
|
||||
public TestAppContainer(IHostService dockerHost)
|
||||
{
|
||||
_dockerHost = dockerHost;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_testApplicationContainer?.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace WebApi.Tests.System;
|
||||
|
||||
public static class Constants
|
||||
{
|
||||
public static class Login
|
||||
{
|
||||
public const string ClientId = "vegasco";
|
||||
public const string ClientSecret = "siIgnkijkkIxeQ9BDNwnGGUb60S53QZh";
|
||||
public const string Username = "test.user";
|
||||
public const string Password = "T3sttest.";
|
||||
public const string Realm = "development";
|
||||
}
|
||||
}
|
||||
@@ -1,301 +0,0 @@
|
||||
using Ductus.FluentDocker.Builders;
|
||||
using Ductus.FluentDocker.Extensions;
|
||||
using Ductus.FluentDocker.Model.Common;
|
||||
using Ductus.FluentDocker.Model.Compose;
|
||||
using Ductus.FluentDocker.Services;
|
||||
using Ductus.FluentDocker.Services.Extensions;
|
||||
|
||||
namespace WebApi.Tests.System;
|
||||
|
||||
public sealed class DockerComposeFixture : IDisposable
|
||||
{
|
||||
private const string ComposeFileName = "compose.system.yaml";
|
||||
|
||||
private const string AppServiceName = "app";
|
||||
private const string AppServiceInternalPort = "8080";
|
||||
private const string AppServiceInternalPortAndProtocol = $"{AppServiceInternalPort}/tcp";
|
||||
|
||||
private const string LoginServiceName = "login";
|
||||
private const string LoginServiceInternalPort = "8080";
|
||||
private const string LoginServiceInternalPortAndProtocol = $"{LoginServiceInternalPort}/tcp";
|
||||
|
||||
private static readonly string ComposeFilePath = Path.GetFullPath(Path.Combine("../../..", ComposeFileName));
|
||||
|
||||
private readonly ICompositeService _dockerService;
|
||||
|
||||
|
||||
private bool _hasCheckedForThisContainer;
|
||||
private bool _hasCheckedIfTestRunInContainer;
|
||||
|
||||
private IHostService? _host;
|
||||
|
||||
private bool _isTestRunningInContainer;
|
||||
private INetworkService? _networkService;
|
||||
private IContainerService? _testApplicationContainer;
|
||||
|
||||
public DockerComposeFixture()
|
||||
{
|
||||
_dockerService = GetDockerComposeServices();
|
||||
_dockerService.Start();
|
||||
AttachDockerNetworksIfRunningInContainer();
|
||||
}
|
||||
|
||||
private IContainerService? _appContainer;
|
||||
public IContainerService AppContainer
|
||||
{
|
||||
get
|
||||
{
|
||||
_appContainer ??= _dockerService.Containers.First(x => x.Name == AppServiceName);
|
||||
return _appContainer;
|
||||
}
|
||||
}
|
||||
|
||||
private IContainerService? _loginContainer;
|
||||
public IContainerService LoginContainer
|
||||
{
|
||||
get
|
||||
{
|
||||
_loginContainer ??= _dockerService.Containers.First(x => x.Name == LoginServiceName);
|
||||
return _loginContainer;
|
||||
}
|
||||
}
|
||||
|
||||
public IContainerService? TestApplicationContainer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_hasCheckedForThisContainer)
|
||||
{
|
||||
_testApplicationContainer = DockerHost.GetRunningContainers()
|
||||
.FirstOrDefault(x => x.Id.StartsWith(Environment.MachineName));
|
||||
|
||||
if (_testApplicationContainer is not null)
|
||||
{
|
||||
// If the test is running inside a container (i.e. usually in a pipeline), we do not want to mess with the container, just release the resources held by this program
|
||||
_testApplicationContainer.RemoveOnDispose = false;
|
||||
_testApplicationContainer.StopOnDispose = false;
|
||||
}
|
||||
|
||||
_hasCheckedForThisContainer = true;
|
||||
}
|
||||
|
||||
return _testApplicationContainer;
|
||||
}
|
||||
}
|
||||
|
||||
public IHostService DockerHost
|
||||
{
|
||||
get
|
||||
{
|
||||
var hosts = new Hosts().Discover();
|
||||
_host = hosts.FirstOrDefault(x => x.IsNative) ??
|
||||
hosts.FirstOrDefault(x => x.Name == "default") ??
|
||||
hosts.FirstOrDefault();
|
||||
|
||||
if (_host is null) throw new InvalidOperationException("No docker host found");
|
||||
|
||||
return _host;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsTestRunningInContainer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_hasCheckedIfTestRunInContainer)
|
||||
{
|
||||
_isTestRunningInContainer = TestApplicationContainer is not null;
|
||||
_hasCheckedIfTestRunInContainer = true;
|
||||
}
|
||||
|
||||
return _isTestRunningInContainer;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_networkService?.Dispose();
|
||||
|
||||
_testApplicationContainer?.Dispose();
|
||||
_appContainer?.Dispose();
|
||||
_loginContainer?.Dispose();
|
||||
|
||||
// Kill container because otherwise the _dockerService.Dispose() takes much longer
|
||||
KillDockerComposeServices();
|
||||
|
||||
_dockerService.Dispose();
|
||||
|
||||
_host?.Dispose();
|
||||
}
|
||||
|
||||
private ICompositeService GetDockerComposeServices()
|
||||
{
|
||||
var services = new Builder()
|
||||
.UseContainer()
|
||||
.UseCompose()
|
||||
.AssumeComposeVersion(ComposeVersion.V2)
|
||||
.FromFile((TemplateString)ComposeFilePath)
|
||||
.ForceBuild()
|
||||
.RemoveOrphans()
|
||||
.Wait("app", WaitForApplicationToListenToRequests)
|
||||
.Build();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
private int WaitForApplicationToListenToRequests(IContainerService container, int iteration)
|
||||
{
|
||||
const int maxTryCount = 15;
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThan(iteration, maxTryCount);
|
||||
|
||||
var isStarted = container.Logs().ReadToEnd().Reverse().Any(x => x.Contains("Now listening on:"));
|
||||
return isStarted ? 0 : 500;
|
||||
}
|
||||
|
||||
private void AttachDockerNetworksIfRunningInContainer()
|
||||
{
|
||||
if (!IsTestRunningInContainer) return;
|
||||
|
||||
var randomNetworkName = Guid.NewGuid().ToString("N");
|
||||
_networkService = DockerHost.CreateNetwork(randomNetworkName, removeOnDispose: true);
|
||||
|
||||
_networkService.Attach(AppContainer, true, AppServiceName);
|
||||
_networkService.Attach(TestApplicationContainer, true);
|
||||
}
|
||||
|
||||
public string GetAppUrl()
|
||||
{
|
||||
return IsTestRunningInContainer
|
||||
? GetAppUrlWhenRunningInsideContainer()
|
||||
: GetUrlFromOutsideContainer(AppContainer, AppServiceInternalPortAndProtocol);
|
||||
}
|
||||
|
||||
private static string GetAppUrlWhenRunningInsideContainer()
|
||||
{
|
||||
return $"http://{AppServiceName}:{AppServiceInternalPort}";
|
||||
}
|
||||
|
||||
public string GetLoginUrl()
|
||||
{
|
||||
return IsTestRunningInContainer
|
||||
? GetLoginUrlWhenRunningInsideContainer()
|
||||
: GetUrlFromOutsideContainer(LoginContainer, LoginServiceInternalPortAndProtocol);
|
||||
}
|
||||
|
||||
private static string GetLoginUrlWhenRunningInsideContainer()
|
||||
{
|
||||
return $"http://{LoginServiceName}:{LoginServiceInternalPort}";
|
||||
}
|
||||
|
||||
private static string GetUrlFromOutsideContainer(IContainerService container, string portAndProto)
|
||||
{
|
||||
var ipEndpoint = container.ToHostExposedEndpoint(portAndProto);
|
||||
return $"http://{ipEndpoint.Address}:{ipEndpoint.Port}";
|
||||
}
|
||||
|
||||
private void KillDockerComposeServices()
|
||||
{
|
||||
foreach (var container in _dockerService.Containers) container.Remove(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public sealed class DockerComposeFixture2 : IDisposable
|
||||
{
|
||||
private const string ComposeFileName = "compose.system.yaml";
|
||||
|
||||
private static readonly string ComposeFilePath = Path.GetFullPath(Path.Combine("../../..", ComposeFileName));
|
||||
|
||||
private readonly ICompositeService _dockerService;
|
||||
|
||||
private IHostService? _host;
|
||||
|
||||
private INetworkService? _networkService;
|
||||
|
||||
public AppContainer AppContainer { get; init; }
|
||||
public LoginContainer LoginContainer { get; init; }
|
||||
public TestAppContainer TestApplicationContainer { get; init; }
|
||||
|
||||
public DockerComposeFixture2()
|
||||
{
|
||||
_dockerService = GetDockerComposeServices();
|
||||
_dockerService.Start();
|
||||
|
||||
TestApplicationContainer = new TestAppContainer(DockerHost);
|
||||
AppContainer = new AppContainer(_dockerService, TestApplicationContainer.IsTestRunningInContainer);
|
||||
LoginContainer = new LoginContainer(_dockerService, TestApplicationContainer.IsTestRunningInContainer);
|
||||
|
||||
AttachDockerNetworksIfRunningInContainer();
|
||||
}
|
||||
|
||||
public IHostService DockerHost
|
||||
{
|
||||
get
|
||||
{
|
||||
var hosts = new Hosts().Discover();
|
||||
_host = hosts.FirstOrDefault(x => x.IsNative) ??
|
||||
hosts.FirstOrDefault(x => x.Name == "default") ??
|
||||
hosts.FirstOrDefault();
|
||||
|
||||
if (_host is null) throw new InvalidOperationException("No docker host found");
|
||||
|
||||
return _host;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_networkService?.Dispose();
|
||||
|
||||
TestApplicationContainer.Dispose();
|
||||
AppContainer.Dispose();
|
||||
LoginContainer.Dispose();
|
||||
|
||||
// Kill container because otherwise the _dockerService.Dispose() takes much longer
|
||||
KillDockerComposeServices();
|
||||
|
||||
_dockerService.Dispose();
|
||||
|
||||
_host?.Dispose();
|
||||
}
|
||||
|
||||
private ICompositeService GetDockerComposeServices()
|
||||
{
|
||||
var services = new Builder()
|
||||
.UseContainer()
|
||||
.UseCompose()
|
||||
.AssumeComposeVersion(ComposeVersion.V2)
|
||||
.FromFile((TemplateString)ComposeFilePath)
|
||||
.ForceBuild()
|
||||
.RemoveOrphans()
|
||||
.Wait("app", WaitForApplicationToListenToRequests)
|
||||
.Build();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
private int WaitForApplicationToListenToRequests(IContainerService container, int iteration)
|
||||
{
|
||||
const int maxTryCount = 15;
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThan(iteration, maxTryCount);
|
||||
|
||||
var isStarted = container.Logs().ReadToEnd().Reverse().Any(x => x.Contains("Now listening on:"));
|
||||
return isStarted ? 0 : 500;
|
||||
}
|
||||
|
||||
private void AttachDockerNetworksIfRunningInContainer()
|
||||
{
|
||||
if (!TestApplicationContainer.IsTestRunningInContainer) return;
|
||||
|
||||
var randomNetworkName = Guid.NewGuid().ToString("N");
|
||||
_networkService = DockerHost.CreateNetwork(randomNetworkName, removeOnDispose: true);
|
||||
|
||||
_networkService.Attach(AppContainer.Container!, true, AppContainer.ServiceName);
|
||||
_networkService.Attach(TestApplicationContainer.Container, true);
|
||||
}
|
||||
|
||||
private void KillDockerComposeServices()
|
||||
{
|
||||
foreach (var container in _dockerService.Containers) container.Remove(true);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
FROM registry.access.redhat.com/ubi9 AS ubi-micro-build
|
||||
RUN mkdir -p /mnt/rootfs
|
||||
RUN dnf install --installroot /mnt/rootfs curl --releasever 9 --setopt install_weak_deps=false --nodocs -y && \
|
||||
dnf --installroot /mnt/rootfs clean all && \
|
||||
rpm --root /mnt/rootfs -e --nodeps setup
|
||||
|
||||
FROM quay.io/keycloak/keycloak
|
||||
COPY --from=ubi-micro-build /mnt/rootfs /
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace WebApi.Tests.System;
|
||||
|
||||
[CollectionDefinition(Name)]
|
||||
public class SharedTestCollection : ICollectionFixture<SharedTestContext>
|
||||
{
|
||||
public const string Name = nameof(SharedTestCollection);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
namespace WebApi.Tests.System;
|
||||
|
||||
public sealed class SharedTestContext : IDisposable
|
||||
{
|
||||
public DockerComposeFixture2 DockerComposeFixture { get; set; } = new();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DockerComposeFixture.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace WebApi.Tests.System;
|
||||
|
||||
[Collection(SharedTestCollection.Name)]
|
||||
public class Test
|
||||
{
|
||||
private readonly SharedTestContext _context;
|
||||
|
||||
public Test(SharedTestContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
public async Task Test1()
|
||||
{
|
||||
var loginUrl = _context.DockerComposeFixture.LoginContainer.GetServiceUrl();
|
||||
var baseUrl = new Uri(loginUrl!, UriKind.Absolute);
|
||||
var relativeUrl = new Uri($"/realms/{Constants.Login.Realm}/protocol/openid-connect/token", UriKind.Relative);
|
||||
var uri = new Uri(baseUrl, relativeUrl);
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, uri);
|
||||
|
||||
var data = new Dictionary<string, string>
|
||||
{
|
||||
{ "grant_type", "password" },
|
||||
{ "audience", Constants.Login.ClientId },
|
||||
{ "username", Constants.Login.Username },
|
||||
{ "password", Constants.Login.Password }
|
||||
};
|
||||
request.Content = new FormUrlEncodedContent(data);
|
||||
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Basic",
|
||||
Convert.ToBase64String(Encoding.UTF8.GetBytes($"{Constants.Login.ClientId}:{Constants.Login.ClientSecret}")));
|
||||
|
||||
using var client = new HttpClient();
|
||||
using var response = await client.SendAsync(request);
|
||||
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
var tokenResponse = JsonSerializer.Deserialize<TokenResponse>(content);
|
||||
|
||||
var appUrl = _context.DockerComposeFixture.AppContainer.GetServiceUrl();
|
||||
baseUrl = new Uri(appUrl!, UriKind.Absolute);
|
||||
relativeUrl = new Uri("/v1/cars", UriKind.Relative);
|
||||
uri = new Uri(baseUrl, relativeUrl);
|
||||
|
||||
request = new HttpRequestMessage(HttpMethod.Get, uri);
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokenResponse!.AccessToken);
|
||||
|
||||
using var response2 = await client.SendAsync(request);
|
||||
|
||||
var content2 = await response2.Content.ReadAsStringAsync();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace WebApi.Tests.System;
|
||||
|
||||
public class TokenResponse
|
||||
{
|
||||
[JsonPropertyName("access_token")]
|
||||
public required string AccessToken { get; init; }
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Ductus.FluentDocker" Version="2.10.59" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
||||
<PackageReference Include="xunit" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Update="Nerdbank.GitVersioning" Version="3.7.112" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,72 +0,0 @@
|
||||
services:
|
||||
app:
|
||||
build: ../../src/WebApi
|
||||
environment:
|
||||
Vegasco_ConnectionStrings__Default: "Host=db;Port=5432;Database=postgres;Username=postgres;Password=postgres"
|
||||
Vegasco_JWT__MetadataUrl: http://login:8080/realms/development/.well-known/openid-configuration
|
||||
Vegasco_JWT__ValidAudience: vegasco
|
||||
Vegasco_JWT__NameClaimType: name
|
||||
Vegasco_JWT__AllowHttpMetadataUrl: "true"
|
||||
ports:
|
||||
- "8080"
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
login:
|
||||
condition: service_healthy
|
||||
|
||||
db:
|
||||
image: postgres:16.3-alpine
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
healthcheck:
|
||||
test: pg_isready -d postgres
|
||||
interval: 5s
|
||||
timeout: 2s
|
||||
retries: 3
|
||||
start_period: 5s
|
||||
|
||||
login:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.keycloak
|
||||
command: start --import-realm
|
||||
environment:
|
||||
KC_DB: postgres
|
||||
KC_DB_URL_HOST: login-db
|
||||
KC_DB_URL_PORT: 5432
|
||||
KC_DB_URL_DATABASE: keycloak
|
||||
KC_DB_USERNAME: keycloak
|
||||
KC_DB_PASSWORD: keycloak
|
||||
KEYCLOAK_ADMIN: admin
|
||||
KEYCLOAK_ADMIN_PASSWORD: admin1!
|
||||
KC_HOSTNAME_STRICT: false
|
||||
KC_HEALTH_ENABLED: true
|
||||
KC_METRICS_ENABLED: true
|
||||
KC_HTTP_ENABLED: true
|
||||
ports:
|
||||
- "8080"
|
||||
volumes:
|
||||
- ./test-realm.json:/opt/keycloak/data/import/test-realm.json:ro
|
||||
depends_on:
|
||||
login-db:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: curl --head -fsS http://localhost:9000/health/ready || exit 1
|
||||
interval: 5s
|
||||
timeout: 2s
|
||||
retries: 6
|
||||
start_period: 5s
|
||||
|
||||
login-db:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
POSTGRES_USER: keycloak
|
||||
POSTGRES_PASSWORD: keycloak
|
||||
healthcheck:
|
||||
test: pg_isready -d keycloak
|
||||
interval: 5s
|
||||
timeout: 2s
|
||||
retries: 3
|
||||
start_period: 5s
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,6 @@
|
||||
</Folder>
|
||||
<Folder Name="/tests/">
|
||||
<Project Path="tests/WebApi.Tests.Integration/WebApi.Tests.Integration.csproj" />
|
||||
<Project Path="tests/WebApi.Tests.System/WebApi.Tests.System.csproj" />
|
||||
<Project Path="tests/WebApi.Tests.Unit/WebApi.Tests.Unit.csproj" />
|
||||
</Folder>
|
||||
</Solution>
|
||||
|
||||
Reference in New Issue
Block a user