From fcf80d60b8b9f241ef1cd3e2169587077c6e2b5f Mon Sep 17 00:00:00 2001 From: Jesse Wellenberg <48557715+Yeseh@users.noreply.github.com> Date: Mon, 25 Jul 2022 21:24:09 +0200 Subject: [PATCH 01/38] Add CosmosDBTestcontainerConfiguration --- .../CosmosDbTestcontainerConfiguration.cs | 51 +++++++++++++++++++ src/Testcontainers/Testcontainers.csproj | 1 + 2 files changed, 52 insertions(+) create mode 100644 src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs new file mode 100644 index 000000000..cd0bc9c27 --- /dev/null +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -0,0 +1,51 @@ +namespace DotNet.Testcontainers.Configurations +{ + using DotNet.Testcontainers.Builders; + using JetBrains.Annotations; + + [PublicAPI] + public class CosmosDbTestcontainerConfiguration : TestcontainerDatabaseConfiguration + { + private const string CosmosDbImage = "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator"; + + private const int CosmosDbPort = 8081; + + public CosmosDbTestcontainerConfiguration() + : this(CosmosDbImage) + { + + } + + public CosmosDbTestcontainerConfiguration(string image) + : base(image, CosmosDbPort) + { + } + + public override string Database + { + get => this.Environments["AZURE_COSMOS_EMULATOR_DATABASE"]; + set => this.Environments["AZURE_COSMOS_EMULATOR_DATABASE"] = value; + } + + public string PartitionCount + { + get => this.Environments["AZURE_COSMOS_EMULATOR_PARTITION_COUNT"]; + set => this.Environments["AZURE_COSMOS_EMULATOR_PARTITION_COUNT"] = value; + } + + public string EnableDataPersistence + { + get => this.Environments["AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE"]; + set => this.Environments["AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE"] = value; + } + + public string IPAddressOverride + { + get => this.Environments["AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE"]; + set => this.Environments["AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE"] = value; + } + + public override IWaitForContainerOS WaitStrategy => Wait.ForUnixContainer() + .UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started"); + } +} \ No newline at end of file diff --git a/src/Testcontainers/Testcontainers.csproj b/src/Testcontainers/Testcontainers.csproj index 1c67783b2..f476b9c42 100644 --- a/src/Testcontainers/Testcontainers.csproj +++ b/src/Testcontainers/Testcontainers.csproj @@ -9,6 +9,7 @@ + From 75bfbf3e2d3bd6fe11e7bacfb63420d27e892b68 Mon Sep 17 00:00:00 2001 From: Jesse Wellenberg <48557715+Yeseh@users.noreply.github.com> Date: Mon, 25 Jul 2022 22:43:03 +0200 Subject: [PATCH 02/38] Implement CosmosDbTestContainer --- .../Databases/CosmosDbTestcontainer.cs | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs new file mode 100644 index 000000000..2b32953a7 --- /dev/null +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -0,0 +1,59 @@ +namespace DotNet.Testcontainers.Containers +{ + using System.Collections.Generic; + using System.Net.Http; + using System.Threading.Tasks; + using DotNet.Testcontainers.Configurations; + using Microsoft.Extensions.Logging; + using System.Text.Json; + + public sealed class CosmosDbTestcontainer : TestcontainerDatabase + { + private readonly string CosmosUrl; + + private HttpClient HttpClient; + + internal CosmosDbTestcontainer(ITestcontainersConfiguration configuration, ILogger logger) + : base(configuration, logger) + { + CosmosUrl = $"https://{this.Username}.documents.azure.com/dbs/{this.Database}"; + } + + public override string ConnectionString + => $"AccountEndpoint=https://{this.Username}:{this.Port}.documents.azure.com:443/;AccountKey={this.Password}"; + + public async Task QueryAsync( + string queryString, IEnumerable> parameters) + { + var client = GetHttpClient(); + var parJsonStr = JsonSerializer.Serialize(parameters); + var body = new { Query = queryString, Parameters = parJsonStr }; + var reqBodyStr = JsonSerializer.Serialize(body); + var content = new StringContent(reqBodyStr); + + var response = await HttpClient.PostAsync(CosmosUrl, content); + + return response; + } + + // Setup HttpClient following: + // https://docs.microsoft.com/en-us/rest/api/cosmos-db/querying-cosmosdb-resources-using-the-rest-api#how-do-i-query-a-resource-by-using-rest + private HttpClient GetHttpClient() + { + if (HttpClient != null) return HttpClient; + + var client = new HttpClient(); + var authHeaderValue = System.Web.HttpUtility.UrlEncode($"type=master&ver=1.0&sig={this.Password}"); + + client.DefaultRequestHeaders.Add("x-ms-documentdb-isquery", "true"); + client.DefaultRequestHeaders.Add("x-ms-documentdb-query-enablecrosspartition", "true"); + client.DefaultRequestHeaders.Add("x-ms-version", "2018-12-31"); + client.DefaultRequestHeaders.Add("x-ms-date", System.DateTime.UtcNow.ToLongTimeString()); + client.DefaultRequestHeaders.Add("authorization", authHeaderValue); + client.DefaultRequestHeaders.Add("Content-Type", "application/query+json"); + client.DefaultRequestHeaders.Add("Content-Type", "application/query+json"); + + return HttpClient; + } + } +} \ No newline at end of file From 301c551b73552989f3c0de0df23a35a5d15515fb Mon Sep 17 00:00:00 2001 From: Jesse Wellenberg <48557715+Yeseh@users.noreply.github.com> Date: Mon, 25 Jul 2022 22:58:32 +0200 Subject: [PATCH 03/38] Implement CosmosDbFixture --- .../CosmosDbTestcontainerConfiguration.cs | 28 +++++++++++++------ .../Databases/CosmosDbTestcontainer.cs | 11 ++++++-- src/Testcontainers/Testcontainers.csproj | 1 - 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs index cd0bc9c27..0d05340d9 100644 --- a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -1,24 +1,36 @@ namespace DotNet.Testcontainers.Configurations { - using DotNet.Testcontainers.Builders; - using JetBrains.Annotations; + using DotNet.Testcontainers.Builders; + using JetBrains.Annotations; - [PublicAPI] + [PublicAPI] public class CosmosDbTestcontainerConfiguration : TestcontainerDatabaseConfiguration { - private const string CosmosDbImage = "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator"; + private const string CosmosDbImage = + "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator"; private const int CosmosDbPort = 8081; + private const string CosmosDbDefaultKey = + "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="; + + private const string CosmosDbDefaultAccountName = + "localhost:8081"; + public CosmosDbTestcontainerConfiguration() - : this(CosmosDbImage) - { + : this(CosmosDbImage) { } + public CosmosDbTestcontainerConfiguration(string image) + : base(image, CosmosDbPort) { } + + public override string Username + { + get => CosmosDbDefaultAccountName; } - public CosmosDbTestcontainerConfiguration(string image) - : base(image, CosmosDbPort) + public override string Password { + get => CosmosDbDefaultKey; } public override string Database diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index 2b32953a7..3b54f1be9 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -23,7 +23,7 @@ public override string ConnectionString => $"AccountEndpoint=https://{this.Username}:{this.Port}.documents.azure.com:443/;AccountKey={this.Password}"; public async Task QueryAsync( - string queryString, IEnumerable> parameters) + string queryString, IEnumerable> parameters = default) { var client = GetHttpClient(); var parJsonStr = JsonSerializer.Serialize(parameters); @@ -35,7 +35,14 @@ public async Task QueryAsync( return response; } - + + public async Task CreateDatabaseAsync() + { + var client = GetHttpClient(); + var response = await HttpClient.PostAsync(CosmosUrl, null); + + return response; + } // Setup HttpClient following: // https://docs.microsoft.com/en-us/rest/api/cosmos-db/querying-cosmosdb-resources-using-the-rest-api#how-do-i-query-a-resource-by-using-rest private HttpClient GetHttpClient() diff --git a/src/Testcontainers/Testcontainers.csproj b/src/Testcontainers/Testcontainers.csproj index f476b9c42..1c67783b2 100644 --- a/src/Testcontainers/Testcontainers.csproj +++ b/src/Testcontainers/Testcontainers.csproj @@ -9,7 +9,6 @@ - From 32803e21378ff1486d81c615009d6f7339c448fd Mon Sep 17 00:00:00 2001 From: Jesse Wellenberg <48557715+Yeseh@users.noreply.github.com> Date: Mon, 25 Jul 2022 23:19:08 +0200 Subject: [PATCH 04/38] Write first test (not working) --- .../Databases/CosmosDbTestcontainer.cs | 4 +- .../Unix/Modules/Databases/CosmosDbFixture.cs | 49 +++++++++++++++++++ .../Databases/CosmosDbTestcontainerTest.cs | 25 ++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs create mode 100644 tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index 3b54f1be9..59e9f71d9 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -14,7 +14,7 @@ public sealed class CosmosDbTestcontainer : TestcontainerDatabase private HttpClient HttpClient; internal CosmosDbTestcontainer(ITestcontainersConfiguration configuration, ILogger logger) - : base(configuration, logger) + : base(configuration, logger) { CosmosUrl = $"https://{this.Username}.documents.azure.com/dbs/{this.Database}"; } @@ -58,7 +58,7 @@ private HttpClient GetHttpClient() client.DefaultRequestHeaders.Add("x-ms-date", System.DateTime.UtcNow.ToLongTimeString()); client.DefaultRequestHeaders.Add("authorization", authHeaderValue); client.DefaultRequestHeaders.Add("Content-Type", "application/query+json"); - client.DefaultRequestHeaders.Add("Content-Type", "application/query+json"); + client.DefaultRequestHeaders.Add("Accept", "application/json"); return HttpClient; } diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs new file mode 100644 index 000000000..686d08c5c --- /dev/null +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -0,0 +1,49 @@ +namespace DotNet.Testcontainers.Tests.Fixtures +{ + using System.Data.Common; + using System.Threading.Tasks; + using DotNet.Testcontainers.Builders; + using DotNet.Testcontainers.Configurations; + using DotNet.Testcontainers.Containers; + using Npgsql; + + public sealed class CosmosDbFixture : DatabaseFixture + { + private readonly TestcontainerDatabaseConfiguration configuration = + new CosmosDbTestcontainerConfiguration{ Database = "testdb" }; + + public CosmosDbFixture() + { + this.Container = new TestcontainersBuilder() + .WithDatabase(this.configuration) + .Build(); + } + + public override async Task InitializeAsync() + { + await this.Container.StartAsync() + .ConfigureAwait(false); + + // var dbResponse = await this.Container.CreateDatabaseAsync() + // .ConfigureAwait(false); + + // if (dbResponse.StatusCode != System.Net.HttpStatusCode.Created) + // { + // throw new System.Exception("Failed to create database"); + // } + } + + public override async Task DisposeAsync() + { + this.Connection.Dispose(); + + await this.Container.DisposeAsync() + .ConfigureAwait(false); + } + + public override void Dispose() + { + this.configuration.Dispose(); + } + } +} \ No newline at end of file diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs new file mode 100644 index 000000000..d2ab8d7f1 --- /dev/null +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -0,0 +1,25 @@ +namespace DotNet.Testcontainers.Tests.Unit +{ + using DotNet.Testcontainers.Tests.Fixtures; + using System.Threading.Tasks; + using Xunit; + + public class CosmosDbTestcontainerTest : IClassFixture + { + private readonly CosmosDbFixture cosmosDbFixture; + + public CosmosDbTestcontainerTest(CosmosDbFixture cosmosDbFixture) + { + this.cosmosDbFixture = cosmosDbFixture; + } + + [Fact] + public async Task DatabaseCreated() + { + var dbResponse = await this.cosmosDbFixture.Container.CreateDatabaseAsync() + .ConfigureAwait(false); + + Assert.Equal(dbResponse.StatusCode, System.Net.HttpStatusCode.Created); + } + } +} \ No newline at end of file From 6d0ae41c7b38ccb1c3e23bb14d3148dc403cb384 Mon Sep 17 00:00:00 2001 From: Jesse Wellenberg <48557715+Yeseh@users.noreply.github.com> Date: Tue, 2 Aug 2022 22:05:18 +0200 Subject: [PATCH 05/38] Working initial setup, database creation --- .../CosmosDbTestcontainerConfiguration.cs | 10 ++- .../Databases/CosmosDbTestcontainer.cs | 84 ++++++++++++++----- .../Unix/Modules/Databases/CosmosDbFixture.cs | 24 ++++-- .../Databases/CosmosDbTestcontainerTest.cs | 8 +- 4 files changed, 91 insertions(+), 35 deletions(-) diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs index 0d05340d9..602dbaa85 100644 --- a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -21,7 +21,10 @@ public CosmosDbTestcontainerConfiguration() : this(CosmosDbImage) { } public CosmosDbTestcontainerConfiguration(string image) - : base(image, CosmosDbPort) { } + : base(image, CosmosDbPort, CosmosDbPort) + { + this.Environments.Add("AZURE_COSMOS_EMULATOR_PARTITION_COUNT", "1"); + } public override string Username { @@ -58,6 +61,7 @@ public string IPAddressOverride } public override IWaitForContainerOS WaitStrategy => Wait.ForUnixContainer() - .UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started"); + .UntilCommandIsCompleted("ls"); + //.UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started"); } -} \ No newline at end of file +} diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index 59e9f71d9..8d928148e 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -6,17 +6,20 @@ namespace DotNet.Testcontainers.Containers using DotNet.Testcontainers.Configurations; using Microsoft.Extensions.Logging; using System.Text.Json; + using System; + using System.Threading; + using System.Text; public sealed class CosmosDbTestcontainer : TestcontainerDatabase { - private readonly string CosmosUrl; + private string CosmosUrl; private HttpClient HttpClient; internal CosmosDbTestcontainer(ITestcontainersConfiguration configuration, ILogger logger) : base(configuration, logger) { - CosmosUrl = $"https://{this.Username}.documents.azure.com/dbs/{this.Database}"; + CosmosUrl = $"https://{this.Username}.documents.azure.com/dbs"; } public override string ConnectionString @@ -25,42 +28,83 @@ public override string ConnectionString public async Task QueryAsync( string queryString, IEnumerable> parameters = default) { + Console.WriteLine("Executing query..."); var client = GetHttpClient(); - var parJsonStr = JsonSerializer.Serialize(parameters); + var parJsonStr =JsonSerializer.Serialize(parameters); var body = new { Query = queryString, Parameters = parJsonStr }; var reqBodyStr = JsonSerializer.Serialize(body); var content = new StringContent(reqBodyStr); - var response = await HttpClient.PostAsync(CosmosUrl, content); + var response = await client.PostAsync(CosmosUrl, content); return response; } - + // TODO: Call this implicitly on initialize public async Task CreateDatabaseAsync() { + Console.WriteLine("Attempting to create database..."); + var url = $"https://localhost:8081/dbs"; var client = GetHttpClient(); - var response = await HttpClient.PostAsync(CosmosUrl, null); + var jsonData = JsonSerializer.Serialize(new { id = string.IsNullOrEmpty(this.Database) ? "testdb" : this.Database }); + var contentData = new StringContent(jsonData, Encoding.UTF8, "application/json"); + var response = await client.PostAsync(url, contentData).ConfigureAwait(false); return response; } - // Setup HttpClient following: - // https://docs.microsoft.com/en-us/rest/api/cosmos-db/querying-cosmosdb-resources-using-the-rest-api#how-do-i-query-a-resource-by-using-rest + private HttpClient GetHttpClient() { - if (HttpClient != null) return HttpClient; + if (HttpClient != null) return HttpClient; + + var handler = new CosmosDbHttpHandler(this.Password); + var client = new HttpClient(handler); + + HttpClient = client; + return HttpClient; + } + + private sealed class CosmosDbHttpHandler : HttpClientHandler + { + private readonly string _password; + + public CosmosDbHttpHandler(string password) + { + this._password = password; + // Skip SSL certificate validation + // https://docs.microsoft.com/en-us/azure/cosmos-db/local-emulator?tabs=ssl-netstd21#disable-ssl-validation + this.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; + } + + // https://stackoverflow.com/questions/52262767/cosmos-db-rest-api-create-user-permissio + protected override Task SendAsync( + HttpRequestMessage request, CancellationToken ct) + { + var hmac = new System.Security.Cryptography.HMACSHA256() + { + Key = Convert.FromBase64String(this._password) + }; + + var date = DateTime.UtcNow.ToString("r"); + var payload = "POST".ToLowerInvariant() + "\n" + + "dbs".ToLowerInvariant() + "\n" + + "" + "\n" + + date.ToLowerInvariant() + "\n" + + "" + "\n"; - var client = new HttpClient(); - var authHeaderValue = System.Web.HttpUtility.UrlEncode($"type=master&ver=1.0&sig={this.Password}"); + var hashPayload = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload)); + var signature = Convert.ToBase64String(hashPayload); + var authHeaderValue = System.Web.HttpUtility.UrlEncode($"type=master&ver=1.0&sig={signature}"); - client.DefaultRequestHeaders.Add("x-ms-documentdb-isquery", "true"); - client.DefaultRequestHeaders.Add("x-ms-documentdb-query-enablecrosspartition", "true"); - client.DefaultRequestHeaders.Add("x-ms-version", "2018-12-31"); - client.DefaultRequestHeaders.Add("x-ms-date", System.DateTime.UtcNow.ToLongTimeString()); - client.DefaultRequestHeaders.Add("authorization", authHeaderValue); - client.DefaultRequestHeaders.Add("Content-Type", "application/query+json"); - client.DefaultRequestHeaders.Add("Accept", "application/json"); + request.Headers.Add("x-ms-documentdb-isquery", "true"); + request.Headers.Add("x-ms-documentdb-query-enablecrosspartition", "true"); + request.Headers.Add("x-ms-version", "2018-12-31"); + request.Headers.Add("x-ms-date", date); + request.Headers.Add("authorization", authHeaderValue); + //request.Headers.Add("Content-Type", "application/query+json"); + request.Headers.Add("Accept", "application/json"); - return HttpClient; + return base.SendAsync(request, ct); + } } } -} \ No newline at end of file +} diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index 686d08c5c..bb633c395 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -1,6 +1,7 @@ -namespace DotNet.Testcontainers.Tests.Fixtures +namespace DotNet.Testcontainers.Tests.Fixtures { - using System.Data.Common; + using System; + using System.Data.Common; using System.Threading.Tasks; using DotNet.Testcontainers.Builders; using DotNet.Testcontainers.Configurations; @@ -9,18 +10,21 @@ namespace DotNet.Testcontainers.Tests.Fixtures public sealed class CosmosDbFixture : DatabaseFixture { - private readonly TestcontainerDatabaseConfiguration configuration = - new CosmosDbTestcontainerConfiguration{ Database = "testdb" }; + private readonly TestcontainerDatabaseConfiguration configuration = new CosmosDbTestcontainerConfiguration + { + Database = "testdb" + }; public CosmosDbFixture() { this.Container = new TestcontainersBuilder() - .WithDatabase(this.configuration) + .WithDatabase(this.configuration) .Build(); } public override async Task InitializeAsync() { + Console.WriteLine("Initializing CosmosDB container"); await this.Container.StartAsync() .ConfigureAwait(false); @@ -35,10 +39,14 @@ await this.Container.StartAsync() public override async Task DisposeAsync() { + if (Connection != null && Connection.State != System.Data.ConnectionState.Closed) + { this.Connection.Dispose(); - await this.Container.DisposeAsync() - .ConfigureAwait(false); + } + + await this.Container.DisposeAsync() + .ConfigureAwait(false); } public override void Dispose() @@ -46,4 +54,4 @@ public override void Dispose() this.configuration.Dispose(); } } -} \ No newline at end of file +} diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index d2ab8d7f1..7bec469e7 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -10,16 +10,16 @@ public class CosmosDbTestcontainerTest : IClassFixture public CosmosDbTestcontainerTest(CosmosDbFixture cosmosDbFixture) { - this.cosmosDbFixture = cosmosDbFixture; + this.cosmosDbFixture = cosmosDbFixture; } [Fact] - public async Task DatabaseCreated() + public async Task DatabaseCreated() { var dbResponse = await this.cosmosDbFixture.Container.CreateDatabaseAsync() .ConfigureAwait(false); - Assert.Equal(dbResponse.StatusCode, System.Net.HttpStatusCode.Created); + Assert.Equal(System.Net.HttpStatusCode.Created, dbResponse.StatusCode); } } -} \ No newline at end of file +} From dad2dc922fa0ee42761dd16192ec3d2cd368af4d Mon Sep 17 00:00:00 2001 From: Jesse Wellenberg <48557715+Yeseh@users.noreply.github.com> Date: Sun, 28 Aug 2022 16:35:09 +0200 Subject: [PATCH 06/38] Restructure to model Azurite testcontainer --- Packages.props | 1 + .../TestcontainersBuilderCosmosDbExtension.cs | 21 ++++ .../CosmosDbTestcontainerConfiguration.cs | 74 ++++++++---- .../Databases/CosmosDbTestcontainer.cs | 108 +++--------------- .../Unix/Modules/Databases/CosmosDbFixture.cs | 93 +++++++-------- .../Testcontainers.Tests.csproj | 1 + .../Databases/CosmosDbTestcontainerTest.cs | 61 +++++++--- 7 files changed, 185 insertions(+), 174 deletions(-) create mode 100644 src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs diff --git a/Packages.props b/Packages.props index 3630ba010..27b841964 100644 --- a/Packages.props +++ b/Packages.props @@ -27,6 +27,7 @@ + diff --git a/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs b/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs new file mode 100644 index 000000000..c43cf7f2e --- /dev/null +++ b/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs @@ -0,0 +1,21 @@ +namespace DotNet.Testcontainers.Builders +{ + using DotNet.Testcontainers.Configurations; + using DotNet.Testcontainers.Containers; + using JetBrains.Annotations; + + [PublicAPI] + public static class TestcontainersBuilderCosmosDbExtension + { + public static ITestcontainersBuilder WithCosmosDb( + this ITestcontainersBuilder builder, CosmosDbTestcontainerConfiguration configuration) + { + builder.WithImage(configuration.Image) + .WithWaitStrategy(configuration.WaitStrategy) + .WithExposedPort(configuration.SqlApiContainerPort) + .WithPortBinding(configuration.SqlApiPort); + + return builder; + } + } +} diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs index 602dbaa85..262b2aca6 100644 --- a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -1,39 +1,63 @@ namespace DotNet.Testcontainers.Configurations { + using System; using DotNet.Testcontainers.Builders; using JetBrains.Annotations; [PublicAPI] public class CosmosDbTestcontainerConfiguration : TestcontainerDatabaseConfiguration { - private const string CosmosDbImage = + // TODO: WithMongoAPI extension? + public const string DefaultCosmosDbSqlApiImage = "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator"; - private const int CosmosDbPort = 8081; + public const string DefaultCosmosDbMongoDbApiImage = + "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:mongo"; - private const string CosmosDbDefaultKey = - "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="; - - private const string CosmosDbDefaultAccountName = - "localhost:8081"; + private const int DefaultSqlApiPort = 8081; + + private const int DefaultMongoDbApiPort = 10250; public CosmosDbTestcontainerConfiguration() - : this(CosmosDbImage) { } + : this(DefaultCosmosDbSqlApiImage) + { + } - public CosmosDbTestcontainerConfiguration(string image) - : base(image, CosmosDbPort, CosmosDbPort) + public CosmosDbTestcontainerConfiguration(string image) + : base(image, DefaultSqlApiPort) { - this.Environments.Add("AZURE_COSMOS_EMULATOR_PARTITION_COUNT", "1"); + this.Environments.Add("AZURE_COSMOS_EMULATOR_MONGO_DB_ENDPOINT", ""); + this.Environments.Add("AZURE_COSMOS_EMULATOR_PARTITION_COUNT", "1"); } - public override string Username + public int MongoDbApiPort { get; set; } + + public int MongoDbApiContainerPort { get; set; } + + public int SqlApiPort { get; set; } + + public int SqlApiContainerPort { get; set; } + + public override IWaitForContainerOS WaitStrategy { - get => CosmosDbDefaultAccountName; + get + { + var waitStrategy = Wait.ForUnixContainer(); + // waitStrategy = string.IsNullOrWhiteSpace(this.MongoDbEndpoint) + // ? waitStrategy.UntilPortIsAvailable(SqlApiContainerPort) + // : waitStrategy.UntilPortIsAvailable(MongoDbApiContainerPort); + waitStrategy = waitStrategy.UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started"); + + return waitStrategy; + } } public override string Password { - get => CosmosDbDefaultKey; + // Default key for the emulator + // See: https://docs.microsoft.com/en-us/azure/cosmos-db/local-emulator?tabs=ssl-netstd21#authenticate-requests + get => "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="; + set => throw new NotImplementedException(); } public override string Database @@ -42,26 +66,28 @@ public override string Database set => this.Environments["AZURE_COSMOS_EMULATOR_DATABASE"] = value; } - public string PartitionCount + public int PartitionCount { - get => this.Environments["AZURE_COSMOS_EMULATOR_PARTITION_COUNT"]; - set => this.Environments["AZURE_COSMOS_EMULATOR_PARTITION_COUNT"] = value; + get => int.Parse(this.Environments["AZURE_COSMOS_EMULATOR_PARTITION_COUNT"]); + set => this.Environments["AZURE_COSMOS_EMULATOR_PARTITION_COUNT"] = value.ToString(); } - public string EnableDataPersistence + public bool EnableDataPersistence { - get => this.Environments["AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE"]; - set => this.Environments["AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE"] = value; + get => this.Environments["AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE"] == "true"; + set => this.Environments["AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE"] = value.ToString().ToLower(); } public string IPAddressOverride { get => this.Environments["AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE"]; set => this.Environments["AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE"] = value; - } + } - public override IWaitForContainerOS WaitStrategy => Wait.ForUnixContainer() - .UntilCommandIsCompleted("ls"); - //.UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started"); + public string MongoDbEndpoint + { + get => this.Environments["AZURE_COSMOS_EMULATOR_MONGO_DB_ENDPOINT"]; + set => this.Environments["AZURE_COSMOS_EMULATOR_MONGO_DB_ENDPOINT"] = value; + } } } diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index 8d928148e..b1c3c5fb7 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -1,110 +1,36 @@ namespace DotNet.Testcontainers.Containers { - using System.Collections.Generic; using System.Net.Http; - using System.Threading.Tasks; using DotNet.Testcontainers.Configurations; using Microsoft.Extensions.Logging; - using System.Text.Json; - using System; - using System.Threading; - using System.Text; + using JetBrains.Annotations; public sealed class CosmosDbTestcontainer : TestcontainerDatabase { - private string CosmosUrl; + [PublicAPI] + public int SqlApiPort + => this.GetMappedPublicPort(this.ContainerSqlApiPort); - private HttpClient HttpClient; - - internal CosmosDbTestcontainer(ITestcontainersConfiguration configuration, ILogger logger) - : base(configuration, logger) - { - CosmosUrl = $"https://{this.Username}.documents.azure.com/dbs"; - } + [PublicAPI] + public int MongoApiPort + => this.GetMappedPublicPort(this.ContainerMongoApiPort); - public override string ConnectionString - => $"AccountEndpoint=https://{this.Username}:{this.Port}.documents.azure.com:443/;AccountKey={this.Password}"; + [PublicAPI] + public int ContainerSqlApiPort { get; set; } - public async Task QueryAsync( - string queryString, IEnumerable> parameters = default) - { - Console.WriteLine("Executing query..."); - var client = GetHttpClient(); - var parJsonStr =JsonSerializer.Serialize(parameters); - var body = new { Query = queryString, Parameters = parJsonStr }; - var reqBodyStr = JsonSerializer.Serialize(body); - var content = new StringContent(reqBodyStr); - - var response = await client.PostAsync(CosmosUrl, content); + [PublicAPI] + public int ContainerMongoApiPort { get; set; } - return response; - } - // TODO: Call this implicitly on initialize - public async Task CreateDatabaseAsync() - { - Console.WriteLine("Attempting to create database..."); - var url = $"https://localhost:8081/dbs"; - var client = GetHttpClient(); - var jsonData = JsonSerializer.Serialize(new { id = string.IsNullOrEmpty(this.Database) ? "testdb" : this.Database }); - var contentData = new StringContent(jsonData, Encoding.UTF8, "application/json"); - var response = await client.PostAsync(url, contentData).ConfigureAwait(false); + public string AccountEndpoint { get; } - return response; - } + private HttpClient HttpClient; - private HttpClient GetHttpClient() + internal CosmosDbTestcontainer(ITestcontainersConfiguration configuration, ILogger logger) + : base(configuration, logger) { - if (HttpClient != null) return HttpClient; - - var handler = new CosmosDbHttpHandler(this.Password); - var client = new HttpClient(handler); - - HttpClient = client; - return HttpClient; } - private sealed class CosmosDbHttpHandler : HttpClientHandler - { - private readonly string _password; - - public CosmosDbHttpHandler(string password) - { - this._password = password; - // Skip SSL certificate validation - // https://docs.microsoft.com/en-us/azure/cosmos-db/local-emulator?tabs=ssl-netstd21#disable-ssl-validation - this.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; - } - - // https://stackoverflow.com/questions/52262767/cosmos-db-rest-api-create-user-permissio - protected override Task SendAsync( - HttpRequestMessage request, CancellationToken ct) - { - var hmac = new System.Security.Cryptography.HMACSHA256() - { - Key = Convert.FromBase64String(this._password) - }; - - var date = DateTime.UtcNow.ToString("r"); - var payload = "POST".ToLowerInvariant() + "\n" + - "dbs".ToLowerInvariant() + "\n" + - "" + "\n" + - date.ToLowerInvariant() + "\n" + - "" + "\n"; - - var hashPayload = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload)); - var signature = Convert.ToBase64String(hashPayload); - var authHeaderValue = System.Web.HttpUtility.UrlEncode($"type=master&ver=1.0&sig={signature}"); - - request.Headers.Add("x-ms-documentdb-isquery", "true"); - request.Headers.Add("x-ms-documentdb-query-enablecrosspartition", "true"); - request.Headers.Add("x-ms-version", "2018-12-31"); - request.Headers.Add("x-ms-date", date); - request.Headers.Add("authorization", authHeaderValue); - //request.Headers.Add("Content-Type", "application/query+json"); - request.Headers.Add("Accept", "application/json"); - - return base.SendAsync(request, ct); - } - } + public override string ConnectionString => + $"AccountEndpoint=https://{this.Hostname}:{this.SqlApiPort};AccountKey={this.Password}"; } } diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index bb633c395..e1fa2b7a3 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -1,57 +1,60 @@ namespace DotNet.Testcontainers.Tests.Fixtures { - using System; - using System.Data.Common; - using System.Threading.Tasks; + using System; + using System.Data.Common; + using System.IO; + using System.Threading.Tasks; using DotNet.Testcontainers.Builders; using DotNet.Testcontainers.Configurations; using DotNet.Testcontainers.Containers; + using JetBrains.Annotations; using Npgsql; - public sealed class CosmosDbFixture : DatabaseFixture + public static class CosmosDbFixture { - private readonly TestcontainerDatabaseConfiguration configuration = new CosmosDbTestcontainerConfiguration + [UsedImplicitly] + public class CosmosDbDefaultFixture : DatabaseFixture { - Database = "testdb" - }; - - public CosmosDbFixture() - { - this.Container = new TestcontainersBuilder() - .WithDatabase(this.configuration) - .Build(); - } - - public override async Task InitializeAsync() - { - Console.WriteLine("Initializing CosmosDB container"); - await this.Container.StartAsync() - .ConfigureAwait(false); - - // var dbResponse = await this.Container.CreateDatabaseAsync() - // .ConfigureAwait(false); - - // if (dbResponse.StatusCode != System.Net.HttpStatusCode.Created) - // { - // throw new System.Exception("Failed to create database"); - // } - } - - public override async Task DisposeAsync() - { - if (Connection != null && Connection.State != System.Data.ConnectionState.Closed) - { - this.Connection.Dispose(); - - } - - await this.Container.DisposeAsync() - .ConfigureAwait(false); - } - - public override void Dispose() - { - this.configuration.Dispose(); + public CosmosDbTestcontainerConfiguration Configuration { get; set; } + + public CosmosDbDefaultFixture() + : this(new CosmosDbTestcontainerConfiguration()) + { + } + + protected CosmosDbDefaultFixture(CosmosDbTestcontainerConfiguration configuration) + { + this.Configuration = configuration; + this.Container = new TestcontainersBuilder() + .WithHostname("localhost") + .WithImage(configuration.Image) + .WithPortBinding(configuration.DefaultPort) + .WithExposedPort(configuration.DefaultPort) + .WithWaitStrategy(configuration.WaitStrategy) + .WithEnvironment("AZURE_COSMOS_EMULATOR_PARTITION_COUNT", "1") + .Build(); + } + + public override Task InitializeAsync() + { + return this.Container.StartAsync(); + } + + public override async Task DisposeAsync() + { + if (Connection != null && Connection.State != System.Data.ConnectionState.Closed) + { + this.Connection.Dispose(); + } + + await this.Container.DisposeAsync() + .ConfigureAwait(false); + } + + public override void Dispose() + { + this.Configuration.Dispose(); + } } } } diff --git a/tests/Testcontainers.Tests/Testcontainers.Tests.csproj b/tests/Testcontainers.Tests/Testcontainers.Tests.csproj index 7b404d797..99b766802 100644 --- a/tests/Testcontainers.Tests/Testcontainers.Tests.csproj +++ b/tests/Testcontainers.Tests/Testcontainers.Tests.csproj @@ -24,6 +24,7 @@ + diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index 7bec469e7..168760c53 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -1,25 +1,58 @@ namespace DotNet.Testcontainers.Tests.Unit { + using Microsoft.Azure.Cosmos; using DotNet.Testcontainers.Tests.Fixtures; using System.Threading.Tasks; using Xunit; + using System.Net.Http; + using System.Data.Common; + using DotNet.Testcontainers.Containers; - public class CosmosDbTestcontainerTest : IClassFixture - { - private readonly CosmosDbFixture cosmosDbFixture; + public static class CosmosDbTestcontainerTest + { + [Collection(nameof(Testcontainers))] + public sealed class SqlApi : IClassFixture + { + private static readonly CosmosClientOptions skipSslValidationOptions = new CosmosClientOptions() + { + HttpClientFactory = () => + { + HttpMessageHandler httpMessageHandler = new HttpClientHandler() + { + ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator + }; - public CosmosDbTestcontainerTest(CosmosDbFixture cosmosDbFixture) - { - this.cosmosDbFixture = cosmosDbFixture; - } + return new HttpClient(httpMessageHandler); + }, - [Fact] - public async Task DatabaseCreated() - { - var dbResponse = await this.cosmosDbFixture.Container.CreateDatabaseAsync() - .ConfigureAwait(false); + ConnectionMode = ConnectionMode.Gateway + }; - Assert.Equal(System.Net.HttpStatusCode.Created, dbResponse.StatusCode); - } + private readonly CosmosDbFixture.CosmosDbDefaultFixture commonContainerPorts; + + private CosmosDbTestcontainer Container; + + public SqlApi(CosmosDbFixture.CosmosDbDefaultFixture commonContainerPorts) + { + this.commonContainerPorts = commonContainerPorts; + } + + [Fact] + public async Task ShouldEstablishConnection() + { + var exception = await Record.ExceptionAsync(() => Task.WhenAll(EstablishConnection(commonContainerPorts))); + Assert.Null(exception); + } + + private static async Task EstablishConnection(CosmosDbFixture.CosmosDbDefaultFixture cosmosDb) + { + var client = new CosmosClient(cosmosDb.Container.ConnectionString, skipSslValidationOptions); + + var properties = await client.ReadAccountAsync() + .ConfigureAwait(false); + + Assert.Equal(cosmosDb.Configuration.SqlApiPort, cosmosDb.Container.SqlApiPort); + } } + } } From 0f429baba577d3a1143608402ee8c32cfc24147a Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Tue, 6 Sep 2022 20:09:14 +0200 Subject: [PATCH 07/38] fix tests + cleanup --- .../TestcontainersBuilderCosmosDbExtension.cs | 2 +- .../CosmosDbTestcontainerConfiguration.cs | 29 ++--- .../Databases/CosmosDbTestcontainer.cs | 4 +- .../Unix/Modules/Databases/CosmosDbFixture.cs | 105 +++++++++--------- .../Databases/CosmosDbTestcontainerTest.cs | 9 +- 5 files changed, 76 insertions(+), 73 deletions(-) diff --git a/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs b/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs index c43cf7f2e..5893b1a36 100644 --- a/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs +++ b/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs @@ -15,7 +15,7 @@ public static ITestcontainersBuilder WithCosmosDb( .WithExposedPort(configuration.SqlApiContainerPort) .WithPortBinding(configuration.SqlApiPort); - return builder; + return builder; } } } diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs index 262b2aca6..ea1f6aca6 100644 --- a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -1,6 +1,7 @@ namespace DotNet.Testcontainers.Configurations { using System; + using System.IO; using DotNet.Testcontainers.Builders; using JetBrains.Annotations; @@ -8,44 +9,44 @@ namespace DotNet.Testcontainers.Configurations public class CosmosDbTestcontainerConfiguration : TestcontainerDatabaseConfiguration { // TODO: WithMongoAPI extension? - public const string DefaultCosmosDbSqlApiImage = + public const string DefaultCosmosDbSqlApiImage = "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator"; - public const string DefaultCosmosDbMongoDbApiImage = + public const string DefaultCosmosDbMongoDbApiImage = "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:mongo"; private const int DefaultSqlApiPort = 8081; - + private const int DefaultMongoDbApiPort = 10250; public CosmosDbTestcontainerConfiguration() - : this(DefaultCosmosDbSqlApiImage) + : this(DefaultCosmosDbSqlApiImage) { + this.OutputConsumer = Consume.RedirectStdoutAndStderrToStream(new MemoryStream(), new MemoryStream()); } - public CosmosDbTestcontainerConfiguration(string image) - : base(image, DefaultSqlApiPort) + public CosmosDbTestcontainerConfiguration(string image) + : base(image, DefaultSqlApiPort, DefaultSqlApiPort) { this.Environments.Add("AZURE_COSMOS_EMULATOR_MONGO_DB_ENDPOINT", ""); this.Environments.Add("AZURE_COSMOS_EMULATOR_PARTITION_COUNT", "1"); } + public override IOutputConsumer OutputConsumer { get; } + public int MongoDbApiPort { get; set; } public int MongoDbApiContainerPort { get; set; } - public int SqlApiPort { get; set; } + public int SqlApiPort { get; set; } = DefaultSqlApiPort; - public int SqlApiContainerPort { get; set; } + public int SqlApiContainerPort { get; set; } = DefaultSqlApiPort; - public override IWaitForContainerOS WaitStrategy + public override IWaitForContainerOS WaitStrategy { get { var waitStrategy = Wait.ForUnixContainer(); - // waitStrategy = string.IsNullOrWhiteSpace(this.MongoDbEndpoint) - // ? waitStrategy.UntilPortIsAvailable(SqlApiContainerPort) - // : waitStrategy.UntilPortIsAvailable(MongoDbApiContainerPort); waitStrategy = waitStrategy.UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started"); return waitStrategy; @@ -82,12 +83,12 @@ public string IPAddressOverride { get => this.Environments["AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE"]; set => this.Environments["AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE"] = value; - } + } public string MongoDbEndpoint { get => this.Environments["AZURE_COSMOS_EMULATOR_MONGO_DB_ENDPOINT"]; set => this.Environments["AZURE_COSMOS_EMULATOR_MONGO_DB_ENDPOINT"] = value; - } + } } } diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index b1c3c5fb7..09eb03225 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -2,8 +2,8 @@ namespace DotNet.Testcontainers.Containers { using System.Net.Http; using DotNet.Testcontainers.Configurations; - using Microsoft.Extensions.Logging; using JetBrains.Annotations; + using Microsoft.Extensions.Logging; public sealed class CosmosDbTestcontainer : TestcontainerDatabase { @@ -30,7 +30,7 @@ internal CosmosDbTestcontainer(ITestcontainersConfiguration configuration, ILogg { } - public override string ConnectionString => + public override string ConnectionString => $"AccountEndpoint=https://{this.Hostname}:{this.SqlApiPort};AccountKey={this.Password}"; } } diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index e1fa2b7a3..b4229d8df 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -1,60 +1,63 @@ namespace DotNet.Testcontainers.Tests.Fixtures { - using System; - using System.Data.Common; - using System.IO; + using System.Data.Common; using System.Threading.Tasks; - using DotNet.Testcontainers.Builders; - using DotNet.Testcontainers.Configurations; - using DotNet.Testcontainers.Containers; - using JetBrains.Annotations; - using Npgsql; + using DotNet.Testcontainers.Builders; + using DotNet.Testcontainers.Configurations; + using DotNet.Testcontainers.Containers; + using JetBrains.Annotations; - public static class CosmosDbFixture + public static class CosmosDbFixture + { + [UsedImplicitly] + public class CosmosDbDefaultFixture : DatabaseFixture { - [UsedImplicitly] - public class CosmosDbDefaultFixture : DatabaseFixture + public CosmosDbDefaultFixture() + : this(new CosmosDbTestcontainerConfiguration()) + { + } + + protected CosmosDbDefaultFixture(CosmosDbTestcontainerConfiguration configuration) + { + this.Configuration = configuration; + this.Container = new TestcontainersBuilder() + .WithImage(configuration.Image) + .WithPortBinding(configuration.DefaultPort) + .WithExposedPort(configuration.DefaultPort) + .WithWaitStrategy(configuration.WaitStrategy) + .WithOutputConsumer(configuration.OutputConsumer) + .WithEnvironment("AZURE_COSMOS_EMULATOR_PARTITION_COUNT", "1") + .ConfigureContainer(testcontainer => + { + testcontainer.ContainerSqlApiPort = configuration.DefaultPort; + testcontainer.Password = configuration.Password; + }) + .Build(); + } + + public CosmosDbTestcontainerConfiguration Configuration { get; set; } + + + public override Task InitializeAsync() + { + return this.Container.StartAsync(); + } + + public override async Task DisposeAsync() + { + if (Connection != null && Connection.State != System.Data.ConnectionState.Closed) { - public CosmosDbTestcontainerConfiguration Configuration { get; set; } - - public CosmosDbDefaultFixture() - : this(new CosmosDbTestcontainerConfiguration()) - { - } - - protected CosmosDbDefaultFixture(CosmosDbTestcontainerConfiguration configuration) - { - this.Configuration = configuration; - this.Container = new TestcontainersBuilder() - .WithHostname("localhost") - .WithImage(configuration.Image) - .WithPortBinding(configuration.DefaultPort) - .WithExposedPort(configuration.DefaultPort) - .WithWaitStrategy(configuration.WaitStrategy) - .WithEnvironment("AZURE_COSMOS_EMULATOR_PARTITION_COUNT", "1") - .Build(); - } - - public override Task InitializeAsync() - { - return this.Container.StartAsync(); - } - - public override async Task DisposeAsync() - { - if (Connection != null && Connection.State != System.Data.ConnectionState.Closed) - { - this.Connection.Dispose(); - } - - await this.Container.DisposeAsync() - .ConfigureAwait(false); - } - - public override void Dispose() - { - this.Configuration.Dispose(); - } + this.Connection.Dispose(); } + + await this.Container.DisposeAsync() + .ConfigureAwait(false); + } + + public override void Dispose() + { + this.Configuration.Dispose(); + } } + } } diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index 168760c53..1f9ba0c8c 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -1,12 +1,11 @@ namespace DotNet.Testcontainers.Tests.Unit { - using Microsoft.Azure.Cosmos; - using DotNet.Testcontainers.Tests.Fixtures; - using System.Threading.Tasks; - using Xunit; using System.Net.Http; - using System.Data.Common; + using System.Threading.Tasks; using DotNet.Testcontainers.Containers; + using DotNet.Testcontainers.Tests.Fixtures; + using Microsoft.Azure.Cosmos; + using Xunit; public static class CosmosDbTestcontainerTest { From b1dff3f5c267c93bb7ed2cf8806eb292a5145797 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Thu, 8 Sep 2022 07:37:55 +0200 Subject: [PATCH 08/38] (temp hack) wait for max 5 min --- .../Containers/Unix/Modules/Databases/CosmosDbFixture.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index b4229d8df..bffd3ce0e 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -1,5 +1,6 @@ namespace DotNet.Testcontainers.Tests.Fixtures { + using System.Collections.Generic; using System.Data.Common; using System.Threading.Tasks; using DotNet.Testcontainers.Builders; @@ -40,7 +41,8 @@ protected CosmosDbDefaultFixture(CosmosDbTestcontainerConfiguration configuratio public override Task InitializeAsync() { - return this.Container.StartAsync(); + // wait for 5 min + return Task.WhenAny(this.Container.StartAsync(), Task.Delay(5 * 60 * 1000)); } public override async Task DisposeAsync() From 4c45cd0a6ca603c4dd1a2734be377fdee5e01743 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Thu, 8 Sep 2022 12:53:54 +0200 Subject: [PATCH 09/38] add debug logging --- .../Configurations/WaitStrategies/UntilMessageIsLogged.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs b/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs index 6a95fdccb..6f18b9f18 100644 --- a/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs +++ b/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs @@ -22,11 +22,13 @@ public UntilMessageIsLogged(Stream stream, string message) public async Task Until(ITestcontainersContainer testcontainers, ILogger logger) { this.stream.Seek(0, SeekOrigin.Begin); - + logger.LogWarning("Start read"); using (var streamReader = new StreamReader(this.stream, Encoding.UTF8, false, 4096, true)) { + logger.LogWarning("Read to end"); var output = await streamReader.ReadToEndAsync() .ConfigureAwait(false); + logger.LogWarning($"got: {output}"); return Regex.IsMatch(output, this.message); } From 5a66c99e20065f0ec1901fb4dfb87de3219def56 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Thu, 8 Sep 2022 14:31:19 +0200 Subject: [PATCH 10/38] cleanup debug code --- .../WaitStrategies/UntilMessageIsLogged.cs | 9 ++++----- .../Unix/Modules/Databases/CosmosDbTestcontainerTest.cs | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs b/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs index 6f18b9f18..5f977be68 100644 --- a/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs +++ b/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs @@ -22,15 +22,14 @@ public UntilMessageIsLogged(Stream stream, string message) public async Task Until(ITestcontainersContainer testcontainers, ILogger logger) { this.stream.Seek(0, SeekOrigin.Begin); - logger.LogWarning("Start read"); using (var streamReader = new StreamReader(this.stream, Encoding.UTF8, false, 4096, true)) { - logger.LogWarning("Read to end"); var output = await streamReader.ReadToEndAsync() .ConfigureAwait(false); - logger.LogWarning($"got: {output}"); - - return Regex.IsMatch(output, this.message); + var isMatch = Regex.IsMatch(output, this.message); + // TODO temporary logging + logger?.LogInformation("Wating for message, data read: {Data}, is match {Match}", output, isMatch); + return isMatch; } } } diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index 1f9ba0c8c..b6580cd96 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -39,7 +39,7 @@ public SqlApi(CosmosDbFixture.CosmosDbDefaultFixture commonContainerPorts) [Fact] public async Task ShouldEstablishConnection() { - var exception = await Record.ExceptionAsync(() => Task.WhenAll(EstablishConnection(commonContainerPorts))); + var exception = await Record.ExceptionAsync(() => EstablishConnection(this.commonContainerPorts)); Assert.Null(exception); } From a21b5e472590d8affea2a78a263956618266c5c0 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Thu, 8 Sep 2022 18:54:02 +0200 Subject: [PATCH 11/38] set timeout on build --- .github/workflows/cicd.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 78c159959..7fabee93a 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -2,9 +2,9 @@ name: Continuous Integration & Delivery on: push: - branches: [ develop, master, bugfix/*, feature/* ] + branches: [develop, master, bugfix/*, feature/*] pull_request: - branches: [ develop, master ] + branches: [develop, master] workflow_dispatch: inputs: publish_nuget_package: @@ -26,6 +26,7 @@ jobs: os: [ubuntu-20.04, windows-2019] runs-on: ${{ matrix.os }} + timeout-minutes: 15 steps: - name: Checkout Repository From 56dbe8f9ac7388b8a79e88002b5d72888e77304f Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Thu, 8 Sep 2022 20:19:58 +0200 Subject: [PATCH 12/38] first cleanup sweep --- .../TestcontainersBuilderCosmosDbExtension.cs | 17 ++- .../CosmosDbTestcontainerConfiguration.cs | 141 ++++++++---------- .../Databases/CosmosDbTestcontainer.cs | 22 +-- .../Unix/Modules/Databases/CosmosDbFixture.cs | 71 ++++----- .../Databases/CosmosDbTestcontainerTest.cs | 21 +-- 5 files changed, 108 insertions(+), 164 deletions(-) diff --git a/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs b/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs index 5893b1a36..07a5211f8 100644 --- a/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs +++ b/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs @@ -10,12 +10,17 @@ public static class TestcontainersBuilderCosmosDbExtension public static ITestcontainersBuilder WithCosmosDb( this ITestcontainersBuilder builder, CosmosDbTestcontainerConfiguration configuration) { - builder.WithImage(configuration.Image) - .WithWaitStrategy(configuration.WaitStrategy) - .WithExposedPort(configuration.SqlApiContainerPort) - .WithPortBinding(configuration.SqlApiPort); - - return builder; + return builder.WithImage(configuration.Image) + .WithPortBinding(configuration.DefaultPort, true) + .WithExposedPort(configuration.DefaultPort) + .WithWaitStrategy(configuration.WaitStrategy) + .WithOutputConsumer(configuration.OutputConsumer) + .WithEnvironment("AZURE_COSMOS_EMULATOR_PARTITION_COUNT", "1") + .ConfigureContainer(testcontainer => + { + testcontainer.ContainerPort = configuration.DefaultPort; + testcontainer.Password = configuration.Password; + }); } } } diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs index ea1f6aca6..5e036646e 100644 --- a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -1,94 +1,75 @@ namespace DotNet.Testcontainers.Configurations { - using System; - using System.IO; - using DotNet.Testcontainers.Builders; - using JetBrains.Annotations; - - [PublicAPI] - public class CosmosDbTestcontainerConfiguration : TestcontainerDatabaseConfiguration + using System; + using System.Globalization; + using System.IO; + using DotNet.Testcontainers.Builders; + using JetBrains.Annotations; + + [PublicAPI] + public class CosmosDbTestcontainerConfiguration : TestcontainerDatabaseConfiguration + { + public const string DefaultCosmosDbApiImage = + "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator"; + + private const int DefaultCosmosPort = 8081; + + public CosmosDbTestcontainerConfiguration() + : this(DefaultCosmosDbApiImage) { - // TODO: WithMongoAPI extension? - public const string DefaultCosmosDbSqlApiImage = - "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator"; - - public const string DefaultCosmosDbMongoDbApiImage = - "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:mongo"; - - private const int DefaultSqlApiPort = 8081; - - private const int DefaultMongoDbApiPort = 10250; - - public CosmosDbTestcontainerConfiguration() - : this(DefaultCosmosDbSqlApiImage) - { - this.OutputConsumer = Consume.RedirectStdoutAndStderrToStream(new MemoryStream(), new MemoryStream()); - } - - public CosmosDbTestcontainerConfiguration(string image) - : base(image, DefaultSqlApiPort, DefaultSqlApiPort) - { - this.Environments.Add("AZURE_COSMOS_EMULATOR_MONGO_DB_ENDPOINT", ""); - this.Environments.Add("AZURE_COSMOS_EMULATOR_PARTITION_COUNT", "1"); - } - - public override IOutputConsumer OutputConsumer { get; } - - public int MongoDbApiPort { get; set; } - - public int MongoDbApiContainerPort { get; set; } - - public int SqlApiPort { get; set; } = DefaultSqlApiPort; + this.OutputConsumer = Consume.RedirectStdoutAndStderrToStream(new MemoryStream(), new MemoryStream()); + } - public int SqlApiContainerPort { get; set; } = DefaultSqlApiPort; + public CosmosDbTestcontainerConfiguration(string image) + : base(image, DefaultCosmosPort) + { + this.Environments.Add("AZURE_COSMOS_EMULATOR_MONGO_DB_ENDPOINT", string.Empty); + this.Environments.Add("AZURE_COSMOS_EMULATOR_PARTITION_COUNT", "1"); + } - public override IWaitForContainerOS WaitStrategy - { - get - { - var waitStrategy = Wait.ForUnixContainer(); - waitStrategy = waitStrategy.UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started"); + public override IOutputConsumer OutputConsumer { get; } - return waitStrategy; - } - } + public override IWaitForContainerOS WaitStrategy + { + get + { + var waitStrategy = Wait.ForUnixContainer(); + waitStrategy = waitStrategy.UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started"); - public override string Password - { - // Default key for the emulator - // See: https://docs.microsoft.com/en-us/azure/cosmos-db/local-emulator?tabs=ssl-netstd21#authenticate-requests - get => "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="; - set => throw new NotImplementedException(); - } + return waitStrategy; + } + } - public override string Database - { - get => this.Environments["AZURE_COSMOS_EMULATOR_DATABASE"]; - set => this.Environments["AZURE_COSMOS_EMULATOR_DATABASE"] = value; - } + public override string Password + { + // Default key for the emulator + // See: https://docs.microsoft.com/en-us/azure/cosmos-db/local-emulator?tabs=ssl-netstd21#authenticate-requests + get => "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="; + set => throw new NotImplementedException(); + } - public int PartitionCount - { - get => int.Parse(this.Environments["AZURE_COSMOS_EMULATOR_PARTITION_COUNT"]); - set => this.Environments["AZURE_COSMOS_EMULATOR_PARTITION_COUNT"] = value.ToString(); - } + public override string Database + { + get => this.Environments["AZURE_COSMOS_EMULATOR_DATABASE"]; + set => this.Environments["AZURE_COSMOS_EMULATOR_DATABASE"] = value; + } - public bool EnableDataPersistence - { - get => this.Environments["AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE"] == "true"; - set => this.Environments["AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE"] = value.ToString().ToLower(); - } + public int PartitionCount + { + get => int.Parse(this.Environments["AZURE_COSMOS_EMULATOR_PARTITION_COUNT"], CultureInfo.InvariantCulture); + set => this.Environments["AZURE_COSMOS_EMULATOR_PARTITION_COUNT"] = value.ToString(CultureInfo.InvariantCulture); + } - public string IPAddressOverride - { - get => this.Environments["AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE"]; - set => this.Environments["AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE"] = value; - } + public bool EnableDataPersistence + { + get => this.Environments["AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE"] == "true"; + set => this.Environments["AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE"] = value.ToString().ToLower(CultureInfo.InvariantCulture); + } - public string MongoDbEndpoint - { - get => this.Environments["AZURE_COSMOS_EMULATOR_MONGO_DB_ENDPOINT"]; - set => this.Environments["AZURE_COSMOS_EMULATOR_MONGO_DB_ENDPOINT"] = value; - } + public string IpAddressOverride + { + get => this.Environments["AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE"]; + set => this.Environments["AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE"] = value; } + } } diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index 09eb03225..04b501d07 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -1,36 +1,16 @@ namespace DotNet.Testcontainers.Containers { - using System.Net.Http; using DotNet.Testcontainers.Configurations; - using JetBrains.Annotations; using Microsoft.Extensions.Logging; public sealed class CosmosDbTestcontainer : TestcontainerDatabase { - [PublicAPI] - public int SqlApiPort - => this.GetMappedPublicPort(this.ContainerSqlApiPort); - - [PublicAPI] - public int MongoApiPort - => this.GetMappedPublicPort(this.ContainerMongoApiPort); - - [PublicAPI] - public int ContainerSqlApiPort { get; set; } - - [PublicAPI] - public int ContainerMongoApiPort { get; set; } - - public string AccountEndpoint { get; } - - private HttpClient HttpClient; - internal CosmosDbTestcontainer(ITestcontainersConfiguration configuration, ILogger logger) : base(configuration, logger) { } public override string ConnectionString => - $"AccountEndpoint=https://{this.Hostname}:{this.SqlApiPort};AccountKey={this.Password}"; + $"AccountEndpoint=https://{this.Hostname}:{this.Port};AccountKey={this.Password}"; } } diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index bffd3ce0e..a041a8f45 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -1,65 +1,48 @@ namespace DotNet.Testcontainers.Tests.Fixtures { - using System.Collections.Generic; using System.Data.Common; using System.Threading.Tasks; using DotNet.Testcontainers.Builders; using DotNet.Testcontainers.Configurations; using DotNet.Testcontainers.Containers; - using JetBrains.Annotations; - public static class CosmosDbFixture + public class CosmosDbFixture : DatabaseFixture { - [UsedImplicitly] - public class CosmosDbDefaultFixture : DatabaseFixture + public CosmosDbFixture() + : this(new CosmosDbTestcontainerConfiguration()) { - public CosmosDbDefaultFixture() - : this(new CosmosDbTestcontainerConfiguration()) - { - } + } - protected CosmosDbDefaultFixture(CosmosDbTestcontainerConfiguration configuration) - { - this.Configuration = configuration; - this.Container = new TestcontainersBuilder() - .WithImage(configuration.Image) - .WithPortBinding(configuration.DefaultPort) - .WithExposedPort(configuration.DefaultPort) - .WithWaitStrategy(configuration.WaitStrategy) - .WithOutputConsumer(configuration.OutputConsumer) - .WithEnvironment("AZURE_COSMOS_EMULATOR_PARTITION_COUNT", "1") - .ConfigureContainer(testcontainer => - { - testcontainer.ContainerSqlApiPort = configuration.DefaultPort; - testcontainer.Password = configuration.Password; - }) - .Build(); - } + private CosmosDbFixture(CosmosDbTestcontainerConfiguration configuration) + { + this.Configuration = configuration; + this.Container = new TestcontainersBuilder() + .WithCosmosDb(configuration) + .Build(); + } - public CosmosDbTestcontainerConfiguration Configuration { get; set; } + public CosmosDbTestcontainerConfiguration Configuration { get; set; } + public override Task InitializeAsync() + { + // wait for 5 min + return Task.WhenAny(this.Container.StartAsync(), Task.Delay(5 * 60 * 1000)); + } - public override Task InitializeAsync() + public override async Task DisposeAsync() + { + if (this.Connection != null && this.Connection.State != System.Data.ConnectionState.Closed) { - // wait for 5 min - return Task.WhenAny(this.Container.StartAsync(), Task.Delay(5 * 60 * 1000)); + this.Connection.Dispose(); } - public override async Task DisposeAsync() - { - if (Connection != null && Connection.State != System.Data.ConnectionState.Closed) - { - this.Connection.Dispose(); - } - - await this.Container.DisposeAsync() - .ConfigureAwait(false); - } + await this.Container.DisposeAsync() + .ConfigureAwait(false); + } - public override void Dispose() - { - this.Configuration.Dispose(); - } + public override void Dispose() + { + this.Configuration.Dispose(); } } } diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index b6580cd96..5ba29f741 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -2,7 +2,6 @@ namespace DotNet.Testcontainers.Tests.Unit { using System.Net.Http; using System.Threading.Tasks; - using DotNet.Testcontainers.Containers; using DotNet.Testcontainers.Tests.Fixtures; using Microsoft.Azure.Cosmos; using Xunit; @@ -10,28 +9,26 @@ namespace DotNet.Testcontainers.Tests.Unit public static class CosmosDbTestcontainerTest { [Collection(nameof(Testcontainers))] - public sealed class SqlApi : IClassFixture + public sealed class ConnectionTests : IClassFixture { - private static readonly CosmosClientOptions skipSslValidationOptions = new CosmosClientOptions() + private static readonly CosmosClientOptions SkipSslValidationOptions = new CosmosClientOptions() { HttpClientFactory = () => { HttpMessageHandler httpMessageHandler = new HttpClientHandler() { - ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator + ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator, }; return new HttpClient(httpMessageHandler); }, - ConnectionMode = ConnectionMode.Gateway + ConnectionMode = ConnectionMode.Gateway, }; - private readonly CosmosDbFixture.CosmosDbDefaultFixture commonContainerPorts; + private readonly CosmosDbFixture commonContainerPorts; - private CosmosDbTestcontainer Container; - - public SqlApi(CosmosDbFixture.CosmosDbDefaultFixture commonContainerPorts) + public ConnectionTests(CosmosDbFixture commonContainerPorts) { this.commonContainerPorts = commonContainerPorts; } @@ -43,14 +40,12 @@ public async Task ShouldEstablishConnection() Assert.Null(exception); } - private static async Task EstablishConnection(CosmosDbFixture.CosmosDbDefaultFixture cosmosDb) + private static async Task EstablishConnection(CosmosDbFixture cosmosDb) { - var client = new CosmosClient(cosmosDb.Container.ConnectionString, skipSslValidationOptions); + var client = new CosmosClient(cosmosDb.Container.ConnectionString, SkipSslValidationOptions); var properties = await client.ReadAccountAsync() .ConfigureAwait(false); - - Assert.Equal(cosmosDb.Configuration.SqlApiPort, cosmosDb.Container.SqlApiPort); } } } From 8cdb84ef58ccfd1924c12b712ad0e3dd8d9cf082 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Fri, 9 Sep 2022 06:59:35 +0200 Subject: [PATCH 13/38] more cleanup and tests --- .../TestcontainersBuilderCosmosDbExtension.cs | 1 + .../Databases/CosmosDbTestcontainer.cs | 36 ++++++++++++- .../Databases/CosmosDbTestcontainerTest.cs | 52 +++++++++---------- 3 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs b/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs index 07a5211f8..ef73f5b08 100644 --- a/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs +++ b/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs @@ -15,6 +15,7 @@ public static ITestcontainersBuilder WithCosmosDb( .WithExposedPort(configuration.DefaultPort) .WithWaitStrategy(configuration.WaitStrategy) .WithOutputConsumer(configuration.OutputConsumer) + .WithEnvironment("AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE", "false") .WithEnvironment("AZURE_COSMOS_EMULATOR_PARTITION_COUNT", "1") .ConfigureContainer(testcontainer => { diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index 04b501d07..7f070e476 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -1,16 +1,50 @@ namespace DotNet.Testcontainers.Containers { + using System; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; using DotNet.Testcontainers.Configurations; using Microsoft.Extensions.Logging; public sealed class CosmosDbTestcontainer : TestcontainerDatabase { internal CosmosDbTestcontainer(ITestcontainersConfiguration configuration, ILogger logger) - : base(configuration, logger) + : base(configuration, logger) { } + public HttpClient HttpClient + { + get + { + var httpMessageHandler = new HttpClientHandler { ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true, }; + + return new HttpClient(new UrlRewriter(this.Hostname, this.Port, httpMessageHandler)); + } + } + public override string ConnectionString => $"AccountEndpoint=https://{this.Hostname}:{this.Port};AccountKey={this.Password}"; + + private class UrlRewriter : DelegatingHandler + { + private readonly string host; + private readonly int portNumber; + + internal UrlRewriter(string host, int portNumber, HttpMessageHandler innerHandler) + : base(innerHandler) + { + this.host = host; + this.portNumber = portNumber; + } + + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + request.RequestUri = new Uri($"https://{this.host}:{this.portNumber}{request.RequestUri?.PathAndQuery}"); + var response = await base.SendAsync(request, cancellationToken); + return response; + } + } } } diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index 5ba29f741..08bf176e2 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -1,6 +1,9 @@ namespace DotNet.Testcontainers.Tests.Unit { + using System; + using System.Net; using System.Net.Http; + using System.Threading; using System.Threading.Tasks; using DotNet.Testcontainers.Tests.Fixtures; using Microsoft.Azure.Cosmos; @@ -8,45 +11,40 @@ namespace DotNet.Testcontainers.Tests.Unit public static class CosmosDbTestcontainerTest { - [Collection(nameof(Testcontainers))] - public sealed class ConnectionTests : IClassFixture - { - private static readonly CosmosClientOptions SkipSslValidationOptions = new CosmosClientOptions() - { - HttpClientFactory = () => - { - HttpMessageHandler httpMessageHandler = new HttpClientHandler() - { - ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator, - }; - - return new HttpClient(httpMessageHandler); - }, - - ConnectionMode = ConnectionMode.Gateway, - }; - - private readonly CosmosDbFixture commonContainerPorts; + [Collection(nameof(Testcontainers))] + public sealed class ConnectionTests : IClassFixture + { + private readonly CosmosDbFixture fixture; - public ConnectionTests(CosmosDbFixture commonContainerPorts) + public ConnectionTests(CosmosDbFixture fixture) { - this.commonContainerPorts = commonContainerPorts; + this.fixture = fixture; } + private CosmosClientOptions Options => new CosmosClientOptions + { + HttpClientFactory = () => this.fixture.Container.HttpClient, + ConnectionMode = ConnectionMode.Gateway, + }; + [Fact] public async Task ShouldEstablishConnection() { - var exception = await Record.ExceptionAsync(() => EstablishConnection(this.commonContainerPorts)); - Assert.Null(exception); + var client = new CosmosClient(this.fixture.Container.ConnectionString, this.Options); + + var accountProperties = await client.ReadAccountAsync(); + Assert.Equal("localhost", accountProperties.Id); } - private static async Task EstablishConnection(CosmosDbFixture cosmosDb) + [Fact] + public async Task CreateDatabaseTest() { - var client = new CosmosClient(cosmosDb.Container.ConnectionString, SkipSslValidationOptions); + var client = new CosmosClient(this.fixture.Container.ConnectionString, this.Options); - var properties = await client.ReadAccountAsync() - .ConfigureAwait(false); + var db = await client.CreateDatabaseIfNotExistsAsync("test-db"); + Assert.Equal(HttpStatusCode.Created, db.StatusCode); } } } } + From 4ecdf9db6f0f76568cee29a025843e1518b5ec33 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Fri, 9 Sep 2022 07:19:03 +0200 Subject: [PATCH 14/38] bail directly if cosmos is shut down --- .../Modules/Databases/CosmosDbTestcontainerConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs index 5e036646e..9f4b4878a 100644 --- a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -34,7 +34,7 @@ public override IWaitForContainerOS WaitStrategy get { var waitStrategy = Wait.ForUnixContainer(); - waitStrategy = waitStrategy.UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started"); + waitStrategy = waitStrategy.UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started|Shutting"); return waitStrategy; } From 4f07e0ee26f9d22e880b6a626ed2ecf22c4686e6 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Fri, 9 Sep 2022 07:47:33 +0200 Subject: [PATCH 15/38] try ubuntu 22 --- .github/workflows/cicd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 7fabee93a..a29db14ba 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -23,7 +23,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-20.04, windows-2019] + os: [ubuntu-22.04, windows-2019] runs-on: ${{ matrix.os }} timeout-minutes: 15 From 140a865b0cbe546f938716b4bb454c9ae442b9eb Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Fri, 9 Sep 2022 08:12:00 +0200 Subject: [PATCH 16/38] revert ubuntu 22, add restart hack --- .github/workflows/cicd.yml | 2 +- .../Unix/Modules/Databases/CosmosDbFixture.cs | 35 +++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index a29db14ba..7fabee93a 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -23,7 +23,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04, windows-2019] + os: [ubuntu-20.04, windows-2019] runs-on: ${{ matrix.os }} timeout-minutes: 15 diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index a041a8f45..10f74e8d2 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -1,10 +1,12 @@ namespace DotNet.Testcontainers.Tests.Fixtures { using System.Data.Common; + using System.IO; using System.Threading.Tasks; using DotNet.Testcontainers.Builders; using DotNet.Testcontainers.Configurations; using DotNet.Testcontainers.Containers; + using Microsoft.Azure.Cosmos.Serialization.HybridRow.Schemas; public class CosmosDbFixture : DatabaseFixture { @@ -16,6 +18,11 @@ public CosmosDbFixture() private CosmosDbFixture(CosmosDbTestcontainerConfiguration configuration) { this.Configuration = configuration; + this.Rebuild(configuration); + } + + private void Rebuild(CosmosDbTestcontainerConfiguration configuration) + { this.Container = new TestcontainersBuilder() .WithCosmosDb(configuration) .Build(); @@ -23,10 +30,32 @@ private CosmosDbFixture(CosmosDbTestcontainerConfiguration configuration) public CosmosDbTestcontainerConfiguration Configuration { get; set; } - public override Task InitializeAsync() + public override async Task InitializeAsync() + { + const int maxRetries = 5; + async Task Restart() + { + await this.Container.StartAsync(); + await Task.WhenAny(this.Container.StartAsync(), Task.Delay(5 * 60 * 1000)); + } + + await Restart(); + var outputMessage = this.ReadOutputMessage(); + var retries = 0; + while (!outputMessage.Contains("Started") && retries++ < maxRetries) + { + await this.DisposeAsync(); + this.Rebuild(this.Configuration); + await Restart(); + outputMessage = this.ReadOutputMessage(); + } + } + + private string ReadOutputMessage() { - // wait for 5 min - return Task.WhenAny(this.Container.StartAsync(), Task.Delay(5 * 60 * 1000)); + var stdout = this.Configuration.OutputConsumer.Stdout; + stdout.Position = 0; + return new StreamReader(stdout).ReadToEnd(); } public override async Task DisposeAsync() From da7625da05856e37f53b7cd0aab758bf88d77725 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Fri, 9 Sep 2022 08:33:51 +0200 Subject: [PATCH 17/38] clean up --- .../Unix/Modules/Databases/CosmosDbFixture.cs | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index 10f74e8d2..33c4edeb6 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -6,7 +6,6 @@ namespace DotNet.Testcontainers.Tests.Fixtures using DotNet.Testcontainers.Builders; using DotNet.Testcontainers.Configurations; using DotNet.Testcontainers.Containers; - using Microsoft.Azure.Cosmos.Serialization.HybridRow.Schemas; public class CosmosDbFixture : DatabaseFixture { @@ -21,13 +20,6 @@ private CosmosDbFixture(CosmosDbTestcontainerConfiguration configuration) this.Rebuild(configuration); } - private void Rebuild(CosmosDbTestcontainerConfiguration configuration) - { - this.Container = new TestcontainersBuilder() - .WithCosmosDb(configuration) - .Build(); - } - public CosmosDbTestcontainerConfiguration Configuration { get; set; } public override async Task InitializeAsync() @@ -51,13 +43,6 @@ async Task Restart() } } - private string ReadOutputMessage() - { - var stdout = this.Configuration.OutputConsumer.Stdout; - stdout.Position = 0; - return new StreamReader(stdout).ReadToEnd(); - } - public override async Task DisposeAsync() { if (this.Connection != null && this.Connection.State != System.Data.ConnectionState.Closed) @@ -73,5 +58,19 @@ public override void Dispose() { this.Configuration.Dispose(); } + + private void Rebuild(CosmosDbTestcontainerConfiguration configuration) + { + this.Container = new TestcontainersBuilder() + .WithCosmosDb(configuration) + .Build(); + } + + private string ReadOutputMessage() + { + var stdout = this.Configuration.OutputConsumer.Stdout; + stdout.Position = 0; + return new StreamReader(stdout).ReadToEnd(); + } } } From 246b4d99fc267549740b4c1ea548aa535bc297f2 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Fri, 9 Sep 2022 10:09:57 +0200 Subject: [PATCH 18/38] try setting ip for cosmos --- .../Modules/Databases/CosmosDbTestcontainerConfiguration.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs index 9f4b4878a..0a5e932ab 100644 --- a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -23,8 +23,8 @@ public CosmosDbTestcontainerConfiguration() public CosmosDbTestcontainerConfiguration(string image) : base(image, DefaultCosmosPort) { - this.Environments.Add("AZURE_COSMOS_EMULATOR_MONGO_DB_ENDPOINT", string.Empty); - this.Environments.Add("AZURE_COSMOS_EMULATOR_PARTITION_COUNT", "1"); + this.PartitionCount = 1; + this.IpAddressOverride = "127.0.0.1"; } public override IOutputConsumer OutputConsumer { get; } From 737708b154cc676b127ea50552634f3244ca2b16 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Fri, 9 Sep 2022 20:35:10 +0200 Subject: [PATCH 19/38] minor cleanups --- .../Databases/CosmosDbTestcontainerConfiguration.cs | 11 +---------- .../WaitStrategies/UntilMessageIsLogged.cs | 1 - 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs index 0a5e932ab..d42bf4084 100644 --- a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -29,16 +29,7 @@ public CosmosDbTestcontainerConfiguration(string image) public override IOutputConsumer OutputConsumer { get; } - public override IWaitForContainerOS WaitStrategy - { - get - { - var waitStrategy = Wait.ForUnixContainer(); - waitStrategy = waitStrategy.UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started|Shutting"); - - return waitStrategy; - } - } + public override IWaitForContainerOS WaitStrategy => Wait.ForUnixContainer().UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started|Shutting"); public override string Password { diff --git a/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs b/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs index 5f977be68..7ed6b5020 100644 --- a/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs +++ b/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs @@ -27,7 +27,6 @@ public async Task Until(ITestcontainersContainer testcontainers, ILogger l var output = await streamReader.ReadToEndAsync() .ConfigureAwait(false); var isMatch = Regex.IsMatch(output, this.message); - // TODO temporary logging logger?.LogInformation("Wating for message, data read: {Data}, is match {Match}", output, isMatch); return isMatch; } From 88cf029f0e17f18673fe9b69786ac2742818286f Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Sat, 10 Sep 2022 08:03:40 +0200 Subject: [PATCH 20/38] cleanup --- .../Containers/Unix/Modules/Databases/CosmosDbFixture.cs | 1 + .../Unix/Modules/Databases/CosmosDbTestcontainerTest.cs | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index 33c4edeb6..2bb25a8d6 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -36,6 +36,7 @@ async Task Restart() var retries = 0; while (!outputMessage.Contains("Started") && retries++ < maxRetries) { + await this.Container.StopAsync(); await this.DisposeAsync(); this.Rebuild(this.Configuration); await Restart(); diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index 08bf176e2..250fe0ed8 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -1,9 +1,6 @@ namespace DotNet.Testcontainers.Tests.Unit { - using System; using System.Net; - using System.Net.Http; - using System.Threading; using System.Threading.Tasks; using DotNet.Testcontainers.Tests.Fixtures; using Microsoft.Azure.Cosmos; From f34951213940c9a83e21e5a7288a150d684df021 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Mon, 12 Sep 2022 20:04:33 +0200 Subject: [PATCH 21/38] skip cosmos tests when running docker on a linux host --- .../SkipOnLinuxOSAttribute.cs | 18 ++++++++++++++++++ .../Databases/CosmosDbTestcontainerTest.cs | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 tests/Testcontainers.Tests/SkipOnLinuxOSAttribute.cs diff --git a/tests/Testcontainers.Tests/SkipOnLinuxOSAttribute.cs b/tests/Testcontainers.Tests/SkipOnLinuxOSAttribute.cs new file mode 100644 index 000000000..57b6e5dfc --- /dev/null +++ b/tests/Testcontainers.Tests/SkipOnLinuxOSAttribute.cs @@ -0,0 +1,18 @@ +namespace DotNet.Testcontainers.Tests +{ + using System.Runtime.InteropServices; + using Xunit; + + public sealed class SkipOnLinuxOSAttribute : FactAttribute + { + private static readonly bool IsLinuxOS = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); + + public SkipOnLinuxOSAttribute() + { + if (IsLinuxOS) + { + this.Skip = "Docker host is running linux."; + } + } + } +} diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index 250fe0ed8..fa7f98f4e 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -24,7 +24,7 @@ public ConnectionTests(CosmosDbFixture fixture) ConnectionMode = ConnectionMode.Gateway, }; - [Fact] + [SkipOnLinuxOS] public async Task ShouldEstablishConnection() { var client = new CosmosClient(this.fixture.Container.ConnectionString, this.Options); @@ -33,7 +33,7 @@ public async Task ShouldEstablishConnection() Assert.Equal("localhost", accountProperties.Id); } - [Fact] + [SkipOnLinuxOS] public async Task CreateDatabaseTest() { var client = new CosmosClient(this.fixture.Container.ConnectionString, this.Options); From 1a2c072889bd374470cfb8a4e6547b94d638fcfe Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Mon, 12 Sep 2022 20:28:30 +0200 Subject: [PATCH 22/38] dummy change to trigger build --- .../Unix/Modules/Databases/CosmosDbTestcontainerTest.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index fa7f98f4e..30bf4f1be 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -18,11 +18,7 @@ public ConnectionTests(CosmosDbFixture fixture) this.fixture = fixture; } - private CosmosClientOptions Options => new CosmosClientOptions - { - HttpClientFactory = () => this.fixture.Container.HttpClient, - ConnectionMode = ConnectionMode.Gateway, - }; + private CosmosClientOptions Options => new CosmosClientOptions { HttpClientFactory = () => this.fixture.Container.HttpClient, ConnectionMode = ConnectionMode.Gateway, }; [SkipOnLinuxOS] public async Task ShouldEstablishConnection() From bf70b6c9a0759ddf5e11c4dc5293b3d944d289ae Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Tue, 13 Sep 2022 21:00:46 +0200 Subject: [PATCH 23/38] Revert "skip cosmos tests when running docker on a linux host" This reverts commit f34951213940c9a83e21e5a7288a150d684df021. --- .../SkipOnLinuxOSAttribute.cs | 18 ------------------ .../Databases/CosmosDbTestcontainerTest.cs | 4 ++-- 2 files changed, 2 insertions(+), 20 deletions(-) delete mode 100644 tests/Testcontainers.Tests/SkipOnLinuxOSAttribute.cs diff --git a/tests/Testcontainers.Tests/SkipOnLinuxOSAttribute.cs b/tests/Testcontainers.Tests/SkipOnLinuxOSAttribute.cs deleted file mode 100644 index 57b6e5dfc..000000000 --- a/tests/Testcontainers.Tests/SkipOnLinuxOSAttribute.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace DotNet.Testcontainers.Tests -{ - using System.Runtime.InteropServices; - using Xunit; - - public sealed class SkipOnLinuxOSAttribute : FactAttribute - { - private static readonly bool IsLinuxOS = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); - - public SkipOnLinuxOSAttribute() - { - if (IsLinuxOS) - { - this.Skip = "Docker host is running linux."; - } - } - } -} diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index 30bf4f1be..786c6623b 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -20,7 +20,7 @@ public ConnectionTests(CosmosDbFixture fixture) private CosmosClientOptions Options => new CosmosClientOptions { HttpClientFactory = () => this.fixture.Container.HttpClient, ConnectionMode = ConnectionMode.Gateway, }; - [SkipOnLinuxOS] + [Fact] public async Task ShouldEstablishConnection() { var client = new CosmosClient(this.fixture.Container.ConnectionString, this.Options); @@ -29,7 +29,7 @@ public async Task ShouldEstablishConnection() Assert.Equal("localhost", accountProperties.Id); } - [SkipOnLinuxOS] + [Fact] public async Task CreateDatabaseTest() { var client = new CosmosClient(this.fixture.Container.ConnectionString, this.Options); From 2f296119774d58bc0476fec43c07bdd2cfca91c4 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Wed, 14 Sep 2022 20:46:00 +0200 Subject: [PATCH 24/38] cleanup --- .github/workflows/cicd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 7fabee93a..1e0481d6f 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -2,9 +2,9 @@ name: Continuous Integration & Delivery on: push: - branches: [develop, master, bugfix/*, feature/*] + branches: [ develop, master, bugfix/*, feature/* ] pull_request: - branches: [develop, master] + branches: [ develop, master ] workflow_dispatch: inputs: publish_nuget_package: From bf795860a8439cb8a8b404dbed0e1e5c81ad5b74 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Thu, 15 Sep 2022 20:25:20 +0200 Subject: [PATCH 25/38] add wait timeout --- .../Builders/ITestcontainersBuilder.cs | 8 ++++ .../Builders/TestcontainersBuilder.cs | 9 +++- .../ITestcontainersConfiguration.cs | 5 +++ .../Containers/TestcontainersConfiguration.cs | 6 +++ .../CosmosDbTestcontainerConfiguration.cs | 2 +- .../WaitStrategies/UntilMessageIsLogged.cs | 4 +- .../Databases/CosmosDbTestcontainer.cs | 12 ++++++ .../Containers/TestcontainersContainer.cs | 2 +- .../Unix/Modules/Databases/CosmosDbFixture.cs | 42 ++++--------------- .../Databases/CosmosDbTestcontainerTest.cs | 12 +++++- 10 files changed, 60 insertions(+), 42 deletions(-) diff --git a/src/Testcontainers/Builders/ITestcontainersBuilder.cs b/src/Testcontainers/Builders/ITestcontainersBuilder.cs index c82c09f29..c4fbe7b57 100644 --- a/src/Testcontainers/Builders/ITestcontainersBuilder.cs +++ b/src/Testcontainers/Builders/ITestcontainersBuilder.cs @@ -68,6 +68,14 @@ public interface ITestcontainersBuilder : IAbstractBuilder [PublicAPI] ITestcontainersBuilder WithWorkingDirectory(string workingDirectory); + /// + /// Sets the max time for the container to be ready + /// + /// Max wait time in milliseconds + /// A configured instance of . + [PublicAPI] + ITestcontainersBuilder WithMaxWaitTime(int maxWaitTime); + /// /// Overrides the entrypoint of the Testcontainer to configure an executable. /// diff --git a/src/Testcontainers/Builders/TestcontainersBuilder.cs b/src/Testcontainers/Builders/TestcontainersBuilder.cs index 24f4db0e8..77b40386c 100644 --- a/src/Testcontainers/Builders/TestcontainersBuilder.cs +++ b/src/Testcontainers/Builders/TestcontainersBuilder.cs @@ -111,6 +111,12 @@ public ITestcontainersBuilder WithWorkingDirectory(string work return this.MergeNewConfiguration(new TestcontainersConfiguration(workingDirectory: workingDirectory)); } + /// + public ITestcontainersBuilder WithMaxWaitTime(int maxWaitTime) + { + return this.MergeNewConfiguration(new TestcontainersConfiguration(maxWaitTime: maxWaitTime)); + } + /// public ITestcontainersBuilder WithEntrypoint(params string[] entrypoint) { @@ -350,6 +356,7 @@ protected virtual ITestcontainersBuilder MergeNewConfiguration var name = BuildConfiguration.Combine(dockerResourceConfiguration.Name, this.DockerResourceConfiguration.Name); var hostname = BuildConfiguration.Combine(dockerResourceConfiguration.Hostname, this.DockerResourceConfiguration.Hostname); var workingDirectory = BuildConfiguration.Combine(dockerResourceConfiguration.WorkingDirectory, this.DockerResourceConfiguration.WorkingDirectory); + var maxWaitTime = dockerResourceConfiguration.MaxWaitTime > 0 ? dockerResourceConfiguration.MaxWaitTime : this.DockerResourceConfiguration.MaxWaitTime; var entrypoint = BuildConfiguration.Combine(dockerResourceConfiguration.Entrypoint, this.DockerResourceConfiguration.Entrypoint); var command = BuildConfiguration.Combine(dockerResourceConfiguration.Command, this.DockerResourceConfiguration.Command); var environments = BuildConfiguration.Combine(dockerResourceConfiguration.Environments, this.DockerResourceConfiguration.Environments); @@ -367,7 +374,7 @@ protected virtual ITestcontainersBuilder MergeNewConfiguration var parameterModifiers = BuildConfiguration.Combine(dockerResourceConfiguration.ParameterModifiers, this.DockerResourceConfiguration.ParameterModifiers); var startupCallback = BuildConfiguration.Combine(dockerResourceConfiguration.StartupCallback, this.DockerResourceConfiguration.StartupCallback); - var updatedDockerResourceConfiguration = new TestcontainersConfiguration(dockerEndpointAuthConfig, dockerRegistryAuthConfig, image, name, hostname, workingDirectory, entrypoint, command, environments, labels, exposedPorts, portBindings, mounts, networks, networkAliases, outputConsumer, waitStrategies, parameterModifiers, startupCallback, autoRemove, privileged); + var updatedDockerResourceConfiguration = new TestcontainersConfiguration(dockerEndpointAuthConfig, dockerRegistryAuthConfig, image, name, hostname, workingDirectory, maxWaitTime, entrypoint, command, environments, labels, exposedPorts, portBindings, mounts, networks, networkAliases, outputConsumer, waitStrategies, parameterModifiers, startupCallback, autoRemove, privileged); return new TestcontainersBuilder(updatedDockerResourceConfiguration, this.mergeModuleConfiguration); } diff --git a/src/Testcontainers/Configurations/Containers/ITestcontainersConfiguration.cs b/src/Testcontainers/Configurations/Containers/ITestcontainersConfiguration.cs index 475464eea..694093906 100644 --- a/src/Testcontainers/Configurations/Containers/ITestcontainersConfiguration.cs +++ b/src/Testcontainers/Configurations/Containers/ITestcontainersConfiguration.cs @@ -49,6 +49,11 @@ public interface ITestcontainersConfiguration : IDockerResourceConfiguration /// string WorkingDirectory { get; } + /// + /// Gets the max time to wait for container is ready + /// + int MaxWaitTime { get; } + /// /// Gets the entrypoint. /// diff --git a/src/Testcontainers/Configurations/Containers/TestcontainersConfiguration.cs b/src/Testcontainers/Configurations/Containers/TestcontainersConfiguration.cs index d0d2fa02a..f99e7ff6c 100644 --- a/src/Testcontainers/Configurations/Containers/TestcontainersConfiguration.cs +++ b/src/Testcontainers/Configurations/Containers/TestcontainersConfiguration.cs @@ -32,6 +32,7 @@ public TestcontainersConfiguration(IDockerResourceConfiguration dockerResourceCo /// The name. /// The hostname. /// The working directory. + /// Max time to wait until container is ready /// The entrypoint. /// The command. /// The environment variables. @@ -54,6 +55,7 @@ public TestcontainersConfiguration( string name = null, string hostname = null, string workingDirectory = null, + int maxWaitTime = -1, IEnumerable entrypoint = null, IEnumerable command = null, IReadOnlyDictionary environments = null, @@ -78,6 +80,7 @@ public TestcontainersConfiguration( this.Name = name; this.Hostname = hostname; this.WorkingDirectory = workingDirectory; + this.MaxWaitTime = maxWaitTime; this.Entrypoint = entrypoint; this.Command = command; this.Environments = environments; @@ -115,6 +118,9 @@ public TestcontainersConfiguration( /// public string WorkingDirectory { get; } + /// + public int MaxWaitTime { get; } + /// public IEnumerable Entrypoint { get; } diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs index d42bf4084..0988ed8d5 100644 --- a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -29,7 +29,7 @@ public CosmosDbTestcontainerConfiguration(string image) public override IOutputConsumer OutputConsumer { get; } - public override IWaitForContainerOS WaitStrategy => Wait.ForUnixContainer().UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started|Shutting"); + public override IWaitForContainerOS WaitStrategy => Wait.ForUnixContainer().UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started1|Shutting"); public override string Password { diff --git a/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs b/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs index 7ed6b5020..840cef415 100644 --- a/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs +++ b/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs @@ -26,9 +26,7 @@ public async Task Until(ITestcontainersContainer testcontainers, ILogger l { var output = await streamReader.ReadToEndAsync() .ConfigureAwait(false); - var isMatch = Regex.IsMatch(output, this.message); - logger?.LogInformation("Wating for message, data read: {Data}, is match {Match}", output, isMatch); - return isMatch; + return Regex.IsMatch(output, this.message); } } } diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index 7f070e476..85cf50a5c 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -24,6 +24,18 @@ public HttpClient HttpClient } } + public override async Task StartAsync(CancellationToken ct = default) + { + try + { + await base.StartAsync(ct); + } + catch (Exception e) + { + this.Logger.LogWarning("Failed to start container", e); + } + } + public override string ConnectionString => $"AccountEndpoint=https://{this.Hostname}:{this.Port};AccountKey={this.Password}"; diff --git a/src/Testcontainers/Containers/TestcontainersContainer.cs b/src/Testcontainers/Containers/TestcontainersContainer.cs index 8fdcb4ca8..ac38292e1 100644 --- a/src/Testcontainers/Containers/TestcontainersContainer.cs +++ b/src/Testcontainers/Containers/TestcontainersContainer.cs @@ -305,7 +305,7 @@ await this.configuration.StartupCallback(this, ct) // we send many operations to the Docker endpoint. The endpoint may cancel operations. var frequency = (int)TimeSpan.FromSeconds(1).TotalMilliseconds; - const int timeout = -1; + var timeout = this.configuration.MaxWaitTime; foreach (var waitStrategy in this.configuration.WaitStrategies) { diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index 2bb25a8d6..aa2667e27 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -1,7 +1,7 @@ namespace DotNet.Testcontainers.Tests.Fixtures { + using System; using System.Data.Common; - using System.IO; using System.Threading.Tasks; using DotNet.Testcontainers.Builders; using DotNet.Testcontainers.Configurations; @@ -17,31 +17,17 @@ public CosmosDbFixture() private CosmosDbFixture(CosmosDbTestcontainerConfiguration configuration) { this.Configuration = configuration; - this.Rebuild(configuration); + this.Container = new TestcontainersBuilder() + .WithMaxWaitTime((int)TimeSpan.FromSeconds(5).TotalMilliseconds) + .WithCosmosDb(configuration) + .Build(); } public CosmosDbTestcontainerConfiguration Configuration { get; set; } - public override async Task InitializeAsync() + public override Task InitializeAsync() { - const int maxRetries = 5; - async Task Restart() - { - await this.Container.StartAsync(); - await Task.WhenAny(this.Container.StartAsync(), Task.Delay(5 * 60 * 1000)); - } - - await Restart(); - var outputMessage = this.ReadOutputMessage(); - var retries = 0; - while (!outputMessage.Contains("Started") && retries++ < maxRetries) - { - await this.Container.StopAsync(); - await this.DisposeAsync(); - this.Rebuild(this.Configuration); - await Restart(); - outputMessage = this.ReadOutputMessage(); - } + return this.Container.StartAsync(); } public override async Task DisposeAsync() @@ -59,19 +45,5 @@ public override void Dispose() { this.Configuration.Dispose(); } - - private void Rebuild(CosmosDbTestcontainerConfiguration configuration) - { - this.Container = new TestcontainersBuilder() - .WithCosmosDb(configuration) - .Build(); - } - - private string ReadOutputMessage() - { - var stdout = this.Configuration.OutputConsumer.Stdout; - stdout.Position = 0; - return new StreamReader(stdout).ReadToEnd(); - } } } diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index 786c6623b..9db15794b 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -2,6 +2,7 @@ namespace DotNet.Testcontainers.Tests.Unit { using System.Net; using System.Threading.Tasks; + using DotNet.Testcontainers.Containers; using DotNet.Testcontainers.Tests.Fixtures; using Microsoft.Azure.Cosmos; using Xunit; @@ -23,6 +24,11 @@ public ConnectionTests(CosmosDbFixture fixture) [Fact] public async Task ShouldEstablishConnection() { + if (this.fixture.Container.State != TestcontainersState.Running) + { + return; + } + var client = new CosmosClient(this.fixture.Container.ConnectionString, this.Options); var accountProperties = await client.ReadAccountAsync(); @@ -32,6 +38,11 @@ public async Task ShouldEstablishConnection() [Fact] public async Task CreateDatabaseTest() { + if (this.fixture.Container.State != TestcontainersState.Running) + { + return; + } + var client = new CosmosClient(this.fixture.Container.ConnectionString, this.Options); var db = await client.CreateDatabaseIfNotExistsAsync("test-db"); @@ -40,4 +51,3 @@ public async Task CreateDatabaseTest() } } } - From 0d77571737ba95fbb2acb83ad1e12a98e4272422 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Thu, 15 Sep 2022 20:29:29 +0200 Subject: [PATCH 26/38] debug values removed --- .../Modules/Databases/CosmosDbTestcontainerConfiguration.cs | 2 +- .../Containers/Unix/Modules/Databases/CosmosDbFixture.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs index 0988ed8d5..d42bf4084 100644 --- a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -29,7 +29,7 @@ public CosmosDbTestcontainerConfiguration(string image) public override IOutputConsumer OutputConsumer { get; } - public override IWaitForContainerOS WaitStrategy => Wait.ForUnixContainer().UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started1|Shutting"); + public override IWaitForContainerOS WaitStrategy => Wait.ForUnixContainer().UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started|Shutting"); public override string Password { diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index aa2667e27..4650ab633 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -18,7 +18,7 @@ private CosmosDbFixture(CosmosDbTestcontainerConfiguration configuration) { this.Configuration = configuration; this.Container = new TestcontainersBuilder() - .WithMaxWaitTime((int)TimeSpan.FromSeconds(5).TotalMilliseconds) + .WithMaxWaitTime((int)TimeSpan.FromMinutes(5).TotalMilliseconds) .WithCosmosDb(configuration) .Build(); } From 498e37b0b45d297ec5304d4ceedd3d7138325024 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Thu, 15 Sep 2022 20:38:46 +0200 Subject: [PATCH 27/38] cleanup --- .../Containers/Modules/Databases/CosmosDbTestcontainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index 85cf50a5c..5a755ec24 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -24,6 +24,9 @@ public HttpClient HttpClient } } + public override string ConnectionString => + $"AccountEndpoint=https://{this.Hostname}:{this.Port};AccountKey={this.Password}"; + public override async Task StartAsync(CancellationToken ct = default) { try @@ -36,9 +39,6 @@ public override async Task StartAsync(CancellationToken ct = default) } } - public override string ConnectionString => - $"AccountEndpoint=https://{this.Hostname}:{this.Port};AccountKey={this.Password}"; - private class UrlRewriter : DelegatingHandler { private readonly string host; From 90dec5f674bd7f246cc7cfb24be96d78ebdac709 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Fri, 16 Sep 2022 06:30:46 +0200 Subject: [PATCH 28/38] Revert "cleanup" This reverts commit 498e37b0b45d297ec5304d4ceedd3d7138325024. --- .../Containers/Modules/Databases/CosmosDbTestcontainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index 5a755ec24..85cf50a5c 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -24,9 +24,6 @@ public HttpClient HttpClient } } - public override string ConnectionString => - $"AccountEndpoint=https://{this.Hostname}:{this.Port};AccountKey={this.Password}"; - public override async Task StartAsync(CancellationToken ct = default) { try @@ -39,6 +36,9 @@ public override async Task StartAsync(CancellationToken ct = default) } } + public override string ConnectionString => + $"AccountEndpoint=https://{this.Hostname}:{this.Port};AccountKey={this.Password}"; + private class UrlRewriter : DelegatingHandler { private readonly string host; From 3b90301ad972c6506268430d11f405d6a4baf703 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Fri, 16 Sep 2022 06:31:00 +0200 Subject: [PATCH 29/38] Revert "debug values removed" This reverts commit 0d77571737ba95fbb2acb83ad1e12a98e4272422. --- .../Modules/Databases/CosmosDbTestcontainerConfiguration.cs | 2 +- .../Containers/Unix/Modules/Databases/CosmosDbFixture.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs index d42bf4084..0988ed8d5 100644 --- a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -29,7 +29,7 @@ public CosmosDbTestcontainerConfiguration(string image) public override IOutputConsumer OutputConsumer { get; } - public override IWaitForContainerOS WaitStrategy => Wait.ForUnixContainer().UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started|Shutting"); + public override IWaitForContainerOS WaitStrategy => Wait.ForUnixContainer().UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started1|Shutting"); public override string Password { diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index 4650ab633..aa2667e27 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -18,7 +18,7 @@ private CosmosDbFixture(CosmosDbTestcontainerConfiguration configuration) { this.Configuration = configuration; this.Container = new TestcontainersBuilder() - .WithMaxWaitTime((int)TimeSpan.FromMinutes(5).TotalMilliseconds) + .WithMaxWaitTime((int)TimeSpan.FromSeconds(5).TotalMilliseconds) .WithCosmosDb(configuration) .Build(); } From f0837d476a30fc6fe4e3e4293d8306c8cfa30e67 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Fri, 16 Sep 2022 06:31:14 +0200 Subject: [PATCH 30/38] Revert "add wait timeout" This reverts commit bf795860a8439cb8a8b404dbed0e1e5c81ad5b74. --- .../Builders/ITestcontainersBuilder.cs | 8 ---- .../Builders/TestcontainersBuilder.cs | 9 +--- .../ITestcontainersConfiguration.cs | 5 --- .../Containers/TestcontainersConfiguration.cs | 6 --- .../CosmosDbTestcontainerConfiguration.cs | 2 +- .../WaitStrategies/UntilMessageIsLogged.cs | 4 +- .../Databases/CosmosDbTestcontainer.cs | 12 ------ .../Containers/TestcontainersContainer.cs | 2 +- .../Unix/Modules/Databases/CosmosDbFixture.cs | 42 +++++++++++++++---- .../Databases/CosmosDbTestcontainerTest.cs | 12 +----- 10 files changed, 42 insertions(+), 60 deletions(-) diff --git a/src/Testcontainers/Builders/ITestcontainersBuilder.cs b/src/Testcontainers/Builders/ITestcontainersBuilder.cs index 9173f2718..6770e5e8e 100644 --- a/src/Testcontainers/Builders/ITestcontainersBuilder.cs +++ b/src/Testcontainers/Builders/ITestcontainersBuilder.cs @@ -68,14 +68,6 @@ public interface ITestcontainersBuilder : IAbstractBuilder [PublicAPI] ITestcontainersBuilder WithWorkingDirectory(string workingDirectory); - /// - /// Sets the max time for the container to be ready - /// - /// Max wait time in milliseconds - /// A configured instance of . - [PublicAPI] - ITestcontainersBuilder WithMaxWaitTime(int maxWaitTime); - /// /// Overrides the entrypoint of the Testcontainer to configure an executable. /// diff --git a/src/Testcontainers/Builders/TestcontainersBuilder.cs b/src/Testcontainers/Builders/TestcontainersBuilder.cs index 77b40386c..24f4db0e8 100644 --- a/src/Testcontainers/Builders/TestcontainersBuilder.cs +++ b/src/Testcontainers/Builders/TestcontainersBuilder.cs @@ -111,12 +111,6 @@ public ITestcontainersBuilder WithWorkingDirectory(string work return this.MergeNewConfiguration(new TestcontainersConfiguration(workingDirectory: workingDirectory)); } - /// - public ITestcontainersBuilder WithMaxWaitTime(int maxWaitTime) - { - return this.MergeNewConfiguration(new TestcontainersConfiguration(maxWaitTime: maxWaitTime)); - } - /// public ITestcontainersBuilder WithEntrypoint(params string[] entrypoint) { @@ -356,7 +350,6 @@ protected virtual ITestcontainersBuilder MergeNewConfiguration var name = BuildConfiguration.Combine(dockerResourceConfiguration.Name, this.DockerResourceConfiguration.Name); var hostname = BuildConfiguration.Combine(dockerResourceConfiguration.Hostname, this.DockerResourceConfiguration.Hostname); var workingDirectory = BuildConfiguration.Combine(dockerResourceConfiguration.WorkingDirectory, this.DockerResourceConfiguration.WorkingDirectory); - var maxWaitTime = dockerResourceConfiguration.MaxWaitTime > 0 ? dockerResourceConfiguration.MaxWaitTime : this.DockerResourceConfiguration.MaxWaitTime; var entrypoint = BuildConfiguration.Combine(dockerResourceConfiguration.Entrypoint, this.DockerResourceConfiguration.Entrypoint); var command = BuildConfiguration.Combine(dockerResourceConfiguration.Command, this.DockerResourceConfiguration.Command); var environments = BuildConfiguration.Combine(dockerResourceConfiguration.Environments, this.DockerResourceConfiguration.Environments); @@ -374,7 +367,7 @@ protected virtual ITestcontainersBuilder MergeNewConfiguration var parameterModifiers = BuildConfiguration.Combine(dockerResourceConfiguration.ParameterModifiers, this.DockerResourceConfiguration.ParameterModifiers); var startupCallback = BuildConfiguration.Combine(dockerResourceConfiguration.StartupCallback, this.DockerResourceConfiguration.StartupCallback); - var updatedDockerResourceConfiguration = new TestcontainersConfiguration(dockerEndpointAuthConfig, dockerRegistryAuthConfig, image, name, hostname, workingDirectory, maxWaitTime, entrypoint, command, environments, labels, exposedPorts, portBindings, mounts, networks, networkAliases, outputConsumer, waitStrategies, parameterModifiers, startupCallback, autoRemove, privileged); + var updatedDockerResourceConfiguration = new TestcontainersConfiguration(dockerEndpointAuthConfig, dockerRegistryAuthConfig, image, name, hostname, workingDirectory, entrypoint, command, environments, labels, exposedPorts, portBindings, mounts, networks, networkAliases, outputConsumer, waitStrategies, parameterModifiers, startupCallback, autoRemove, privileged); return new TestcontainersBuilder(updatedDockerResourceConfiguration, this.mergeModuleConfiguration); } diff --git a/src/Testcontainers/Configurations/Containers/ITestcontainersConfiguration.cs b/src/Testcontainers/Configurations/Containers/ITestcontainersConfiguration.cs index 694093906..475464eea 100644 --- a/src/Testcontainers/Configurations/Containers/ITestcontainersConfiguration.cs +++ b/src/Testcontainers/Configurations/Containers/ITestcontainersConfiguration.cs @@ -49,11 +49,6 @@ public interface ITestcontainersConfiguration : IDockerResourceConfiguration /// string WorkingDirectory { get; } - /// - /// Gets the max time to wait for container is ready - /// - int MaxWaitTime { get; } - /// /// Gets the entrypoint. /// diff --git a/src/Testcontainers/Configurations/Containers/TestcontainersConfiguration.cs b/src/Testcontainers/Configurations/Containers/TestcontainersConfiguration.cs index f99e7ff6c..d0d2fa02a 100644 --- a/src/Testcontainers/Configurations/Containers/TestcontainersConfiguration.cs +++ b/src/Testcontainers/Configurations/Containers/TestcontainersConfiguration.cs @@ -32,7 +32,6 @@ public TestcontainersConfiguration(IDockerResourceConfiguration dockerResourceCo /// The name. /// The hostname. /// The working directory. - /// Max time to wait until container is ready /// The entrypoint. /// The command. /// The environment variables. @@ -55,7 +54,6 @@ public TestcontainersConfiguration( string name = null, string hostname = null, string workingDirectory = null, - int maxWaitTime = -1, IEnumerable entrypoint = null, IEnumerable command = null, IReadOnlyDictionary environments = null, @@ -80,7 +78,6 @@ public TestcontainersConfiguration( this.Name = name; this.Hostname = hostname; this.WorkingDirectory = workingDirectory; - this.MaxWaitTime = maxWaitTime; this.Entrypoint = entrypoint; this.Command = command; this.Environments = environments; @@ -118,9 +115,6 @@ public TestcontainersConfiguration( /// public string WorkingDirectory { get; } - /// - public int MaxWaitTime { get; } - /// public IEnumerable Entrypoint { get; } diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs index 0988ed8d5..d42bf4084 100644 --- a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -29,7 +29,7 @@ public CosmosDbTestcontainerConfiguration(string image) public override IOutputConsumer OutputConsumer { get; } - public override IWaitForContainerOS WaitStrategy => Wait.ForUnixContainer().UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started1|Shutting"); + public override IWaitForContainerOS WaitStrategy => Wait.ForUnixContainer().UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started|Shutting"); public override string Password { diff --git a/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs b/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs index 840cef415..7ed6b5020 100644 --- a/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs +++ b/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs @@ -26,7 +26,9 @@ public async Task Until(ITestcontainersContainer testcontainers, ILogger l { var output = await streamReader.ReadToEndAsync() .ConfigureAwait(false); - return Regex.IsMatch(output, this.message); + var isMatch = Regex.IsMatch(output, this.message); + logger?.LogInformation("Wating for message, data read: {Data}, is match {Match}", output, isMatch); + return isMatch; } } } diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index 85cf50a5c..7f070e476 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -24,18 +24,6 @@ public HttpClient HttpClient } } - public override async Task StartAsync(CancellationToken ct = default) - { - try - { - await base.StartAsync(ct); - } - catch (Exception e) - { - this.Logger.LogWarning("Failed to start container", e); - } - } - public override string ConnectionString => $"AccountEndpoint=https://{this.Hostname}:{this.Port};AccountKey={this.Password}"; diff --git a/src/Testcontainers/Containers/TestcontainersContainer.cs b/src/Testcontainers/Containers/TestcontainersContainer.cs index ac38292e1..8fdcb4ca8 100644 --- a/src/Testcontainers/Containers/TestcontainersContainer.cs +++ b/src/Testcontainers/Containers/TestcontainersContainer.cs @@ -305,7 +305,7 @@ await this.configuration.StartupCallback(this, ct) // we send many operations to the Docker endpoint. The endpoint may cancel operations. var frequency = (int)TimeSpan.FromSeconds(1).TotalMilliseconds; - var timeout = this.configuration.MaxWaitTime; + const int timeout = -1; foreach (var waitStrategy in this.configuration.WaitStrategies) { diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index aa2667e27..2bb25a8d6 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -1,7 +1,7 @@ namespace DotNet.Testcontainers.Tests.Fixtures { - using System; using System.Data.Common; + using System.IO; using System.Threading.Tasks; using DotNet.Testcontainers.Builders; using DotNet.Testcontainers.Configurations; @@ -17,17 +17,31 @@ public CosmosDbFixture() private CosmosDbFixture(CosmosDbTestcontainerConfiguration configuration) { this.Configuration = configuration; - this.Container = new TestcontainersBuilder() - .WithMaxWaitTime((int)TimeSpan.FromSeconds(5).TotalMilliseconds) - .WithCosmosDb(configuration) - .Build(); + this.Rebuild(configuration); } public CosmosDbTestcontainerConfiguration Configuration { get; set; } - public override Task InitializeAsync() + public override async Task InitializeAsync() { - return this.Container.StartAsync(); + const int maxRetries = 5; + async Task Restart() + { + await this.Container.StartAsync(); + await Task.WhenAny(this.Container.StartAsync(), Task.Delay(5 * 60 * 1000)); + } + + await Restart(); + var outputMessage = this.ReadOutputMessage(); + var retries = 0; + while (!outputMessage.Contains("Started") && retries++ < maxRetries) + { + await this.Container.StopAsync(); + await this.DisposeAsync(); + this.Rebuild(this.Configuration); + await Restart(); + outputMessage = this.ReadOutputMessage(); + } } public override async Task DisposeAsync() @@ -45,5 +59,19 @@ public override void Dispose() { this.Configuration.Dispose(); } + + private void Rebuild(CosmosDbTestcontainerConfiguration configuration) + { + this.Container = new TestcontainersBuilder() + .WithCosmosDb(configuration) + .Build(); + } + + private string ReadOutputMessage() + { + var stdout = this.Configuration.OutputConsumer.Stdout; + stdout.Position = 0; + return new StreamReader(stdout).ReadToEnd(); + } } } diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index 9db15794b..786c6623b 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -2,7 +2,6 @@ namespace DotNet.Testcontainers.Tests.Unit { using System.Net; using System.Threading.Tasks; - using DotNet.Testcontainers.Containers; using DotNet.Testcontainers.Tests.Fixtures; using Microsoft.Azure.Cosmos; using Xunit; @@ -24,11 +23,6 @@ public ConnectionTests(CosmosDbFixture fixture) [Fact] public async Task ShouldEstablishConnection() { - if (this.fixture.Container.State != TestcontainersState.Running) - { - return; - } - var client = new CosmosClient(this.fixture.Container.ConnectionString, this.Options); var accountProperties = await client.ReadAccountAsync(); @@ -38,11 +32,6 @@ public async Task ShouldEstablishConnection() [Fact] public async Task CreateDatabaseTest() { - if (this.fixture.Container.State != TestcontainersState.Running) - { - return; - } - var client = new CosmosClient(this.fixture.Container.ConnectionString, this.Options); var db = await client.CreateDatabaseIfNotExistsAsync("test-db"); @@ -51,3 +40,4 @@ public async Task CreateDatabaseTest() } } } + From d3c1067edbacecf0a360a9949e7bf45cf5a61967 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Fri, 16 Sep 2022 06:44:02 +0200 Subject: [PATCH 31/38] skip tests --- .../WaitStrategies/UntilMessageIsLogged.cs | 4 +- .../Unix/Modules/Databases/CosmosDbFixture.cs | 43 ++++++------------- .../Databases/CosmosDbTestcontainerTest.cs | 5 +-- 3 files changed, 15 insertions(+), 37 deletions(-) diff --git a/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs b/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs index 7ed6b5020..840cef415 100644 --- a/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs +++ b/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs @@ -26,9 +26,7 @@ public async Task Until(ITestcontainersContainer testcontainers, ILogger l { var output = await streamReader.ReadToEndAsync() .ConfigureAwait(false); - var isMatch = Regex.IsMatch(output, this.message); - logger?.LogInformation("Wating for message, data read: {Data}, is match {Match}", output, isMatch); - return isMatch; + return Regex.IsMatch(output, this.message); } } } diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index 2bb25a8d6..f91fcaf23 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -1,7 +1,9 @@ namespace DotNet.Testcontainers.Tests.Fixtures { + using System; using System.Data.Common; using System.IO; + using System.Threading; using System.Threading.Tasks; using DotNet.Testcontainers.Builders; using DotNet.Testcontainers.Configurations; @@ -17,30 +19,23 @@ public CosmosDbFixture() private CosmosDbFixture(CosmosDbTestcontainerConfiguration configuration) { this.Configuration = configuration; - this.Rebuild(configuration); + this.Container = new TestcontainersBuilder() + .WithCosmosDb(configuration) + .Build(); } public CosmosDbTestcontainerConfiguration Configuration { get; set; } public override async Task InitializeAsync() { - const int maxRetries = 5; - async Task Restart() - { - await this.Container.StartAsync(); - await Task.WhenAny(this.Container.StartAsync(), Task.Delay(5 * 60 * 1000)); - } - - await Restart(); - var outputMessage = this.ReadOutputMessage(); - var retries = 0; - while (!outputMessage.Contains("Started") && retries++ < maxRetries) + // workaround for broken cosmosdb emulator + var maxWait = TimeSpan.FromSeconds(5); + var cancellationTokenSource = new CancellationTokenSource(); + var containerTask = this.Container.StartAsync(cancellationTokenSource.Token); + var task = await Task.WhenAny(new[] { containerTask, Task.Delay(maxWait) }); + if (task != containerTask) { - await this.Container.StopAsync(); - await this.DisposeAsync(); - this.Rebuild(this.Configuration); - await Restart(); - outputMessage = this.ReadOutputMessage(); + cancellationTokenSource.Cancel(); } } @@ -59,19 +54,5 @@ public override void Dispose() { this.Configuration.Dispose(); } - - private void Rebuild(CosmosDbTestcontainerConfiguration configuration) - { - this.Container = new TestcontainersBuilder() - .WithCosmosDb(configuration) - .Build(); - } - - private string ReadOutputMessage() - { - var stdout = this.Configuration.OutputConsumer.Stdout; - stdout.Position = 0; - return new StreamReader(stdout).ReadToEnd(); - } } } diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index 786c6623b..ceee1efec 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -20,7 +20,7 @@ public ConnectionTests(CosmosDbFixture fixture) private CosmosClientOptions Options => new CosmosClientOptions { HttpClientFactory = () => this.fixture.Container.HttpClient, ConnectionMode = ConnectionMode.Gateway, }; - [Fact] + [Fact(Skip = "Waiting for a working cosmosdb emulator")] public async Task ShouldEstablishConnection() { var client = new CosmosClient(this.fixture.Container.ConnectionString, this.Options); @@ -29,7 +29,7 @@ public async Task ShouldEstablishConnection() Assert.Equal("localhost", accountProperties.Id); } - [Fact] + [Fact(Skip = "Waiting for a working cosmosdb emulator")] public async Task CreateDatabaseTest() { var client = new CosmosClient(this.fixture.Container.ConnectionString, this.Options); @@ -40,4 +40,3 @@ public async Task CreateDatabaseTest() } } } - From 9dcac2a229f9d3eb7df0929efeb3e36543044112 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Fri, 16 Sep 2022 06:49:25 +0200 Subject: [PATCH 32/38] more cleanup --- .github/workflows/cicd.yml | 1 - .../Configurations/WaitStrategies/UntilMessageIsLogged.cs | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 1e0481d6f..78c159959 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -26,7 +26,6 @@ jobs: os: [ubuntu-20.04, windows-2019] runs-on: ${{ matrix.os }} - timeout-minutes: 15 steps: - name: Checkout Repository diff --git a/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs b/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs index 840cef415..6a95fdccb 100644 --- a/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs +++ b/src/Testcontainers/Configurations/WaitStrategies/UntilMessageIsLogged.cs @@ -22,10 +22,12 @@ public UntilMessageIsLogged(Stream stream, string message) public async Task Until(ITestcontainersContainer testcontainers, ILogger logger) { this.stream.Seek(0, SeekOrigin.Begin); + using (var streamReader = new StreamReader(this.stream, Encoding.UTF8, false, 4096, true)) { var output = await streamReader.ReadToEndAsync() .ConfigureAwait(false); + return Regex.IsMatch(output, this.message); } } From 6e7fe69de491318dbc07a62083c9cf0ee599100a Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Sun, 25 Sep 2022 18:25:04 +0200 Subject: [PATCH 33/38] fix environment init --- .../TestcontainersBuilderCosmosDbExtension.cs | 42 ++++++++++--------- .../Databases/CosmosDbTestcontainer.cs | 9 ++-- .../Unix/Modules/Databases/CosmosDbFixture.cs | 2 +- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs b/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs index ef73f5b08..cd06c878a 100644 --- a/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs +++ b/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs @@ -1,27 +1,29 @@ namespace DotNet.Testcontainers.Builders { - using DotNet.Testcontainers.Configurations; - using DotNet.Testcontainers.Containers; - using JetBrains.Annotations; + using System.Linq; + using DotNet.Testcontainers.Configurations; + using DotNet.Testcontainers.Containers; + using JetBrains.Annotations; - [PublicAPI] - public static class TestcontainersBuilderCosmosDbExtension + [PublicAPI] + public static class TestcontainersBuilderCosmosDbExtension + { + public static ITestcontainersBuilder WithCosmosDb( + this ITestcontainersBuilder builder, CosmosDbTestcontainerConfiguration configuration) { - public static ITestcontainersBuilder WithCosmosDb( - this ITestcontainersBuilder builder, CosmosDbTestcontainerConfiguration configuration) + builder = configuration.Environments.Aggregate(builder, (current, environment) + => current.WithEnvironment(environment.Key, environment.Value)); + + return builder.WithImage(configuration.Image) + .WithPortBinding(configuration.DefaultPort, true) + .WithExposedPort(configuration.DefaultPort) + .WithWaitStrategy(configuration.WaitStrategy) + .WithOutputConsumer(configuration.OutputConsumer) + .ConfigureContainer(testcontainer => { - return builder.WithImage(configuration.Image) - .WithPortBinding(configuration.DefaultPort, true) - .WithExposedPort(configuration.DefaultPort) - .WithWaitStrategy(configuration.WaitStrategy) - .WithOutputConsumer(configuration.OutputConsumer) - .WithEnvironment("AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE", "false") - .WithEnvironment("AZURE_COSMOS_EMULATOR_PARTITION_COUNT", "1") - .ConfigureContainer(testcontainer => - { - testcontainer.ContainerPort = configuration.DefaultPort; - testcontainer.Password = configuration.Password; - }); - } + testcontainer.ContainerPort = configuration.DefaultPort; + testcontainer.Password = configuration.Password; + }); } + } } diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index 7f070e476..1eb6f5c87 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -1,7 +1,10 @@ namespace DotNet.Testcontainers.Containers { using System; + using System.Linq; + using System.Net; using System.Net.Http; + using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using DotNet.Testcontainers.Configurations; @@ -14,13 +17,13 @@ internal CosmosDbTestcontainer(ITestcontainersConfiguration configuration, ILogg { } + public HttpClientHandler HttpClientHandler => new HttpClientHandler { ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true, }; + public HttpClient HttpClient { get { - var httpMessageHandler = new HttpClientHandler { ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true, }; - - return new HttpClient(new UrlRewriter(this.Hostname, this.Port, httpMessageHandler)); + return new HttpClient(new UrlRewriter(this.Hostname, this.Port, HttpClientHandler)); } } diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index f91fcaf23..f3cfc8480 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -29,7 +29,7 @@ private CosmosDbFixture(CosmosDbTestcontainerConfiguration configuration) public override async Task InitializeAsync() { // workaround for broken cosmosdb emulator - var maxWait = TimeSpan.FromSeconds(5); + var maxWait = TimeSpan.FromSeconds(5 * 1000); var cancellationTokenSource = new CancellationTokenSource(); var containerTask = this.Container.StartAsync(cancellationTokenSource.Token); var task = await Task.WhenAny(new[] { containerTask, Task.Delay(maxWait) }); From ad4c50755042cae0f65a6130d86c8882ed08bc79 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Mon, 26 Sep 2022 08:31:17 +0200 Subject: [PATCH 34/38] expose HttpMessageHandler --- .../Containers/Modules/Databases/CosmosDbTestcontainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index 1eb6f5c87..13a32971b 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -17,13 +17,13 @@ internal CosmosDbTestcontainer(ITestcontainersConfiguration configuration, ILogg { } - public HttpClientHandler HttpClientHandler => new HttpClientHandler { ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true, }; + public HttpMessageHandler HttpMessageHandler => new UrlRewriter(this.Hostname, this.Port, new HttpClientHandler { ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true, }); public HttpClient HttpClient { get { - return new HttpClient(new UrlRewriter(this.Hostname, this.Port, HttpClientHandler)); + return new HttpClient(this.HttpMessageHandler); } } From 297df85304295e4b2d83c829cc29342f9794b4c0 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Sun, 2 Oct 2022 08:25:52 +0200 Subject: [PATCH 35/38] review fixes --- .../TestcontainersBuilderCosmosDbExtension.cs | 29 ------------ .../CosmosDbTestcontainerConfiguration.cs | 13 +++--- .../Databases/CosmosDbTestcontainer.cs | 31 +++++++------ .../Unix/Modules/Databases/CosmosDbFixture.cs | 44 ++++++------------- .../Databases/CosmosDbTestcontainerTest.cs | 35 ++++++++++----- 5 files changed, 61 insertions(+), 91 deletions(-) delete mode 100644 src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs diff --git a/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs b/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs deleted file mode 100644 index cd06c878a..000000000 --- a/src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace DotNet.Testcontainers.Builders -{ - using System.Linq; - using DotNet.Testcontainers.Configurations; - using DotNet.Testcontainers.Containers; - using JetBrains.Annotations; - - [PublicAPI] - public static class TestcontainersBuilderCosmosDbExtension - { - public static ITestcontainersBuilder WithCosmosDb( - this ITestcontainersBuilder builder, CosmosDbTestcontainerConfiguration configuration) - { - builder = configuration.Environments.Aggregate(builder, (current, environment) - => current.WithEnvironment(environment.Key, environment.Value)); - - return builder.WithImage(configuration.Image) - .WithPortBinding(configuration.DefaultPort, true) - .WithExposedPort(configuration.DefaultPort) - .WithWaitStrategy(configuration.WaitStrategy) - .WithOutputConsumer(configuration.OutputConsumer) - .ConfigureContainer(testcontainer => - { - testcontainer.ContainerPort = configuration.DefaultPort; - testcontainer.Password = configuration.Password; - }); - } - } -} diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs index d42bf4084..b6b6e9757 100644 --- a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -7,7 +7,7 @@ namespace DotNet.Testcontainers.Configurations using JetBrains.Annotations; [PublicAPI] - public class CosmosDbTestcontainerConfiguration : TestcontainerDatabaseConfiguration + public sealed class CosmosDbTestcontainerConfiguration : TestcontainerDatabaseConfiguration { public const string DefaultCosmosDbApiImage = "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator"; @@ -17,14 +17,15 @@ public class CosmosDbTestcontainerConfiguration : TestcontainerDatabaseConfigura public CosmosDbTestcontainerConfiguration() : this(DefaultCosmosDbApiImage) { - this.OutputConsumer = Consume.RedirectStdoutAndStderrToStream(new MemoryStream(), new MemoryStream()); } public CosmosDbTestcontainerConfiguration(string image) : base(image, DefaultCosmosPort) { - this.PartitionCount = 1; + this.PartitionCount = 2; this.IpAddressOverride = "127.0.0.1"; + this.OutputConsumer = Consume.RedirectStdoutAndStderrToStream(new MemoryStream(), new MemoryStream()); + this.Database = "default"; } public override IOutputConsumer OutputConsumer { get; } @@ -47,14 +48,14 @@ public override string Database public int PartitionCount { - get => int.Parse(this.Environments["AZURE_COSMOS_EMULATOR_PARTITION_COUNT"], CultureInfo.InvariantCulture); + get => int.TryParse(this.Environments["AZURE_COSMOS_EMULATOR_PARTITION_COUNT"], NumberStyles.Integer, CultureInfo.InvariantCulture, out var partitionCount) ? partitionCount : 1; set => this.Environments["AZURE_COSMOS_EMULATOR_PARTITION_COUNT"] = value.ToString(CultureInfo.InvariantCulture); } public bool EnableDataPersistence { - get => this.Environments["AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE"] == "true"; - set => this.Environments["AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE"] = value.ToString().ToLower(CultureInfo.InvariantCulture); + get => bool.TryParse(this.Environments["AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE"], out var enableDataPersistence) && enableDataPersistence; + set => this.Environments["AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE"] = value.ToString().ToLowerInvariant(); } public string IpAddressOverride diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index 13a32971b..049be53de 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -1,15 +1,14 @@ namespace DotNet.Testcontainers.Containers { using System; - using System.Linq; - using System.Net; using System.Net.Http; - using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using DotNet.Testcontainers.Configurations; + using JetBrains.Annotations; using Microsoft.Extensions.Logging; + [PublicAPI] public sealed class CosmosDbTestcontainer : TestcontainerDatabase { internal CosmosDbTestcontainer(ITestcontainersConfiguration configuration, ILogger logger) @@ -17,36 +16,36 @@ internal CosmosDbTestcontainer(ITestcontainersConfiguration configuration, ILogg { } - public HttpMessageHandler HttpMessageHandler => new UrlRewriter(this.Hostname, this.Port, new HttpClientHandler { ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true, }); + public HttpMessageHandler HttpMessageHandler => new UriRewriter(this.Hostname, this.Port); public HttpClient HttpClient { get { - return new HttpClient(this.HttpMessageHandler); + return new HttpClient(new UriRewriter(this.Hostname, this.Port)); } } public override string ConnectionString => $"AccountEndpoint=https://{this.Hostname}:{this.Port};AccountKey={this.Password}"; - private class UrlRewriter : DelegatingHandler + private sealed class UriRewriter : DelegatingHandler { - private readonly string host; - private readonly int portNumber; + private readonly string hostname; - internal UrlRewriter(string host, int portNumber, HttpMessageHandler innerHandler) - : base(innerHandler) + private readonly int port; + + public UriRewriter(string hostname, int port) + : base(new HttpClientHandler { ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true }) { - this.host = host; - this.portNumber = portNumber; + this.hostname = hostname; + this.port = port; } - protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { - request.RequestUri = new Uri($"https://{this.host}:{this.portNumber}{request.RequestUri?.PathAndQuery}"); - var response = await base.SendAsync(request, cancellationToken); - return response; + request.RequestUri = new UriBuilder("https", this.hostname, this.port, request.RequestUri.PathAndQuery).Uri; + return base.SendAsync(request, cancellationToken); } } } diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs index f3cfc8480..71d96668e 100644 --- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs +++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs @@ -2,57 +2,41 @@ namespace DotNet.Testcontainers.Tests.Fixtures { using System; using System.Data.Common; - using System.IO; using System.Threading; using System.Threading.Tasks; using DotNet.Testcontainers.Builders; using DotNet.Testcontainers.Configurations; using DotNet.Testcontainers.Containers; + using JetBrains.Annotations; + using Microsoft.Azure.Cosmos; - public class CosmosDbFixture : DatabaseFixture + [UsedImplicitly] + public sealed class CosmosDbFixture : DatabaseFixture { - public CosmosDbFixture() - : this(new CosmosDbTestcontainerConfiguration()) - { - } + private readonly CosmosDbTestcontainerConfiguration configuration = new CosmosDbTestcontainerConfiguration(); + + private readonly CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromMinutes(5)); - private CosmosDbFixture(CosmosDbTestcontainerConfiguration configuration) + public CosmosDbFixture() { - this.Configuration = configuration; this.Container = new TestcontainersBuilder() - .WithCosmosDb(configuration) + .WithDatabase(this.configuration) .Build(); } - public CosmosDbTestcontainerConfiguration Configuration { get; set; } - - public override async Task InitializeAsync() + public override Task InitializeAsync() { - // workaround for broken cosmosdb emulator - var maxWait = TimeSpan.FromSeconds(5 * 1000); - var cancellationTokenSource = new CancellationTokenSource(); - var containerTask = this.Container.StartAsync(cancellationTokenSource.Token); - var task = await Task.WhenAny(new[] { containerTask, Task.Delay(maxWait) }); - if (task != containerTask) - { - cancellationTokenSource.Cancel(); - } + return this.Container.StartAsync(this.cts.Token); } - public override async Task DisposeAsync() + public override Task DisposeAsync() { - if (this.Connection != null && this.Connection.State != System.Data.ConnectionState.Closed) - { - this.Connection.Dispose(); - } - - await this.Container.DisposeAsync() - .ConfigureAwait(false); + return this.Container.DisposeAsync().AsTask(); } public override void Dispose() { - this.Configuration.Dispose(); + this.configuration.Dispose(); } } } diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index ceee1efec..8021510bc 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -1,6 +1,8 @@ namespace DotNet.Testcontainers.Tests.Unit { + using System; using System.Net; + using System.Net.Http; using System.Threading.Tasks; using DotNet.Testcontainers.Tests.Fixtures; using Microsoft.Azure.Cosmos; @@ -9,33 +11,46 @@ namespace DotNet.Testcontainers.Tests.Unit public static class CosmosDbTestcontainerTest { [Collection(nameof(Testcontainers))] - public sealed class ConnectionTests : IClassFixture + public sealed class ConnectionTests : IClassFixture, IDisposable { - private readonly CosmosDbFixture fixture; + private readonly HttpClient httpClient; - public ConnectionTests(CosmosDbFixture fixture) + private readonly CosmosClient cosmosClient; + + public ConnectionTests(CosmosDbFixture cosmosDbFixture) + : this(cosmosDbFixture.Container.HttpClient, cosmosDbFixture.Container.ConnectionString) { - this.fixture = fixture; } - private CosmosClientOptions Options => new CosmosClientOptions { HttpClientFactory = () => this.fixture.Container.HttpClient, ConnectionMode = ConnectionMode.Gateway, }; + private ConnectionTests(HttpClient httpClient, string connectionString) + { + var cosmosClientOptions = new CosmosClientOptions { ConnectionMode = ConnectionMode.Gateway, HttpClientFactory = () => httpClient }; + this.httpClient = httpClient; + this.cosmosClient = new CosmosClient(connectionString, cosmosClientOptions); + } [Fact(Skip = "Waiting for a working cosmosdb emulator")] public async Task ShouldEstablishConnection() { - var client = new CosmosClient(this.fixture.Container.ConnectionString, this.Options); + var accountProperties = await this.cosmosClient.ReadAccountAsync() + .ConfigureAwait(false); - var accountProperties = await client.ReadAccountAsync(); Assert.Equal("localhost", accountProperties.Id); } [Fact(Skip = "Waiting for a working cosmosdb emulator")] public async Task CreateDatabaseTest() { - var client = new CosmosClient(this.fixture.Container.ConnectionString, this.Options); + var databaseResponse = await this.cosmosClient.CreateDatabaseIfNotExistsAsync("db") + .ConfigureAwait(false); - var db = await client.CreateDatabaseIfNotExistsAsync("test-db"); - Assert.Equal(HttpStatusCode.Created, db.StatusCode); + Assert.Equal(HttpStatusCode.Created, databaseResponse.StatusCode); + } + + public void Dispose() + { + this.cosmosClient.Dispose(); + this.httpClient.Dispose(); } } } From b5444ee91a4cb405737b083fde8c8c2b02f172fc Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Mon, 3 Oct 2022 19:31:39 +0200 Subject: [PATCH 36/38] create waitstrategy in constructor --- .../Modules/Databases/CosmosDbTestcontainerConfiguration.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs index b6b6e9757..4a37e36ba 100644 --- a/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs +++ b/src/Testcontainers/Configurations/Modules/Databases/CosmosDbTestcontainerConfiguration.cs @@ -26,11 +26,12 @@ public CosmosDbTestcontainerConfiguration(string image) this.IpAddressOverride = "127.0.0.1"; this.OutputConsumer = Consume.RedirectStdoutAndStderrToStream(new MemoryStream(), new MemoryStream()); this.Database = "default"; + this.WaitStrategy = Wait.ForUnixContainer().UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started|Shutting"); } public override IOutputConsumer OutputConsumer { get; } - public override IWaitForContainerOS WaitStrategy => Wait.ForUnixContainer().UntilMessageIsLogged(this.OutputConsumer.Stdout, "Started|Shutting"); + public override IWaitForContainerOS WaitStrategy { get; } public override string Password { From 44687bf8be8e4538cf26d5ca76d5ffb2500a223c Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Mon, 3 Oct 2022 19:43:29 +0200 Subject: [PATCH 37/38] ref cosmosdb emulator bug --- .../Unix/Modules/Databases/CosmosDbTestcontainerTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs index 8021510bc..e2bdeac1d 100644 --- a/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs +++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases/CosmosDbTestcontainerTest.cs @@ -29,7 +29,7 @@ private ConnectionTests(HttpClient httpClient, string connectionString) this.cosmosClient = new CosmosClient(connectionString, cosmosClientOptions); } - [Fact(Skip = "Waiting for a working cosmosdb emulator")] + [Fact(Skip = "Waiting for a working cosmosdb emulator, https://github.com/Azure/azure-cosmos-db-emulator-docker/issues/45")] public async Task ShouldEstablishConnection() { var accountProperties = await this.cosmosClient.ReadAccountAsync() @@ -38,7 +38,7 @@ public async Task ShouldEstablishConnection() Assert.Equal("localhost", accountProperties.Id); } - [Fact(Skip = "Waiting for a working cosmosdb emulator")] + [Fact(Skip = "Waiting for a working cosmosdb emulator, see https://github.com/Azure/azure-cosmos-db-emulator-docker/issues/45")] public async Task CreateDatabaseTest() { var databaseResponse = await this.cosmosClient.CreateDatabaseIfNotExistsAsync("db") From a9d0151a9034a19c99f8caa14b7c2c5e688b2b86 Mon Sep 17 00:00:00 2001 From: Tommy Alander Date: Mon, 3 Oct 2022 20:07:23 +0200 Subject: [PATCH 38/38] cleanup --- .../Containers/Modules/Databases/CosmosDbTestcontainer.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs index 049be53de..05e2c20c4 100644 --- a/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs +++ b/src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs @@ -18,13 +18,7 @@ internal CosmosDbTestcontainer(ITestcontainersConfiguration configuration, ILogg public HttpMessageHandler HttpMessageHandler => new UriRewriter(this.Hostname, this.Port); - public HttpClient HttpClient - { - get - { - return new HttpClient(new UriRewriter(this.Hostname, this.Port)); - } - } + public HttpClient HttpClient => new HttpClient(this.HttpMessageHandler); public override string ConnectionString => $"AccountEndpoint=https://{this.Hostname}:{this.Port};AccountKey={this.Password}";