-
-
Notifications
You must be signed in to change notification settings - Fork 288
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Restructure to model Azurite testcontainer
- Loading branch information
Showing
7 changed files
with
185 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
src/Testcontainers/Builders/TestcontainersBuilderCosmosDbExtension.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<CosmosDbTestcontainer> WithCosmosDb( | ||
this ITestcontainersBuilder<CosmosDbTestcontainer> builder, CosmosDbTestcontainerConfiguration configuration) | ||
{ | ||
builder.WithImage(configuration.Image) | ||
.WithWaitStrategy(configuration.WaitStrategy) | ||
.WithExposedPort(configuration.SqlApiContainerPort) | ||
.WithPortBinding(configuration.SqlApiPort); | ||
|
||
return builder; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 17 additions & 91 deletions
108
src/Testcontainers/Containers/Modules/Databases/CosmosDbTestcontainer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<HttpResponseMessage> QueryAsync( | ||
string queryString, IEnumerable<KeyValuePair<string, string>> 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<HttpResponseMessage> 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<HttpResponseMessage> 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}"; | ||
} | ||
} |
93 changes: 48 additions & 45 deletions
93
tests/Testcontainers.Tests/Fixtures/Containers/Unix/Modules/Databases/CosmosDbFixture.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<CosmosDbTestcontainer, DbConnection> | ||
public static class CosmosDbFixture | ||
{ | ||
private readonly TestcontainerDatabaseConfiguration configuration = new CosmosDbTestcontainerConfiguration | ||
[UsedImplicitly] | ||
public class CosmosDbDefaultFixture : DatabaseFixture<CosmosDbTestcontainer, DbConnection> | ||
{ | ||
Database = "testdb" | ||
}; | ||
|
||
public CosmosDbFixture() | ||
{ | ||
this.Container = new TestcontainersBuilder<CosmosDbTestcontainer>() | ||
.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<CosmosDbTestcontainer>() | ||
.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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.