From 2916c8093aafe3a9c43196b27b5cfa74507678e3 Mon Sep 17 00:00:00 2001 From: Mono <81423605+monofunc@users.noreply.github.com> Date: Thu, 14 Aug 2025 21:25:17 +0400 Subject: [PATCH] Migrate HealthChecks.ClickHouse tests to Testcontainers --- .../workflows/healthchecks_clickhouse_ci.yml | 51 ++----------------- Directory.Packages.props | 1 + .../ClickHouseContainerFixture.cs | 39 ++++++++++++++ .../Functional/ClickHouseHealthCheckTests.cs | 29 +++++++---- .../HealthChecks.ClickHouse.Tests.csproj | 4 ++ 5 files changed, 67 insertions(+), 57 deletions(-) create mode 100644 test/HealthChecks.ClickHouse.Tests/ClickHouseContainerFixture.cs diff --git a/.github/workflows/healthchecks_clickhouse_ci.yml b/.github/workflows/healthchecks_clickhouse_ci.yml index 710de009b1..8b9e1514b3 100644 --- a/.github/workflows/healthchecks_clickhouse_ci.yml +++ b/.github/workflows/healthchecks_clickhouse_ci.yml @@ -29,49 +29,8 @@ on: jobs: build: - runs-on: ubuntu-latest - services: - clickhouse: - image: clickhouse/clickhouse-server:24-alpine - ports: - - 8123:8123 - env: - CLICKHOUSE_DB: default - CLICKHOUSE_USER: default - CLICKHOUSE_PASSWORD: "Password12!" - CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: "1" - 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.ClickHouse/HealthChecks.ClickHouse.csproj && - dotnet restore ./test/HealthChecks.ClickHouse.Tests/HealthChecks.ClickHouse.Tests.csproj - - name: Check formatting - run: | - dotnet format --no-restore --verify-no-changes --severity warn ./src/HealthChecks.ClickHouse/HealthChecks.ClickHouse.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1) && - dotnet format --no-restore --verify-no-changes --severity warn ./test/HealthChecks.ClickHouse.Tests/HealthChecks.ClickHouse.Tests.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1) - - name: Build - run: | - dotnet build --no-restore ./src/HealthChecks.ClickHouse/HealthChecks.ClickHouse.csproj && - dotnet build --no-restore ./test/HealthChecks.ClickHouse.Tests/HealthChecks.ClickHouse.Tests.csproj - - name: Test - run: > - dotnet test - ./test/HealthChecks.ClickHouse.Tests/HealthChecks.ClickHouse.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: ClickHouse - directory: .coverage + uses: ./.github/workflows/reusable_ci_workflow.yml + with: + PROJECT_PATH: ./src/HealthChecks.ClickHouse/HealthChecks.ClickHouse.csproj + TEST_PROJECT_PATH: ./test/HealthChecks.ClickHouse.Tests/HealthChecks.ClickHouse.Tests.csproj + CODECOV_FLAGS: ClickHouse diff --git a/Directory.Packages.props b/Directory.Packages.props index 0fe654077e..1027e0f845 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -103,6 +103,7 @@ + diff --git a/test/HealthChecks.ClickHouse.Tests/ClickHouseContainerFixture.cs b/test/HealthChecks.ClickHouse.Tests/ClickHouseContainerFixture.cs new file mode 100644 index 0000000000..3060651aa6 --- /dev/null +++ b/test/HealthChecks.ClickHouse.Tests/ClickHouseContainerFixture.cs @@ -0,0 +1,39 @@ +using Testcontainers.ClickHouse; + +namespace HealthChecks.ClickHouse.Tests; + +public class ClickHouseContainerFixture : IAsyncLifetime +{ + private const string Registry = "docker.io"; + + private const string Image = "library/clickhouse"; + + private const string Tag = "25.7.2"; + + public ClickHouseContainer? Container { get; private set; } + + public string GetConnectionString() + { + if (Container is null) + { + throw new InvalidOperationException("The test container was not initialized."); + } + + return Container.GetConnectionString(); + } + + public async Task InitializeAsync() => Container = await CreateContainerAsync(); + + public Task DisposeAsync() => Container?.DisposeAsync().AsTask() ?? Task.CompletedTask; + + private async Task CreateContainerAsync() + { + var container = new ClickHouseBuilder() + .WithImage($"{Registry}/{Image}:{Tag}") + .Build(); + + await container.StartAsync(); + + return container; + } +} diff --git a/test/HealthChecks.ClickHouse.Tests/Functional/ClickHouseHealthCheckTests.cs b/test/HealthChecks.ClickHouse.Tests/Functional/ClickHouseHealthCheckTests.cs index 9d0a35420c..3cbf9f8552 100644 --- a/test/HealthChecks.ClickHouse.Tests/Functional/ClickHouseHealthCheckTests.cs +++ b/test/HealthChecks.ClickHouse.Tests/Functional/ClickHouseHealthCheckTests.cs @@ -10,18 +10,18 @@ public class DBConfigSetting public string ConnectionString { get; set; } = null!; } -public class ClickHouse_healthcheck_should +public class ClickHouse_healthcheck_should(ClickHouseContainerFixture clickHouseFixture) : IClassFixture { - private const string ConnectionString = "Host=127.0.0.1;Port=8123;Database=default;Username=default;Password=Password12!;"; + private readonly string _connectionString = clickHouseFixture.GetConnectionString(); [Fact] public async Task be_healthy_if_ClickHouse_is_available() { var webHostBuilder = new WebHostBuilder() - .ConfigureServices(static services => + .ConfigureServices(services => { services.AddHealthChecks() - .AddClickHouse(static _ => new ClickHouseConnection(ConnectionString), tags: new string[] { "ClickHouse" }); + .AddClickHouse(_ => new ClickHouseConnection(_connectionString), tags: new string[] { "ClickHouse" }); }) .Configure(static app => { @@ -42,10 +42,10 @@ public async Task be_healthy_if_ClickHouse_is_available() public async Task be_unhealthy_if_sql_query_is_not_valid() { var webHostBuilder = new WebHostBuilder() - .ConfigureServices(static services => + .ConfigureServices(services => { services.AddHealthChecks() - .AddClickHouse(static _ => new ClickHouseConnection(ConnectionString), "SELECT 1 FROM InvalidDB", tags: new string[] { "ClickHouse" }); + .AddClickHouse(_ => new ClickHouseConnection(_connectionString), "SELECT 1 FROM InvalidDB", tags: new string[] { "ClickHouse" }); }) .Configure(static app => { @@ -68,8 +68,11 @@ public async Task be_unhealthy_if_ClickHouse_is_not_available() var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => { - services.AddHealthChecks() - .AddClickHouse(static _ => new ClickHouseConnection("Host=200.0.0.1;Port=8123;Database=default;Username=default;Password=Password12!;"), tags: new string[] { "ClickHouse" }); + services + .AddHealthChecks() + .AddClickHouse(static _ => new ClickHouseConnection("Host=200.0.0.1;Port=8123;Database=default;Username=default;Password=Password12!;"), + tags: ["ClickHouse"], + timeout: TimeSpan.FromSeconds(15)); }) .Configure(app => { @@ -94,7 +97,7 @@ public async Task be_healthy_if_ClickHouse_is_available_by_iServiceProvider_regi { services.AddSingleton(new DBConfigSetting { - ConnectionString = ConnectionString + ConnectionString = _connectionString }); services.AddHealthChecks() @@ -126,8 +129,12 @@ public async Task be_unhealthy_if_ClickHouse_is_not_available_registered() ConnectionString = "Server=200.0.0.1;Port=8010;User ID=postgres;Password=Password12!;database=postgres" }); - services.AddHealthChecks() - .AddClickHouse(static sp => new ClickHouseConnection(sp.GetRequiredService().ConnectionString), tags: new string[] { "ClickHouse" }); + services + .AddHealthChecks() + .AddClickHouse( + static sp => new ClickHouseConnection(sp.GetRequiredService().ConnectionString), + tags: ["ClickHouse"], + timeout: TimeSpan.FromSeconds(15)); }) .Configure(app => { diff --git a/test/HealthChecks.ClickHouse.Tests/HealthChecks.ClickHouse.Tests.csproj b/test/HealthChecks.ClickHouse.Tests/HealthChecks.ClickHouse.Tests.csproj index 1ba4988d75..3436008ddc 100644 --- a/test/HealthChecks.ClickHouse.Tests/HealthChecks.ClickHouse.Tests.csproj +++ b/test/HealthChecks.ClickHouse.Tests/HealthChecks.ClickHouse.Tests.csproj @@ -4,4 +4,8 @@ + + + +