diff --git a/Testcontainers.sln b/Testcontainers.sln
index 793db4b9c..b867e19ff 100644
--- a/Testcontainers.sln
+++ b/Testcontainers.sln
@@ -15,6 +15,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{7164F1FB
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Azurite", "src\Testcontainers.Azurite\Testcontainers.Azurite.csproj", "{3F2E254F-C203-43FD-A078-DC3E2CBC0F9F}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.ClickHouse", "src\Testcontainers.ClickHouse\Testcontainers.ClickHouse.csproj", "{B061A78E-536E-4CA1-8401-234D5FBFBAB7}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.CosmosDb", "src\Testcontainers.CosmosDb\Testcontainers.CosmosDb.csproj", "{A724806F-8C94-4438-8011-04A9A1575318}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Couchbase", "src\Testcontainers.Couchbase\Testcontainers.Couchbase.csproj", "{58E94721-2681-4D82-8D94-0B2F9DB0D575}"
@@ -67,6 +69,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers", "src\Testc
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Azurite.Tests", "tests\Testcontainers.Azurite.Tests\Testcontainers.Azurite.Tests.csproj", "{B272FDDE-5E01-425D-B9E1-10FF883DDAAA}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.ClickHouse.Tests", "tests\Testcontainers.ClickHouse.Tests\Testcontainers.ClickHouse.Tests.csproj", "{9D0A0B32-4921-400C-99CB-8650677E3E44}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Commons", "tests\Testcontainers.Commons\Testcontainers.Commons.csproj", "{2478673C-B063-469D-ABD1-0C3E0A25541B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.CosmosDb.Tests", "tests\Testcontainers.CosmosDb.Tests\Testcontainers.CosmosDb.Tests.csproj", "{BD445A54-F411-4758-955E-397A1E98680C}"
@@ -138,6 +142,10 @@ Global
{3F2E254F-C203-43FD-A078-DC3E2CBC0F9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F2E254F-C203-43FD-A078-DC3E2CBC0F9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F2E254F-C203-43FD-A078-DC3E2CBC0F9F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B061A78E-536E-4CA1-8401-234D5FBFBAB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B061A78E-536E-4CA1-8401-234D5FBFBAB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B061A78E-536E-4CA1-8401-234D5FBFBAB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B061A78E-536E-4CA1-8401-234D5FBFBAB7}.Release|Any CPU.Build.0 = Release|Any CPU
{A724806F-8C94-4438-8011-04A9A1575318}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A724806F-8C94-4438-8011-04A9A1575318}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A724806F-8C94-4438-8011-04A9A1575318}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -242,6 +250,10 @@ Global
{B272FDDE-5E01-425D-B9E1-10FF883DDAAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B272FDDE-5E01-425D-B9E1-10FF883DDAAA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B272FDDE-5E01-425D-B9E1-10FF883DDAAA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9D0A0B32-4921-400C-99CB-8650677E3E44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9D0A0B32-4921-400C-99CB-8650677E3E44}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9D0A0B32-4921-400C-99CB-8650677E3E44}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9D0A0B32-4921-400C-99CB-8650677E3E44}.Release|Any CPU.Build.0 = Release|Any CPU
{2478673C-B063-469D-ABD1-0C3E0A25541B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2478673C-B063-469D-ABD1-0C3E0A25541B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2478673C-B063-469D-ABD1-0C3E0A25541B}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -361,6 +373,7 @@ Global
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{3F2E254F-C203-43FD-A078-DC3E2CBC0F9F} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
+ {B061A78E-536E-4CA1-8401-234D5FBFBAB7} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{A724806F-8C94-4438-8011-04A9A1575318} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{58E94721-2681-4D82-8D94-0B2F9DB0D575} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{DCECB1F6-D9AA-431F-AE42-25D56B9E7DFC} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
@@ -387,6 +400,7 @@ Global
{64A87DE5-29B0-4A54-9E74-560484D8C7C0} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{EC76857B-A3B8-4B7A-A1B0-8D867A4D1733} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{B272FDDE-5E01-425D-B9E1-10FF883DDAAA} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
+ {9D0A0B32-4921-400C-99CB-8650677E3E44} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{2478673C-B063-469D-ABD1-0C3E0A25541B} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{BD445A54-F411-4758-955E-397A1E98680C} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{809322BA-D690-4F2B-B884-23F895663963} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
diff --git a/docs/modules/index.md b/docs/modules/index.md
index cae3770ad..f4482058b 100644
--- a/docs/modules/index.md
+++ b/docs/modules/index.md
@@ -24,6 +24,7 @@ await moduleNameContainer.StartAsync();
| Azure Cosmos DB | `mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest` | [NuGet](https://www.nuget.org/packages/Testcontainers.CosmosDb) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.CosmosDb) |
| Azure SQL Edge | `mcr.microsoft.com/azure-sql-edge:1.0.7` | [NuGet](https://www.nuget.org/packages/Testcontainers.SqlEdge) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.SqlEdge) |
| Azurite | `mcr.microsoft.com/azure-storage/azurite:3.23.0` | [NuGet](https://www.nuget.org/packages/Testcontainers.Azurite) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Azurite) |
+| ClickHouse | `clickhouse/clickhouse-server:23.6-alpine` | [NuGet](https://www.nuget.org/packages/Testcontainers.ClickHouse) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.ClickHouse) |
| Couchbase | `couchbase:community-7.0.2` | [NuGet](https://www.nuget.org/packages/Testcontainers.Couchbase) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Couchbase) |
| CouchDB | `couchdb:3.3` | [NuGet](https://www.nuget.org/packages/Testcontainers.CouchDb) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.CouchDb) |
| DynamoDB | `amazon/dynamodb-local:1.21.0` | [NuGet](https://www.nuget.org/packages/Testcontainers.DynamoDb) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.DynamoDb) |
@@ -31,6 +32,7 @@ await moduleNameContainer.StartAsync();
| EventStoreDB | `eventstore/eventstore:22.10.1-buster-slim` | [NuGet](https://www.nuget.org/packages/Testcontainers.EventStoreDb) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.EventStoreDb) |
| K3s | `rancher/k3s:v1.26.2-k3s1` | [NuGet](https://www.nuget.org/packages/Testcontainers.K3s) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.K3s) |
| Kafka | `confluentinc/cp-kafka:6.1.9` | [NuGet](https://www.nuget.org/packages/Testcontainers.Kafka) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Kafka) |
+| Keycloak | `quay.io/keycloak/keycloak:21.1` | [NuGet](https://www.nuget.org/packages/Testcontainers.Keycloak) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Keycloak) |
| LocalStack | `localstack/localstack:2.0` | [NuGet](https://www.nuget.org/packages/Testcontainers.LocalStack) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.LocalStack) |
| MariaDB | `mariadb:10.10` | [NuGet](https://www.nuget.org/packages/Testcontainers.MariaDb) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.MariaDb) |
| MinIO | `minio/minio:RELEASE.2023-01-31T02-24-19Z` | [NuGet](https://www.nuget.org/packages/Testcontainers.Minio) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Minio) |
@@ -44,6 +46,7 @@ await moduleNameContainer.StartAsync();
| Redis | `redis:7.0` | [NuGet](https://www.nuget.org/packages/Testcontainers.Redis) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Redis) |
| Redpanda | `docker.redpanda.com/redpandadata/redpanda:v22.2.1` | [NuGet](https://www.nuget.org/packages/Testcontainers.Redpanda) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Redpanda) |
| SQL Server | `mcr.microsoft.com/mssql/server:2019-CU18-ubuntu-20.04` | [NuGet](https://www.nuget.org/packages/Testcontainers.MsSql) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.MsSql) |
+| WebDriver | `selenium/standalone-chrome:110.0` | [NuGet](https://www.nuget.org/packages/Testcontainers.WebDriver) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.WebDriver) |
## Implement a module
diff --git a/src/Testcontainers.ClickHouse/.editorconfig b/src/Testcontainers.ClickHouse/.editorconfig
new file mode 100644
index 000000000..6f066619d
--- /dev/null
+++ b/src/Testcontainers.ClickHouse/.editorconfig
@@ -0,0 +1 @@
+root = true
\ No newline at end of file
diff --git a/src/Testcontainers.ClickHouse/ClickHouseBuilder.cs b/src/Testcontainers.ClickHouse/ClickHouseBuilder.cs
new file mode 100644
index 000000000..e3871b0fe
--- /dev/null
+++ b/src/Testcontainers.ClickHouse/ClickHouseBuilder.cs
@@ -0,0 +1,131 @@
+namespace Testcontainers.ClickHouse;
+
+///
+[PublicAPI]
+public sealed class ClickHouseBuilder : ContainerBuilder
+{
+ public const string ClickHouseImage = "clickhouse/clickhouse-server:23.6-alpine";
+
+ public const ushort HttpPort = 8123;
+
+ public const ushort NativePort = 9000;
+
+ public const string DefaultDatabase = "default";
+
+ public const string DefaultUsername = "clickhouse";
+
+ public const string DefaultPassword = "clickhouse";
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ClickHouseBuilder()
+ : this(new ClickHouseConfiguration())
+ {
+ DockerResourceConfiguration = Init().DockerResourceConfiguration;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Docker resource configuration.
+ private ClickHouseBuilder(ClickHouseConfiguration resourceConfiguration)
+ : base(resourceConfiguration)
+ {
+ DockerResourceConfiguration = resourceConfiguration;
+ }
+
+ ///
+ protected override ClickHouseConfiguration DockerResourceConfiguration { get; }
+
+ ///
+ /// Sets the ClickHouse database.
+ ///
+ /// The ClickHouse database.
+ /// A configured instance of .
+ public ClickHouseBuilder WithDatabase(string database)
+ {
+ return Merge(DockerResourceConfiguration, new ClickHouseConfiguration(database: database))
+ .WithEnvironment("CLICKHOUSE_DB", database);
+ }
+
+ ///
+ /// Sets the ClickHouse username.
+ ///
+ /// The ClickHouse username.
+ /// A configured instance of .
+ public ClickHouseBuilder WithUsername(string username)
+ {
+ return Merge(DockerResourceConfiguration, new ClickHouseConfiguration(username: username))
+ .WithEnvironment("CLICKHOUSE_USER", username);
+ }
+
+ ///
+ /// Sets the ClickHouse password.
+ ///
+ /// The ClickHouse password.
+ /// A configured instance of .
+ public ClickHouseBuilder WithPassword(string password)
+ {
+ return Merge(DockerResourceConfiguration, new ClickHouseConfiguration(password: password))
+ .WithEnvironment("CLICKHOUSE_PASSWORD", password);
+ }
+
+ ///
+ public override ClickHouseContainer Build()
+ {
+ Validate();
+ return new ClickHouseContainer(DockerResourceConfiguration, TestcontainersSettings.Logger);
+ }
+
+ ///
+ protected override ClickHouseBuilder Init()
+ {
+ return base.Init()
+ .WithImage(ClickHouseImage)
+ .WithPortBinding(HttpPort, true)
+ .WithPortBinding(NativePort, true)
+ .WithEnvironment("CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT", "1")
+ .WithDatabase(DefaultDatabase)
+ .WithUsername(DefaultUsername)
+ .WithPassword(DefaultPassword)
+ .WithWaitStrategy(Wait.ForUnixContainer().UntilHttpRequestIsSucceeded(request =>
+ request.ForPort(HttpPort).ForResponseMessageMatching(IsNodeReadyAsync)));
+ }
+
+ ///
+ protected override void Validate()
+ {
+ base.Validate();
+
+ _ = Guard.Argument(DockerResourceConfiguration.Password, nameof(DockerResourceConfiguration.Password))
+ .NotNull()
+ .NotEmpty();
+ }
+
+ ///
+ protected override ClickHouseBuilder Clone(IResourceConfiguration resourceConfiguration)
+ {
+ return Merge(DockerResourceConfiguration, new ClickHouseConfiguration(resourceConfiguration));
+ }
+
+ ///
+ protected override ClickHouseBuilder Clone(IContainerConfiguration resourceConfiguration)
+ {
+ return Merge(DockerResourceConfiguration, new ClickHouseConfiguration(resourceConfiguration));
+ }
+
+ ///
+ protected override ClickHouseBuilder Merge(ClickHouseConfiguration oldValue, ClickHouseConfiguration newValue)
+ {
+ return new ClickHouseBuilder(new ClickHouseConfiguration(oldValue, newValue));
+ }
+
+ private async Task IsNodeReadyAsync(HttpResponseMessage response)
+ {
+ var content = await response.Content.ReadAsStringAsync()
+ .ConfigureAwait(false);
+
+ return "Ok.\n".Equals(content, StringComparison.OrdinalIgnoreCase);
+ }
+}
\ No newline at end of file
diff --git a/src/Testcontainers.ClickHouse/ClickHouseConfiguration.cs b/src/Testcontainers.ClickHouse/ClickHouseConfiguration.cs
new file mode 100644
index 000000000..f65b3c2ad
--- /dev/null
+++ b/src/Testcontainers.ClickHouse/ClickHouseConfiguration.cs
@@ -0,0 +1,80 @@
+namespace Testcontainers.ClickHouse;
+
+///
+[PublicAPI]
+public sealed class ClickHouseConfiguration : ContainerConfiguration
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The ClickHouse database.
+ /// The ClickHouse username.
+ /// The ClickHouse password.
+ public ClickHouseConfiguration(
+ string database = null,
+ string username = null,
+ string password = null)
+ {
+ Database = database;
+ Username = username;
+ Password = password;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Docker resource configuration.
+ public ClickHouseConfiguration(IResourceConfiguration resourceConfiguration)
+ : base(resourceConfiguration)
+ {
+ // Passes the configuration upwards to the base implementations to create an updated immutable copy.
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Docker resource configuration.
+ public ClickHouseConfiguration(IContainerConfiguration resourceConfiguration)
+ : base(resourceConfiguration)
+ {
+ // Passes the configuration upwards to the base implementations to create an updated immutable copy.
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Docker resource configuration.
+ public ClickHouseConfiguration(ClickHouseConfiguration resourceConfiguration)
+ : this(new ClickHouseConfiguration(), resourceConfiguration)
+ {
+ // Passes the configuration upwards to the base implementations to create an updated immutable copy.
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The old Docker resource configuration.
+ /// The new Docker resource configuration.
+ public ClickHouseConfiguration(ClickHouseConfiguration oldValue, ClickHouseConfiguration newValue)
+ : base(oldValue, newValue)
+ {
+ Database = BuildConfiguration.Combine(oldValue.Database, newValue.Database);
+ Username = BuildConfiguration.Combine(oldValue.Username, newValue.Username);
+ Password = BuildConfiguration.Combine(oldValue.Password, newValue.Password);
+ }
+
+ ///
+ /// Gets the ClickHouse database.
+ ///
+ public string Database { get; }
+
+ ///
+ /// Gets the ClickHouse username.
+ ///
+ public string Username { get; }
+
+ ///
+ /// Gets the ClickHouse password.
+ ///
+ public string Password { get; }
+}
\ No newline at end of file
diff --git a/src/Testcontainers.ClickHouse/ClickHouseContainer.cs b/src/Testcontainers.ClickHouse/ClickHouseContainer.cs
new file mode 100644
index 000000000..3b7328860
--- /dev/null
+++ b/src/Testcontainers.ClickHouse/ClickHouseContainer.cs
@@ -0,0 +1,51 @@
+namespace Testcontainers.ClickHouse;
+
+///
+[PublicAPI]
+public sealed class ClickHouseContainer : DockerContainer
+{
+ private readonly ClickHouseConfiguration _configuration;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The container configuration.
+ /// The logger.
+ public ClickHouseContainer(ClickHouseConfiguration configuration, ILogger logger)
+ : base(configuration, logger)
+ {
+ _configuration = configuration;
+ }
+
+ ///
+ /// Gets the ClickHouse connection string.
+ ///
+ /// The ClickHouse connection string.
+ public string GetConnectionString()
+ {
+ var properties = new Dictionary();
+ properties.Add("Host", Hostname);
+ properties.Add("Port", GetMappedPublicPort(ClickHouseBuilder.HttpPort).ToString());
+ properties.Add("Database", _configuration.Database);
+ properties.Add("Username", _configuration.Username);
+ properties.Add("Password", _configuration.Password);
+ return string.Join(";", properties.Select(property => string.Join("=", property.Key, property.Value)));
+ }
+
+ ///
+ /// Executes the SQL script in the ClickHouse container.
+ ///
+ /// The content of the SQL script to execute.
+ /// Cancellation token.
+ /// Task that completes when the SQL script has been executed.
+ public async Task ExecScriptAsync(string scriptContent, CancellationToken ct = default)
+ {
+ var scriptFilePath = string.Join("/", string.Empty, "tmp", Guid.NewGuid().ToString("D"), Path.GetRandomFileName());
+
+ await CopyAsync(Encoding.Default.GetBytes(scriptContent), scriptFilePath, Unix.FileMode644, ct)
+ .ConfigureAwait(false);
+
+ return await ExecAsync(new[] { "clickhouse-client", "--database", _configuration.Database, "--queries-file", scriptFilePath }, ct)
+ .ConfigureAwait(false);
+ }
+}
\ No newline at end of file
diff --git a/src/Testcontainers.ClickHouse/Testcontainers.ClickHouse.csproj b/src/Testcontainers.ClickHouse/Testcontainers.ClickHouse.csproj
new file mode 100644
index 000000000..4c05d521f
--- /dev/null
+++ b/src/Testcontainers.ClickHouse/Testcontainers.ClickHouse.csproj
@@ -0,0 +1,13 @@
+
+
+ netstandard2.0;netstandard2.1
+ latest
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Testcontainers.ClickHouse/Usings.cs b/src/Testcontainers.ClickHouse/Usings.cs
new file mode 100644
index 000000000..fa70e2120
--- /dev/null
+++ b/src/Testcontainers.ClickHouse/Usings.cs
@@ -0,0 +1,15 @@
+global using System;
+global using System.Collections.Generic;
+global using System.IO;
+global using System.Linq;
+global using System.Net.Http;
+global using System.Text;
+global using System.Threading;
+global using System.Threading.Tasks;
+global using Docker.DotNet.Models;
+global using DotNet.Testcontainers;
+global using DotNet.Testcontainers.Builders;
+global using DotNet.Testcontainers.Configurations;
+global using DotNet.Testcontainers.Containers;
+global using JetBrains.Annotations;
+global using Microsoft.Extensions.Logging;
\ No newline at end of file
diff --git a/src/Testcontainers.Keycloak/Usings.cs b/src/Testcontainers.Keycloak/Usings.cs
index 4ec1e3a96..c6ee33b57 100644
--- a/src/Testcontainers.Keycloak/Usings.cs
+++ b/src/Testcontainers.Keycloak/Usings.cs
@@ -1,5 +1,4 @@
global using System;
-global using System.Threading.Tasks;
global using Docker.DotNet.Models;
global using DotNet.Testcontainers;
global using DotNet.Testcontainers.Builders;
diff --git a/tests/Testcontainers.ClickHouse.Tests/.editorconfig b/tests/Testcontainers.ClickHouse.Tests/.editorconfig
new file mode 100644
index 000000000..6f066619d
--- /dev/null
+++ b/tests/Testcontainers.ClickHouse.Tests/.editorconfig
@@ -0,0 +1 @@
+root = true
\ No newline at end of file
diff --git a/tests/Testcontainers.ClickHouse.Tests/ClickHouseContainerTest.cs b/tests/Testcontainers.ClickHouse.Tests/ClickHouseContainerTest.cs
new file mode 100644
index 000000000..f48af2f52
--- /dev/null
+++ b/tests/Testcontainers.ClickHouse.Tests/ClickHouseContainerTest.cs
@@ -0,0 +1,45 @@
+namespace Testcontainers.ClickHouse;
+
+public sealed class ClickHouseContainerTest : IAsyncLifetime
+{
+ private readonly ClickHouseContainer _clickHouseContainer = new ClickHouseBuilder().Build();
+
+ public Task InitializeAsync()
+ {
+ return _clickHouseContainer.StartAsync();
+ }
+
+ public Task DisposeAsync()
+ {
+ return _clickHouseContainer.DisposeAsync().AsTask();
+ }
+
+ [Fact]
+ [Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))]
+ public void ConnectionStateReturnsOpen()
+ {
+ // Given
+ using DbConnection connection = new ClickHouseConnection(_clickHouseContainer.GetConnectionString());
+
+ // When
+ connection.Open();
+
+ // Then
+ Assert.Equal(ConnectionState.Open, connection.State);
+ }
+
+ [Fact]
+ [Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))]
+ public async Task ExecScriptReturnsSuccessful()
+ {
+ // Given
+ const string scriptContent = "SELECT 1;";
+
+ // When
+ var execResult = await _clickHouseContainer.ExecScriptAsync(scriptContent)
+ .ConfigureAwait(false);
+
+ // When
+ Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
+ }
+}
\ No newline at end of file
diff --git a/tests/Testcontainers.ClickHouse.Tests/Testcontainers.ClickHouse.Tests.csproj b/tests/Testcontainers.ClickHouse.Tests/Testcontainers.ClickHouse.Tests.csproj
new file mode 100644
index 000000000..bc925adde
--- /dev/null
+++ b/tests/Testcontainers.ClickHouse.Tests/Testcontainers.ClickHouse.Tests.csproj
@@ -0,0 +1,18 @@
+
+
+ net6.0
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/Testcontainers.ClickHouse.Tests/Usings.cs b/tests/Testcontainers.ClickHouse.Tests/Usings.cs
new file mode 100644
index 000000000..349e20d26
--- /dev/null
+++ b/tests/Testcontainers.ClickHouse.Tests/Usings.cs
@@ -0,0 +1,6 @@
+global using System.Data;
+global using System.Data.Common;
+global using System.Threading.Tasks;
+global using ClickHouse.Client.ADO;
+global using DotNet.Testcontainers.Commons;
+global using Xunit;
\ No newline at end of file