diff --git a/.github/workflows/healthchecks_ibmmq_ci.yml b/.github/workflows/healthchecks_ibmmq_ci.yml index 096e38361c..50b613c183 100644 --- a/.github/workflows/healthchecks_ibmmq_ci.yml +++ b/.github/workflows/healthchecks_ibmmq_ci.yml @@ -29,50 +29,8 @@ on: jobs: build: - runs-on: ubuntu-latest - services: - ibmmq: - image: ibmcom/mq - ports: - - 1414:1414 - - 9157:9157 - env: - LICENSE: accept - MQ_QMGR_NAME: QM1 - MQ_APP_PASSWORD: 12345678 - MQ_ENABLE_METRICS: true - 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.IbmMQ/HealthChecks.IbmMQ.csproj && - dotnet restore ./test/HealthChecks.IbmMQ.Tests/HealthChecks.IbmMQ.Tests.csproj - - name: Check formatting - run: | - dotnet format --no-restore --verify-no-changes --severity warn ./src/HealthChecks.IbmMQ/HealthChecks.IbmMQ.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1) && - dotnet format --no-restore --verify-no-changes --severity warn ./test/HealthChecks.IbmMQ.Tests/HealthChecks.IbmMQ.Tests.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1) - - name: Build - run: | - dotnet build --no-restore ./src/HealthChecks.IbmMQ/HealthChecks.IbmMQ.csproj && - dotnet build --no-restore ./test/HealthChecks.IbmMQ.Tests/HealthChecks.IbmMQ.Tests.csproj - - name: Test - run: > - dotnet test - ./test/HealthChecks.IbmMQ.Tests/HealthChecks.IbmMQ.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: IbmMQ - directory: .coverage + uses: ./.github/workflows/reusable_ci_workflow.yml + with: + PROJECT_PATH: ./src/HealthChecks.IbmMQ/HealthChecks.IbmMQ.csproj + TEST_PROJECT_PATH: ./test/HealthChecks.IbmMQ.Tests/HealthChecks.IbmMQ.Tests.csproj + CODECOV_FLAGS: IbmMQ diff --git a/test/HealthChecks.IbmMQ.Tests/Functional/IbmMQHealthCheckTests.cs b/test/HealthChecks.IbmMQ.Tests/Functional/IbmMQHealthCheckTests.cs index fb0872c2f1..cfd9d64a5a 100644 --- a/test/HealthChecks.IbmMQ.Tests/Functional/IbmMQHealthCheckTests.cs +++ b/test/HealthChecks.IbmMQ.Tests/Functional/IbmMQHealthCheckTests.cs @@ -2,37 +2,24 @@ using System.Net; using IBM.WMQ; -namespace HealthChecks.Ibmq.Tests.Functional; +namespace HealthChecks.IbmMQ.Tests.Functional; -public class ibmmq_healthcheck_should +public class ibmmq_healthcheck_should(IbmMQContainerFixture ibmMqFixture) : IClassFixture { - - // Define the name of the queue manager to use (applies to all connections) - private const string qManager = "QM1"; - - // Define the name of your host connection (applies to client connections only) - private const string hostName = "localhost(1414)"; private const string wrongHostName = "localhost(1417)"; - // Define the name of the channel to use (applies to client connections only) - private const string channel = "DEV.APP.SVRCONN"; - - // Define the user name. - private const string user = "app"; - - // Define the password. - private const string password = "12345678"; - [Fact] public async Task be_healthy_if_ibmmq_is_available() { - var properties = new Hashtable + var properties = ibmMqFixture.GetConnectionProperties(); + + var connectionProperties = new Hashtable { { MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED }, - { MQC.CHANNEL_PROPERTY, channel }, - { MQC.CONNECTION_NAME_PROPERTY, hostName }, - { MQC.USER_ID_PROPERTY, user }, - { MQC.PASSWORD_PROPERTY, password } + { MQC.CHANNEL_PROPERTY, properties.Channel }, + { MQC.CONNECTION_NAME_PROPERTY, properties.Hostname }, + { MQC.USER_ID_PROPERTY, properties.Username }, + { MQC.PASSWORD_PROPERTY, properties.Password } }; var webHostBuilder = new WebHostBuilder() @@ -40,7 +27,7 @@ public async Task be_healthy_if_ibmmq_is_available() { services .AddHealthChecks() - .AddIbmMQ(qManager, properties, tags: ["ibmmq"]); + .AddIbmMQ(properties.QueueManager, connectionProperties, tags: ["ibmmq"]); }) .Configure(app => { @@ -60,13 +47,15 @@ public async Task be_healthy_if_ibmmq_is_available() [Fact] public async Task be_unhealthy_if_ibmmq_is_unavailable() { - var properties = new Hashtable + var properties = ibmMqFixture.GetConnectionProperties(); + + var connectionProperties = new Hashtable { { MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED }, - { MQC.CHANNEL_PROPERTY, channel }, + { MQC.CHANNEL_PROPERTY, properties.Channel }, { MQC.CONNECTION_NAME_PROPERTY, wrongHostName }, - { MQC.USER_ID_PROPERTY, user }, - { MQC.PASSWORD_PROPERTY, password } + { MQC.USER_ID_PROPERTY, properties.Username }, + { MQC.PASSWORD_PROPERTY, properties.Password } }; var webHostBuilder = new WebHostBuilder() @@ -74,7 +63,7 @@ public async Task be_unhealthy_if_ibmmq_is_unavailable() { services .AddHealthChecks() - .AddIbmMQ(qManager, properties, tags: ["ibmmq"]); + .AddIbmMQ(properties.QueueManager, connectionProperties, tags: ["ibmmq"]); }) .Configure(app => { @@ -94,12 +83,20 @@ public async Task be_unhealthy_if_ibmmq_is_unavailable() [Fact] public async Task be_unhealthy_if_ibmmq_managed_is_unavailable() { + var properties = ibmMqFixture.GetConnectionProperties(); + var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => { services .AddHealthChecks() - .AddIbmMQManagedConnection(qManager, channel, wrongHostName, user, password, tags: ["ibmmq"]); + .AddIbmMQManagedConnection( + properties.QueueManager, + properties.Channel, + wrongHostName, + properties.Username, + properties.Password, + tags: ["ibmmq"]); }) .Configure(app => { @@ -119,12 +116,20 @@ public async Task be_unhealthy_if_ibmmq_managed_is_unavailable() [Fact] public async Task be_healthy_if_ibmmq_managed_is_available() { + var properties = ibmMqFixture.GetConnectionProperties(); + var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => { services .AddHealthChecks() - .AddIbmMQManagedConnection(qManager, channel, hostName, user, password, tags: ["ibmmq"]); + .AddIbmMQManagedConnection( + properties.QueueManager, + properties.Channel, + properties.Hostname, + properties.Username, + properties.Password, + tags: ["ibmmq"]); }) .Configure(app => { diff --git a/test/HealthChecks.IbmMQ.Tests/HealthChecks.IbmMQ.Tests.csproj b/test/HealthChecks.IbmMQ.Tests/HealthChecks.IbmMQ.Tests.csproj index ad6ffc1225..73b9b96868 100644 --- a/test/HealthChecks.IbmMQ.Tests/HealthChecks.IbmMQ.Tests.csproj +++ b/test/HealthChecks.IbmMQ.Tests/HealthChecks.IbmMQ.Tests.csproj @@ -4,4 +4,8 @@ + + + + diff --git a/test/HealthChecks.IbmMQ.Tests/IbmMQContainerFixture.cs b/test/HealthChecks.IbmMQ.Tests/IbmMQContainerFixture.cs new file mode 100644 index 0000000000..62f924c08f --- /dev/null +++ b/test/HealthChecks.IbmMQ.Tests/IbmMQContainerFixture.cs @@ -0,0 +1,55 @@ +using DotNet.Testcontainers.Builders; +using DotNet.Testcontainers.Containers; + +namespace HealthChecks.IbmMQ.Tests; + +public class IbmMQContainerFixture : IAsyncLifetime +{ + public const string Registry = "docker.io"; + + public const string Image = "ibmcom/mq"; + + public const string Tag = "9.2.4.0-r1"; + + private const int Port = 1414; + + private const string QueueManager = "QM1"; + + private const string Channel = "DEV.APP.SVRCONN"; + + private const string Username = "app"; + + private const string Password = "password"; + + public IContainer? Container { get; private set; } + + public (string Hostname, string Username, string Password, string Channel, string QueueManager) GetConnectionProperties() + { + if (Container is null) + { + throw new InvalidOperationException("The test container was not initialized."); + } + + return ($"localhost({Container.GetMappedPublicPort(Port)})", Username, Password, Channel, QueueManager); + } + + public async Task InitializeAsync() => Container = await CreateContainerAsync(); + + public Task DisposeAsync() => Container?.DisposeAsync().AsTask() ?? Task.CompletedTask; + + private async Task CreateContainerAsync() + { + var container = new ContainerBuilder() + .WithImage($"{Registry}/{Image}:{Tag}") + .WithEnvironment("LICENSE", "accept") + .WithEnvironment("MQ_QMGR_NAME", QueueManager) + .WithEnvironment("MQ_APP_PASSWORD", Password) + .WithPortBinding(Port, true) + .WithWaitStrategy(Wait.ForUnixContainer().UntilCommandIsCompleted("chkmqready")) + .Build(); + + await container.StartAsync(); + + return container; + } +}