From 682ee6085a4e27370c5263e0d911f05b6b5a46c5 Mon Sep 17 00:00:00 2001 From: Mono <81423605+monofunc@users.noreply.github.com> Date: Wed, 13 Aug 2025 23:47:10 +0400 Subject: [PATCH] Migrate HealthChecks.Oracle tests to Testcontainers --- .github/workflows/healthchecks_oracle_ci.yml | 48 ++----------------- Directory.Packages.props | 3 +- .../Functional/OracleHealthCheckTests.cs | 21 ++++---- .../HealthChecks.Oracle.Tests.csproj | 4 ++ .../OracleContainerFixture.cs | 42 ++++++++++++++++ 5 files changed, 65 insertions(+), 53 deletions(-) create mode 100644 test/HealthChecks.Oracle.Tests/OracleContainerFixture.cs diff --git a/.github/workflows/healthchecks_oracle_ci.yml b/.github/workflows/healthchecks_oracle_ci.yml index 9a76ff5503..2ade85fb3e 100644 --- a/.github/workflows/healthchecks_oracle_ci.yml +++ b/.github/workflows/healthchecks_oracle_ci.yml @@ -29,46 +29,8 @@ on: jobs: build: - runs-on: ubuntu-latest - services: - oracle: - image: gvenzl/oracle-xe:18-slim - ports: - - 1521:1521 - env: - ORACLE_PASSWORD: oracle - 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.Oracle/HealthChecks.Oracle.csproj && - dotnet restore ./test/HealthChecks.Oracle.Tests/HealthChecks.Oracle.Tests.csproj - - name: Check formatting - run: | - dotnet format --no-restore --verify-no-changes --severity warn ./src/HealthChecks.Oracle/HealthChecks.Oracle.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1) && - dotnet format --no-restore --verify-no-changes --severity warn ./test/HealthChecks.Oracle.Tests/HealthChecks.Oracle.Tests.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1) - - name: Build - run: | - dotnet build --no-restore ./src/HealthChecks.Oracle/HealthChecks.Oracle.csproj && - dotnet build --no-restore ./test/HealthChecks.Oracle.Tests/HealthChecks.Oracle.Tests.csproj - - name: Test - run: > - dotnet test - ./test/HealthChecks.Oracle.Tests/HealthChecks.Oracle.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: Oracle - directory: .coverage + uses: ./.github/workflows/reusable_ci_workflow.yml + with: + PROJECT_PATH: ./src/HealthChecks.Oracle/HealthChecks.Oracle.csproj + TEST_PROJECT_PATH: ./test/HealthChecks.Oracle.Tests/HealthChecks.Oracle.Tests.csproj + CODECOV_FLAGS: Oracle diff --git a/Directory.Packages.props b/Directory.Packages.props index 2c2207765a..fb69651aac 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -106,6 +106,7 @@ + @@ -119,4 +120,4 @@ - + \ No newline at end of file diff --git a/test/HealthChecks.Oracle.Tests/Functional/OracleHealthCheckTests.cs b/test/HealthChecks.Oracle.Tests/Functional/OracleHealthCheckTests.cs index aa311f86b8..e4861b285b 100644 --- a/test/HealthChecks.Oracle.Tests/Functional/OracleHealthCheckTests.cs +++ b/test/HealthChecks.Oracle.Tests/Functional/OracleHealthCheckTests.cs @@ -4,12 +4,12 @@ namespace HealthChecks.Oracle.Tests.Functional; -public class oracle_healthcheck_should +public class oracle_healthcheck_should(OracleContainerFixture oracleFixture) : IClassFixture { [Fact] public async Task be_healthy_when_oracle_is_available() { - var connectionString = "Data Source=localhost:1521/XEPDB1;User Id=system;Password=oracle"; + string connectionString = oracleFixture.GetConnectionString(); var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => @@ -34,13 +34,15 @@ public async Task be_healthy_when_oracle_is_available() [Fact] public async Task be_unhealthy_when_oracle_is_not_available() { - var connectionString = "Data Source=255.255.255.255:1521/XEPDB1;User Id=system;Password=oracle"; + var connectionStringBuilder = oracleFixture.GetConnectionStringBuilder(); + + connectionStringBuilder.DataSource = "invalid"; var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => { services.AddHealthChecks() - .AddOracle(connectionString, tags: ["oracle"]); + .AddOracle(connectionStringBuilder.ConnectionString, tags: ["oracle"]); }) .Configure(app => { @@ -58,7 +60,8 @@ public async Task be_unhealthy_when_oracle_is_not_available() [Fact] public async Task be_unhealthy_when_sql_query_is_not_valid() { - var connectionString = "Data Source=localhost:1521/XEPDB1;User Id=system;Password=oracle"; + string connectionString = oracleFixture.GetConnectionString(); + var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => { @@ -82,7 +85,7 @@ public async Task be_unhealthy_when_sql_query_is_not_valid() public async Task be_healthy_with_connection_string_factory_when_oracle_is_available() { bool factoryCalled = false; - string connectionString = "Data Source=localhost:1521/XEPDB1;User Id=system;Password=oracle"; + string connectionString = oracleFixture.GetConnectionString(); var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => @@ -114,8 +117,8 @@ public async Task be_healthy_with_connection_string_factory_when_oracle_is_avail public async Task be_healthy_with_connection_string_and_credential_when_oracle_is_available() { bool factoryCalled = false; - string connectionString = "Data Source=localhost:1521/XEPDB1"; - var password = new NetworkCredential("system", "oracle").SecurePassword; + var connectionStringBuilder = oracleFixture.GetConnectionStringBuilder(); + var password = new NetworkCredential(connectionStringBuilder.UserID, connectionStringBuilder.Password).SecurePassword; password.MakeReadOnly(); var credential = new OracleCredential("system", password); @@ -124,7 +127,7 @@ public async Task be_healthy_with_connection_string_and_credential_when_oracle_i { services .AddHealthChecks() - .AddOracle(connectionString, tags: ["oracle"], + .AddOracle($"DATA SOURCE={connectionStringBuilder.DataSource}", tags: ["oracle"], configure: options => { factoryCalled = true; diff --git a/test/HealthChecks.Oracle.Tests/HealthChecks.Oracle.Tests.csproj b/test/HealthChecks.Oracle.Tests/HealthChecks.Oracle.Tests.csproj index 936df2da3a..112792fb95 100644 --- a/test/HealthChecks.Oracle.Tests/HealthChecks.Oracle.Tests.csproj +++ b/test/HealthChecks.Oracle.Tests/HealthChecks.Oracle.Tests.csproj @@ -4,4 +4,8 @@ + + + + diff --git a/test/HealthChecks.Oracle.Tests/OracleContainerFixture.cs b/test/HealthChecks.Oracle.Tests/OracleContainerFixture.cs new file mode 100644 index 0000000000..484aa8cb90 --- /dev/null +++ b/test/HealthChecks.Oracle.Tests/OracleContainerFixture.cs @@ -0,0 +1,42 @@ +using Oracle.ManagedDataAccess.Client; +using Testcontainers.Oracle; + +namespace HealthChecks.Oracle.Tests; + +public class OracleContainerFixture : IAsyncLifetime +{ + private const string Registry = "docker.io"; + + private const string Image = "gvenzl/oracle-xe"; + + private const string Tag = "21.3.0-slim-faststart"; + + public OracleContainer? Container { get; private set; } + + public string GetConnectionString() + { + if (Container is null) + { + throw new InvalidOperationException("The test container was not initialized."); + } + + return Container.GetConnectionString(); + } + + public OracleConnectionStringBuilder GetConnectionStringBuilder() => new(GetConnectionString()); + + public async Task InitializeAsync() => Container = await CreateContainerAsync(); + + public Task DisposeAsync() => Container?.DisposeAsync().AsTask() ?? Task.CompletedTask; + + private async Task CreateContainerAsync() + { + var container = new OracleBuilder() + .WithImage($"{Registry}/{Image}:{Tag}") + .Build(); + + await container.StartAsync(); + + return container; + } +}