From d34f36dc661b48ba1e407adaf1b82e3a06b1c3fc Mon Sep 17 00:00:00 2001 From: Mono <81423605+monofunc@users.noreply.github.com> Date: Wed, 13 Aug 2025 21:16:49 +0400 Subject: [PATCH] Migrate HealthChecks.Gremlin tests to Testcontainers --- .github/workflows/healthchecks_gremlin_ci.yml | 49 ++--------------- .../Functional/GremlinHealthCheckTests.cs | 38 +++++-------- .../GremlinContainerFixture.cs | 55 +++++++++++++++++++ .../HealthChecks.Gremlin.Tests.csproj | 4 ++ 4 files changed, 77 insertions(+), 69 deletions(-) create mode 100644 test/HealthChecks.Gremlin.Tests/GremlinContainerFixture.cs diff --git a/.github/workflows/healthchecks_gremlin_ci.yml b/.github/workflows/healthchecks_gremlin_ci.yml index abd3e465eb..74414a0258 100644 --- a/.github/workflows/healthchecks_gremlin_ci.yml +++ b/.github/workflows/healthchecks_gremlin_ci.yml @@ -29,47 +29,8 @@ on: jobs: build: - runs-on: ubuntu-latest - services: - gremlin: - image: tinkerpop/gremlin-server - ports: - - 8182:8182 - env: - VIRTUAL_HOST: gremlin.docker - VIRTUAL_PORT: 8182 - steps: - - uses: actions/checkout@v3 - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: | - 8.0.x - 9.0.x - - name: Restore - run: | - dotnet restore ./src/HealthChecks.Gremlin/HealthChecks.Gremlin.csproj && - dotnet restore ./test/HealthChecks.Gremlin.Tests/HealthChecks.Gremlin.Tests.csproj - - name: Check formatting - run: | - dotnet format --no-restore --verify-no-changes --severity warn ./src/HealthChecks.Gremlin/HealthChecks.Gremlin.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1) && - dotnet format --no-restore --verify-no-changes --severity warn ./test/HealthChecks.Gremlin.Tests/HealthChecks.Gremlin.Tests.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1) - - name: Build - run: | - dotnet build --no-restore ./src/HealthChecks.Gremlin/HealthChecks.Gremlin.csproj && - dotnet build --no-restore ./test/HealthChecks.Gremlin.Tests/HealthChecks.Gremlin.Tests.csproj - - name: Test - run: > - dotnet test - ./test/HealthChecks.Gremlin.Tests/HealthChecks.Gremlin.Tests.csproj - --no-restore - --no-build - --collect "XPlat Code Coverage" - --results-directory .coverage - -- - DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover - - name: Upload Coverage - uses: codecov/codecov-action@v5 - with: - flags: Gremlin - directory: .coverage + uses: ./.github/workflows/reusable_ci_workflow.yml + with: + PROJECT_PATH: ./src/HealthChecks.Gremlin/HealthChecks.Gremlin.csproj + TEST_PROJECT_PATH: ./test/HealthChecks.Gremlin.Tests/HealthChecks.Gremlin.Tests.csproj + CODECOV_FLAGS: Gremlin diff --git a/test/HealthChecks.Gremlin.Tests/Functional/GremlinHealthCheckTests.cs b/test/HealthChecks.Gremlin.Tests/Functional/GremlinHealthCheckTests.cs index 606b9de636..d2f57f98a4 100644 --- a/test/HealthChecks.Gremlin.Tests/Functional/GremlinHealthCheckTests.cs +++ b/test/HealthChecks.Gremlin.Tests/Functional/GremlinHealthCheckTests.cs @@ -2,21 +2,18 @@ namespace HealthChecks.Gremlin.Tests.Functional; -public class gremlin_healthcheck_should +public class gremlin_healthcheck_should(GremlinContainerFixture gremlinFixture) : IClassFixture { [Fact] public async Task be_healthy_if_gremlin_is_available() { + var options = gremlinFixture.GetConnectionOptions(); + var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => { services.AddHealthChecks() - .AddGremlin(_ => new GremlinOptions - { - Hostname = "localhost", - Port = 8182, - EnableSsl = false - }, tags: ["gremlin"]); + .AddGremlin(_ => options, tags: ["gremlin"]); }) .Configure(app => { @@ -36,22 +33,14 @@ public async Task be_healthy_if_gremlin_is_available() [Fact] public async Task be_healthy_if_multiple_gremlin_are_available() { + var options = gremlinFixture.GetConnectionOptions(); + var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => { services.AddHealthChecks() - .AddGremlin(_ => new GremlinOptions - { - Hostname = "localhost", - Port = 8182, - EnableSsl = false - }, tags: ["gremlin"], name: "1") - .AddGremlin(_ => new GremlinOptions - { - Hostname = "localhost", - Port = 8182, - EnableSsl = false - }, tags: ["gremlin"], name: "2"); + .AddGremlin(_ => options, tags: ["gremlin"], name: "1") + .AddGremlin(_ => options, tags: ["gremlin"], name: "2"); }) .Configure(app => { @@ -71,16 +60,15 @@ public async Task be_healthy_if_multiple_gremlin_are_available() [Fact] public async Task be_unhealthy_if_gremlin_is_not_available() { + var options = gremlinFixture.GetConnectionOptions(); + + options.Hostname = "wronghost"; + var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => { services.AddHealthChecks() - .AddGremlin(_ => new GremlinOptions - { - Hostname = "wronghost", - Port = 8182, - EnableSsl = false - }, tags: ["gremlin"]); + .AddGremlin(_ => options, tags: ["gremlin"]); }) .Configure(app => { diff --git a/test/HealthChecks.Gremlin.Tests/GremlinContainerFixture.cs b/test/HealthChecks.Gremlin.Tests/GremlinContainerFixture.cs new file mode 100644 index 0000000000..51bd5c96a2 --- /dev/null +++ b/test/HealthChecks.Gremlin.Tests/GremlinContainerFixture.cs @@ -0,0 +1,55 @@ +using DotNet.Testcontainers.Builders; +using DotNet.Testcontainers.Containers; + +namespace HealthChecks.Gremlin.Tests; + +public class GremlinContainerFixture : IAsyncLifetime +{ + private const string Registry = "docker.io"; + + private const string Image = "tinkerpop/gremlin-server"; + + private const string Tag = "3.7.4"; + + private const int Port = 8182; + + public IContainer? Container { get; private set; } + + public GremlinOptions GetConnectionOptions() + { + if (Container is null) + { + throw new InvalidOperationException("The test container was not initialized."); + } + + var options = new GremlinOptions + { + Hostname = Container.Hostname, + Port = Container.GetMappedPublicPort(Port), + EnableSsl = false + }; + + return options; + } + + public async Task InitializeAsync() => Container = await CreateContainerAsync(); + + public Task DisposeAsync() => Container?.DisposeAsync().AsTask() ?? Task.CompletedTask; + + private static async Task CreateContainerAsync() + { + var waitStrategy = Wait + .ForUnixContainer() + .UntilPortIsAvailable(Port); + + var container = new ContainerBuilder() + .WithImage($"{Registry}/{Image}:{Tag}") + .WithPortBinding(Port, true) + .WithWaitStrategy(waitStrategy) + .Build(); + + await container.StartAsync(); + + return container; + } +} diff --git a/test/HealthChecks.Gremlin.Tests/HealthChecks.Gremlin.Tests.csproj b/test/HealthChecks.Gremlin.Tests/HealthChecks.Gremlin.Tests.csproj index c31e6741f5..fa2643dafc 100644 --- a/test/HealthChecks.Gremlin.Tests/HealthChecks.Gremlin.Tests.csproj +++ b/test/HealthChecks.Gremlin.Tests/HealthChecks.Gremlin.Tests.csproj @@ -4,4 +4,8 @@ + + + +