Skip to content

Commit 8fef3bb

Browse files
authored
feat: Replace Azurite module (#871)
1 parent 29c6180 commit 8fef3bb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+408
-1122
lines changed

Packages.props

-4
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,5 @@
1414
<PackageReference Update="coverlet.collector" Version="3.2.0" />
1515
<PackageReference Update="xunit.runner.visualstudio" Version="2.4.5" />
1616
<PackageReference Update="xunit" Version="2.4.2" />
17-
<!-- 3rd party client dependencies -->
18-
<PackageReference Update="Azure.Data.Tables" Version="12.6.1" />
19-
<PackageReference Update="Azure.Storage.Blobs" Version="12.13.0" />
20-
<PackageReference Update="Azure.Storage.Queues" Version="12.11.0" />
2117
</ItemGroup>
2218
</Project>

Testcontainers.sln

+14
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{673F23AE-769
1313
EndProject
1414
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}"
1515
EndProject
16+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Azurite", "src\Testcontainers.Azurite\Testcontainers.Azurite.csproj", "{3F2E254F-C203-43FD-A078-DC3E2CBC0F9F}"
17+
EndProject
1618
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.CosmosDb", "src\Testcontainers.CosmosDb\Testcontainers.CosmosDb.csproj", "{A724806F-8C94-4438-8011-04A9A1575318}"
1719
EndProject
1820
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Couchbase", "src\Testcontainers.Couchbase\Testcontainers.Couchbase.csproj", "{58E94721-2681-4D82-8D94-0B2F9DB0D575}"
@@ -61,6 +63,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.WebDriver",
6163
EndProject
6264
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers", "src\Testcontainers\Testcontainers.csproj", "{EC76857B-A3B8-4B7A-A1B0-8D867A4D1733}"
6365
EndProject
66+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Azurite.Tests", "tests\Testcontainers.Azurite.Tests\Testcontainers.Azurite.Tests.csproj", "{B272FDDE-5E01-425D-B9E1-10FF883DDAAA}"
67+
EndProject
6468
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Commons", "tests\Testcontainers.Commons\Testcontainers.Commons.csproj", "{2478673C-B063-469D-ABD1-0C3E0A25541B}"
6569
EndProject
6670
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.CosmosDb.Tests", "tests\Testcontainers.CosmosDb.Tests\Testcontainers.CosmosDb.Tests.csproj", "{BD445A54-F411-4758-955E-397A1E98680C}"
@@ -126,6 +130,10 @@ Global
126130
HideSolutionNode = FALSE
127131
EndGlobalSection
128132
GlobalSection(ProjectConfigurationPlatforms) = postSolution
133+
{3F2E254F-C203-43FD-A078-DC3E2CBC0F9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
134+
{3F2E254F-C203-43FD-A078-DC3E2CBC0F9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
135+
{3F2E254F-C203-43FD-A078-DC3E2CBC0F9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
136+
{3F2E254F-C203-43FD-A078-DC3E2CBC0F9F}.Release|Any CPU.Build.0 = Release|Any CPU
129137
{A724806F-8C94-4438-8011-04A9A1575318}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
130138
{A724806F-8C94-4438-8011-04A9A1575318}.Debug|Any CPU.Build.0 = Debug|Any CPU
131139
{A724806F-8C94-4438-8011-04A9A1575318}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -222,6 +230,10 @@ Global
222230
{EC76857B-A3B8-4B7A-A1B0-8D867A4D1733}.Debug|Any CPU.Build.0 = Debug|Any CPU
223231
{EC76857B-A3B8-4B7A-A1B0-8D867A4D1733}.Release|Any CPU.ActiveCfg = Release|Any CPU
224232
{EC76857B-A3B8-4B7A-A1B0-8D867A4D1733}.Release|Any CPU.Build.0 = Release|Any CPU
233+
{B272FDDE-5E01-425D-B9E1-10FF883DDAAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
234+
{B272FDDE-5E01-425D-B9E1-10FF883DDAAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
235+
{B272FDDE-5E01-425D-B9E1-10FF883DDAAA}.Release|Any CPU.ActiveCfg = Release|Any CPU
236+
{B272FDDE-5E01-425D-B9E1-10FF883DDAAA}.Release|Any CPU.Build.0 = Release|Any CPU
225237
{2478673C-B063-469D-ABD1-0C3E0A25541B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
226238
{2478673C-B063-469D-ABD1-0C3E0A25541B}.Debug|Any CPU.Build.0 = Debug|Any CPU
227239
{2478673C-B063-469D-ABD1-0C3E0A25541B}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -336,6 +348,7 @@ Global
336348
{EBA72C3B-57D5-43FF-A5B4-3D55B3B6D4C2}.Release|Any CPU.Build.0 = Release|Any CPU
337349
EndGlobalSection
338350
GlobalSection(NestedProjects) = preSolution
351+
{3F2E254F-C203-43FD-A078-DC3E2CBC0F9F} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
339352
{A724806F-8C94-4438-8011-04A9A1575318} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
340353
{58E94721-2681-4D82-8D94-0B2F9DB0D575} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
341354
{DCECB1F6-D9AA-431F-AE42-25D56B9E7DFC} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
@@ -360,6 +373,7 @@ Global
360373
{C95A3B2F-2B28-49A7-8806-731C158BBC21} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
361374
{64A87DE5-29B0-4A54-9E74-560484D8C7C0} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
362375
{EC76857B-A3B8-4B7A-A1B0-8D867A4D1733} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
376+
{B272FDDE-5E01-425D-B9E1-10FF883DDAAA} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
363377
{2478673C-B063-469D-ABD1-0C3E0A25541B} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
364378
{BD445A54-F411-4758-955E-397A1E98680C} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
365379
{809322BA-D690-4F2B-B884-23F895663963} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
root = true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
namespace Testcontainers.Azurite;
2+
3+
/// <inheritdoc cref="ContainerBuilder{TBuilderEntity, TContainerEntity, TConfigurationEntity}" />
4+
[PublicAPI]
5+
public sealed class AzuriteBuilder : ContainerBuilder<AzuriteBuilder, AzuriteContainer, AzuriteConfiguration>
6+
{
7+
public const string AzuriteImage = "mcr.microsoft.com/azure-storage/azurite:3.23.0";
8+
9+
public const ushort BlobPort = 10000;
10+
11+
public const ushort QueuePort = 10001;
12+
13+
public const ushort TablePort = 10002;
14+
15+
private readonly ISet<AzuriteService> _enabledServices = new HashSet<AzuriteService>();
16+
17+
/// <summary>
18+
/// Initializes a new instance of the <see cref="AzuriteBuilder" /> class.
19+
/// </summary>
20+
public AzuriteBuilder()
21+
: this(new AzuriteConfiguration())
22+
{
23+
DockerResourceConfiguration = Init().DockerResourceConfiguration;
24+
25+
_enabledServices.Add(AzuriteService.Blob);
26+
_enabledServices.Add(AzuriteService.Queue);
27+
_enabledServices.Add(AzuriteService.Table);
28+
}
29+
30+
/// <summary>
31+
/// Initializes a new instance of the <see cref="AzuriteBuilder" /> class.
32+
/// </summary>
33+
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
34+
private AzuriteBuilder(AzuriteConfiguration resourceConfiguration)
35+
: base(resourceConfiguration)
36+
{
37+
DockerResourceConfiguration = resourceConfiguration;
38+
}
39+
40+
/// <inheritdoc />
41+
protected override AzuriteConfiguration DockerResourceConfiguration { get; }
42+
43+
/// <inheritdoc />
44+
public override AzuriteContainer Build()
45+
{
46+
Validate();
47+
48+
var waitStrategy = Wait.ForUnixContainer();
49+
50+
if (_enabledServices.Contains(AzuriteService.Blob))
51+
{
52+
waitStrategy = waitStrategy.UntilMessageIsLogged("Blob service is successfully listening");
53+
}
54+
55+
if (_enabledServices.Contains(AzuriteService.Queue))
56+
{
57+
waitStrategy = waitStrategy.UntilMessageIsLogged("Queue service is successfully listening");
58+
}
59+
60+
if (_enabledServices.Contains(AzuriteService.Table))
61+
{
62+
waitStrategy = waitStrategy.UntilMessageIsLogged("Table service is successfully listening");
63+
}
64+
65+
var azuriteBuilder = DockerResourceConfiguration.WaitStrategies.Count() > 1 ? this : WithWaitStrategy(waitStrategy);
66+
return new AzuriteContainer(azuriteBuilder.DockerResourceConfiguration, TestcontainersSettings.Logger);
67+
}
68+
69+
/// <inheritdoc />
70+
protected override AzuriteBuilder Init()
71+
{
72+
return base.Init()
73+
.WithImage(AzuriteImage)
74+
.WithPortBinding(BlobPort, true)
75+
.WithPortBinding(QueuePort, true)
76+
.WithPortBinding(TablePort, true);
77+
}
78+
79+
/// <inheritdoc />
80+
protected override AzuriteBuilder Clone(IResourceConfiguration<CreateContainerParameters> resourceConfiguration)
81+
{
82+
return Merge(DockerResourceConfiguration, new AzuriteConfiguration(resourceConfiguration));
83+
}
84+
85+
/// <inheritdoc />
86+
protected override AzuriteBuilder Clone(IContainerConfiguration resourceConfiguration)
87+
{
88+
return Merge(DockerResourceConfiguration, new AzuriteConfiguration(resourceConfiguration));
89+
}
90+
91+
/// <inheritdoc />
92+
protected override AzuriteBuilder Merge(AzuriteConfiguration oldValue, AzuriteConfiguration newValue)
93+
{
94+
return new AzuriteBuilder(new AzuriteConfiguration(oldValue, newValue));
95+
}
96+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
namespace Testcontainers.Azurite;
2+
3+
/// <inheritdoc cref="ContainerConfiguration" />
4+
[PublicAPI]
5+
public sealed class AzuriteConfiguration : ContainerConfiguration
6+
{
7+
/// <summary>
8+
/// Initializes a new instance of the <see cref="AzuriteConfiguration" /> class.
9+
/// </summary>
10+
public AzuriteConfiguration()
11+
{
12+
}
13+
14+
/// <summary>
15+
/// Initializes a new instance of the <see cref="AzuriteConfiguration" /> class.
16+
/// </summary>
17+
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
18+
public AzuriteConfiguration(IResourceConfiguration<CreateContainerParameters> resourceConfiguration)
19+
: base(resourceConfiguration)
20+
{
21+
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
22+
}
23+
24+
/// <summary>
25+
/// Initializes a new instance of the <see cref="AzuriteConfiguration" /> class.
26+
/// </summary>
27+
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
28+
public AzuriteConfiguration(IContainerConfiguration resourceConfiguration)
29+
: base(resourceConfiguration)
30+
{
31+
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
32+
}
33+
34+
/// <summary>
35+
/// Initializes a new instance of the <see cref="AzuriteConfiguration" /> class.
36+
/// </summary>
37+
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
38+
public AzuriteConfiguration(AzuriteConfiguration resourceConfiguration)
39+
: this(new AzuriteConfiguration(), resourceConfiguration)
40+
{
41+
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
42+
}
43+
44+
/// <summary>
45+
/// Initializes a new instance of the <see cref="AzuriteConfiguration" /> class.
46+
/// </summary>
47+
/// <param name="oldValue">The old Docker resource configuration.</param>
48+
/// <param name="newValue">The new Docker resource configuration.</param>
49+
public AzuriteConfiguration(AzuriteConfiguration oldValue, AzuriteConfiguration newValue)
50+
: base(oldValue, newValue)
51+
{
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
namespace Testcontainers.Azurite;
2+
3+
/// <inheritdoc cref="DockerContainer" />
4+
[PublicAPI]
5+
public sealed class AzuriteContainer : DockerContainer
6+
{
7+
private const string AccountName = "devstoreaccount1";
8+
9+
private const string AccountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
10+
11+
/// <summary>
12+
/// Initializes a new instance of the <see cref="AzuriteContainer" /> class.
13+
/// </summary>
14+
/// <param name="configuration">The container configuration.</param>
15+
/// <param name="logger">The logger.</param>
16+
public AzuriteContainer(AzuriteConfiguration configuration, ILogger logger)
17+
: base(configuration, logger)
18+
{
19+
}
20+
21+
/// <summary>
22+
/// Gets the Azurite connection string.
23+
/// </summary>
24+
/// <returns>The Azurite connection string.</returns>
25+
public string GetConnectionString()
26+
{
27+
var properties = new Dictionary<string, string>();
28+
properties.Add("DefaultEndpointsProtocol", Uri.UriSchemeHttp);
29+
properties.Add("AccountName", AccountName);
30+
properties.Add("AccountKey", AccountKey);
31+
properties.Add("BlobEndpoint", new UriBuilder(Uri.UriSchemeHttp, Hostname, GetMappedPublicPort(AzuriteBuilder.BlobPort), AccountName).ToString());
32+
properties.Add("QueueEndpoint", new UriBuilder(Uri.UriSchemeHttp, Hostname, GetMappedPublicPort(AzuriteBuilder.QueuePort), AccountName).ToString());
33+
properties.Add("TableEndpoint", new UriBuilder(Uri.UriSchemeHttp, Hostname, GetMappedPublicPort(AzuriteBuilder.TablePort), AccountName).ToString());
34+
return string.Join(";", properties.Select(property => string.Join("=", property.Key, property.Value)));
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
namespace Testcontainers.Azurite;
2+
3+
/// <summary>
4+
/// An Azurite service.
5+
/// </summary>
6+
internal readonly struct AzuriteService
7+
{
8+
/// <summary>
9+
/// Gets the Blob service.
10+
/// </summary>
11+
public static readonly AzuriteService Blob = new AzuriteService("blob");
12+
13+
/// <summary>
14+
/// Gets the Queue service.
15+
/// </summary>
16+
public static readonly AzuriteService Queue = new AzuriteService("queue");
17+
18+
/// <summary>
19+
/// Gets the Table service.
20+
/// </summary>
21+
public static readonly AzuriteService Table = new AzuriteService("table");
22+
23+
/// <summary>
24+
/// Initializes a new instance of the <see cref="AzuriteService" /> struct.
25+
/// </summary>
26+
/// <param name="identifier">The identifier.</param>
27+
private AzuriteService(string identifier)
28+
{
29+
_ = identifier;
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
4+
<LangVersion>latest</LangVersion>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All"/>
8+
<PackageReference Include="JetBrains.Annotations" Version="2022.3.1" PrivateAssets="All"/>
9+
</ItemGroup>
10+
<ItemGroup>
11+
<ProjectReference Include="$(SolutionDir)src/Testcontainers/Testcontainers.csproj"/>
12+
</ItemGroup>
13+
</Project>

src/Testcontainers.Azurite/Usings.cs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
global using System;
2+
global using System.Collections.Generic;
3+
global using System.Linq;
4+
global using Docker.DotNet.Models;
5+
global using DotNet.Testcontainers.Builders;
6+
global using DotNet.Testcontainers.Configurations;
7+
global using DotNet.Testcontainers.Containers;
8+
global using JetBrains.Annotations;
9+
global using Microsoft.Extensions.Logging;

src/Testcontainers.Couchbase/CouchbaseService.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,32 @@ internal readonly struct CouchbaseService
88
/// <summary>
99
/// Gets the Data service.
1010
/// </summary>
11-
public static readonly CouchbaseService Data = new("kv", 256);
11+
public static readonly CouchbaseService Data = new CouchbaseService("kv", 256);
1212

1313
/// <summary>
1414
/// Gets the Index service.
1515
/// </summary>
16-
public static readonly CouchbaseService Index = new("index", 256);
16+
public static readonly CouchbaseService Index = new CouchbaseService("index", 256);
1717

1818
/// <summary>
1919
/// Gets the Query service.
2020
/// </summary>
21-
public static readonly CouchbaseService Query = new("n1ql", 0);
21+
public static readonly CouchbaseService Query = new CouchbaseService("n1ql", 0);
2222

2323
/// <summary>
2424
/// Gets the Search service.
2525
/// </summary>
26-
public static readonly CouchbaseService Search = new("fts", 256);
26+
public static readonly CouchbaseService Search = new CouchbaseService("fts", 256);
2727

2828
/// <summary>
2929
/// Gets the Analytics service.
3030
/// </summary>
31-
public static readonly CouchbaseService Analytics = new("cbas", 1024);
31+
public static readonly CouchbaseService Analytics = new CouchbaseService("cbas", 1024);
3232

3333
/// <summary>
3434
/// Gets the Eventing service.
3535
/// </summary>
36-
public static readonly CouchbaseService Eventing = new("eventing", 256);
36+
public static readonly CouchbaseService Eventing = new CouchbaseService("eventing", 256);
3737

3838
/// <summary>
3939
/// Initializes a new instance of the <see cref="CouchbaseService" /> struct.

src/Testcontainers/BackwardCompatibility/BackwardsCompatibility.cs

-35
This file was deleted.

0 commit comments

Comments
 (0)