From 3f4ad9e9378e91be2c9c39050f496a937303c2d0 Mon Sep 17 00:00:00 2001 From: Alireza Baloochi Date: Thu, 19 Dec 2024 17:02:40 +0330 Subject: [PATCH] Migrate HealthChecks.Rabbitmq tests to Testcontainers (#2352) --- .../workflows/healthchecks_rabbitmq_ci.yml | 70 ++++--------------- Directory.Packages.props | 1 + .../Functional/RabbitHealthCheckTests.cs | 18 ++--- .../HealthChecks.RabbitMQ.Tests.csproj | 5 +- .../RabbitMQContainerFixture.cs | 35 ++++++++++ .../Functional/RabbitHealthCheckTests.cs | 22 +++--- .../HealthChecks.RabbitMQ.v6.Tests.csproj | 10 ++- 7 files changed, 82 insertions(+), 79 deletions(-) create mode 100644 test/HealthChecks.RabbitMQ.Tests/RabbitMQContainerFixture.cs diff --git a/.github/workflows/healthchecks_rabbitmq_ci.yml b/.github/workflows/healthchecks_rabbitmq_ci.yml index 0f6507a94e..ff137b6869 100644 --- a/.github/workflows/healthchecks_rabbitmq_ci.yml +++ b/.github/workflows/healthchecks_rabbitmq_ci.yml @@ -6,7 +6,9 @@ on: branches: [ master ] paths: - src/HealthChecks.Rabbitmq/** + - src/HealthChecks.Rabbitmq.v6/** - test/HealthChecks.RabbitMQ.Tests/** + - test/HealthChecks.RabbitMQ.v6.Tests/** - test/_SHARED/** - .github/workflows/healthchecks_rabbitmq_ci.yml - Directory.Build.props @@ -31,60 +33,14 @@ on: jobs: build: - runs-on: ubuntu-latest - services: - rabbitmq: - image: rabbitmq - ports: - - 5672:5672 - 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.Rabbitmq/HealthChecks.Rabbitmq.csproj && - dotnet restore ./src/HealthChecks.Rabbitmq.v6/HealthChecks.Rabbitmq.v6.csproj && - dotnet restore ./test/HealthChecks.RabbitMQ.Tests/HealthChecks.RabbitMQ.Tests.csproj && - dotnet restore ./test/HealthChecks.RabbitMQ.v6.Tests/HealthChecks.RabbitMQ.v6.Tests.csproj - - name: Check formatting - run: | - dotnet format --no-restore --verify-no-changes --severity warn ./src/HealthChecks.Rabbitmq/HealthChecks.Rabbitmq.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1) && - dotnet format --no-restore --verify-no-changes --severity warn ./src/HealthChecks.Rabbitmq.v6/HealthChecks.Rabbitmq.v6.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1) && - dotnet format --no-restore --verify-no-changes --severity warn ./test/HealthChecks.RabbitMQ.Tests/HealthChecks.RabbitMQ.Tests.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1) && - dotnet format --no-restore --verify-no-changes --severity warn ./test/HealthChecks.RabbitMQ.v6.Tests/HealthChecks.RabbitMQ.v6.Tests.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1) - - name: Build - run: | - dotnet build --no-restore ./src/HealthChecks.Rabbitmq/HealthChecks.Rabbitmq.csproj && - dotnet build --no-restore ./src/HealthChecks.Rabbitmq.v6/HealthChecks.Rabbitmq.v6.csproj && - dotnet build --no-restore ./test/HealthChecks.RabbitMQ.Tests/HealthChecks.RabbitMQ.Tests.csproj && - dotnet build --no-restore ./test/HealthChecks.RabbitMQ.v6.Tests/HealthChecks.RabbitMQ.v6.Tests.csproj - - name: Test - run: > - dotnet test - ./test/HealthChecks.RabbitMQ.Tests/HealthChecks.RabbitMQ.Tests.csproj - --no-restore - --no-build - --collect "XPlat Code Coverage" - --results-directory .coverage - -- - DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover - - name: Test v6 - run: > - dotnet test - ./test/HealthChecks.RabbitMQ.v6.Tests/HealthChecks.RabbitMQ.v6.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: RabbitMQ - directory: .coverage + uses: ./.github/workflows/reusable_ci_workflow.yml + with: + PROJECT_PATH: ./src/HealthChecks.Rabbitmq/HealthChecks.Rabbitmq.csproj + TEST_PROJECT_PATH: ./test/HealthChecks.RabbitMQ.Tests/HealthChecks.RabbitMQ.Tests.csproj + CODECOV_FLAGS: RabbitMQ + build-v6: + uses: ./.github/workflows/reusable_ci_workflow.yml + with: + PROJECT_PATH: ./src/HealthChecks.Rabbitmq.v6/HealthChecks.Rabbitmq.v6.csproj + TEST_PROJECT_PATH: ./test/HealthChecks.RabbitMQ.v6.Tests/HealthChecks.RabbitMQ.v6.Tests.csproj + CODECOV_FLAGS: RabbitMQ diff --git a/Directory.Packages.props b/Directory.Packages.props index 0833f4385c..7a3c077b65 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -106,6 +106,7 @@ + diff --git a/test/HealthChecks.RabbitMQ.Tests/Functional/RabbitHealthCheckTests.cs b/test/HealthChecks.RabbitMQ.Tests/Functional/RabbitHealthCheckTests.cs index b0886b62e7..a8a731ff4f 100644 --- a/test/HealthChecks.RabbitMQ.Tests/Functional/RabbitHealthCheckTests.cs +++ b/test/HealthChecks.RabbitMQ.Tests/Functional/RabbitHealthCheckTests.cs @@ -3,12 +3,12 @@ namespace HealthChecks.RabbitMQ.Tests.Functional; -public class rabbitmq_healthcheck_should +public class rabbitmq_healthcheck_should(RabbitMQContainerFixture rabbitMQContainerFixture) : IClassFixture { [Fact] public async Task be_healthy_if_rabbitmq_is_available() { - var connectionString = "amqp://localhost:5672"; + var connectionString = rabbitMQContainerFixture.GetConnectionString(); var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => @@ -36,7 +36,7 @@ public async Task be_healthy_if_rabbitmq_is_available() [Fact] public async Task be_unhealthy_if_rabbitmq_is_not_available() { - var connectionString = "amqp://localhost:6672"; + var connectionString = "amqp://invalidhost:6672"; var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => @@ -64,7 +64,7 @@ public async Task be_unhealthy_if_rabbitmq_is_not_available() [Fact] public async Task be_healthy_if_rabbitmq_is_available_using_iconnection() { - var connectionString = "amqp://localhost:5672"; + var connectionString = rabbitMQContainerFixture.GetConnectionString(); var factory = new ConnectionFactory() { @@ -104,7 +104,7 @@ public async Task be_healthy_if_rabbitmq_is_available_using_iconnection() [Fact] public async Task be_healthy_if_rabbitmq_is_available_using_iconnection_in_serviceprovider() { - var connectionString = "amqp://localhost:5672"; + var connectionString = rabbitMQContainerFixture.GetConnectionString(); var factory = new ConnectionFactory() { @@ -149,9 +149,9 @@ public async Task be_not_crash_on_startup_when_rabbitmq_is_down_at_startup() { return new ConnectionFactory() { - Uri = new Uri("amqp://localhost:3333"), + Uri = new Uri("amqp://invalidhost:3333"), AutomaticRecoveryEnabled = true, - Ssl = new SslOption(serverName: "localhost", enabled: false) + Ssl = new SslOption(serverName: "invalidhost", enabled: false) }; }) .AddHealthChecks() @@ -176,8 +176,8 @@ public async Task be_not_crash_on_startup_when_rabbitmq_is_down_at_startup() [Fact] public async Task two_rabbitmq_health_check() { - const string connectionString1 = "amqp://localhost:5672"; - const string connectionString2 = "amqp://localhost:6672/"; + var connectionString1 = rabbitMQContainerFixture.GetConnectionString(); + const string connectionString2 = "amqp://invalidhost:6672/"; var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => diff --git a/test/HealthChecks.RabbitMQ.Tests/HealthChecks.RabbitMQ.Tests.csproj b/test/HealthChecks.RabbitMQ.Tests/HealthChecks.RabbitMQ.Tests.csproj index 90dd74e20a..cdce4e0d83 100644 --- a/test/HealthChecks.RabbitMQ.Tests/HealthChecks.RabbitMQ.Tests.csproj +++ b/test/HealthChecks.RabbitMQ.Tests/HealthChecks.RabbitMQ.Tests.csproj @@ -1,7 +1,10 @@ - + + + + diff --git a/test/HealthChecks.RabbitMQ.Tests/RabbitMQContainerFixture.cs b/test/HealthChecks.RabbitMQ.Tests/RabbitMQContainerFixture.cs new file mode 100644 index 0000000000..8aefc6b415 --- /dev/null +++ b/test/HealthChecks.RabbitMQ.Tests/RabbitMQContainerFixture.cs @@ -0,0 +1,35 @@ +using Testcontainers.RabbitMq; + +namespace HealthChecks.RabbitMQ.Tests; + +public sealed class RabbitMQContainerFixture : IAsyncLifetime +{ + public const string Registry = "docker.io"; + + public const string Image = "library/rabbitmq"; + + public const string Tag = "4.0"; + + public RabbitMqContainer? Container { get; private set; } + + public string GetConnectionString() => Container?.GetConnectionString() ?? + throw new InvalidOperationException("The test container was not initialized."); + + public async Task InitializeAsync() => Container = await CreateContainerAsync(); + + public async Task DisposeAsync() + { + if (Container is not null) + await Container.DisposeAsync(); + } + + public static async Task CreateContainerAsync() + { + var container = new RabbitMqBuilder() + .WithImage($"{Registry}/{Image}:{Tag}") + .Build(); + await container.StartAsync(); + + return container; + } +} diff --git a/test/HealthChecks.RabbitMQ.v6.Tests/Functional/RabbitHealthCheckTests.cs b/test/HealthChecks.RabbitMQ.v6.Tests/Functional/RabbitHealthCheckTests.cs index fc36601b36..afa3e35caf 100644 --- a/test/HealthChecks.RabbitMQ.v6.Tests/Functional/RabbitHealthCheckTests.cs +++ b/test/HealthChecks.RabbitMQ.v6.Tests/Functional/RabbitHealthCheckTests.cs @@ -3,12 +3,12 @@ namespace HealthChecks.RabbitMQ.Tests.Functional; -public class rabbitmq_healthcheck_should +public class rabbitmq_healthcheck_should(RabbitMQContainerFixture rabbitMQContainerFixture) : IClassFixture { [Fact] public async Task be_healthy_if_rabbitmq_is_available() { - var connectionString = "amqp://localhost:5672"; + var connectionString = rabbitMQContainerFixture.GetConnectionString(); var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => @@ -34,7 +34,7 @@ public async Task be_healthy_if_rabbitmq_is_available() [Fact] public async Task be_healthy_if_rabbitmq_is_available_using_ssloption() { - var connectionString = "amqp://localhost:5672"; + var connectionString = rabbitMQContainerFixture.GetConnectionString(); var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => @@ -64,7 +64,7 @@ public async Task be_unhealthy_if_rabbitmq_is_not_available() .ConfigureServices(services => { services.AddHealthChecks() - .AddRabbitMQ("amqp://localhost:6672", sslOption: new SslOption(serverName: "localhost", enabled: false), tags: ["rabbitmq"]); + .AddRabbitMQ("amqp://invalidlocalhost:6672", sslOption: new SslOption(serverName: "invalidlocalhost", enabled: false), tags: ["rabbitmq"]); }) .Configure(app => { @@ -84,7 +84,7 @@ public async Task be_unhealthy_if_rabbitmq_is_not_available() [Fact] public async Task be_healthy_if_rabbitmq_is_available_using_iconnectionfactory() { - var connectionString = "amqp://localhost:5672"; + var connectionString = rabbitMQContainerFixture.GetConnectionString(); var factory = new ConnectionFactory() { @@ -118,7 +118,7 @@ public async Task be_healthy_if_rabbitmq_is_available_using_iconnectionfactory() [Fact] public async Task be_healthy_if_rabbitmq_is_available_using_iconnection() { - var connectionString = "amqp://localhost:5672"; + var connectionString = rabbitMQContainerFixture.GetConnectionString(); var factory = new ConnectionFactory() { @@ -155,7 +155,7 @@ public async Task be_healthy_if_rabbitmq_is_available_using_iconnection() [Fact] public async Task be_healthy_if_rabbitmq_is_available_and_specify_default_ssloption() { - var connectionString = "amqp://localhost:5672"; + var connectionString = rabbitMQContainerFixture.GetConnectionString(); var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => @@ -189,7 +189,7 @@ public async Task be_not_crash_on_startup_when_rabbitmq_is_down_at_startup() { return new ConnectionFactory() { - Uri = new Uri("amqp://localhost:3333"), + Uri = new Uri("amqp://invalidlocalhost:3333"), AutomaticRecoveryEnabled = true, Ssl = new SslOption(serverName: "localhost", enabled: false) }; @@ -214,7 +214,7 @@ public async Task be_not_crash_on_startup_when_rabbitmq_is_down_at_startup() [Fact] public async Task be_healthy_if_rabbitmq_is_available_using_iServiceProvider() { - var connectionString = "amqp://localhost:5672"; + var connectionString = rabbitMQContainerFixture.GetConnectionString(); var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => @@ -242,8 +242,8 @@ public async Task be_healthy_if_rabbitmq_is_available_using_iServiceProvider() [Fact] public async Task two_rabbitmq_health_check() { - const string connectionString1 = "amqp://localhost:5672"; - const string connectionString2 = "amqp://localhost:6672/"; + var connectionString1 = rabbitMQContainerFixture.GetConnectionString(); + const string connectionString2 = "amqp://invalidhost:6672/"; var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => diff --git a/test/HealthChecks.RabbitMQ.v6.Tests/HealthChecks.RabbitMQ.v6.Tests.csproj b/test/HealthChecks.RabbitMQ.v6.Tests/HealthChecks.RabbitMQ.v6.Tests.csproj index d37d8c713e..8f5aac69b0 100644 --- a/test/HealthChecks.RabbitMQ.v6.Tests/HealthChecks.RabbitMQ.v6.Tests.csproj +++ b/test/HealthChecks.RabbitMQ.v6.Tests/HealthChecks.RabbitMQ.v6.Tests.csproj @@ -1,4 +1,4 @@ - + HealthChecks.RabbitMQ.Tests @@ -8,4 +8,12 @@ + + + + + + + +