-
-
Notifications
You must be signed in to change notification settings - Fork 274
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
360 additions
and
0 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
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 @@ | ||
root = true |
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,108 @@ | ||
namespace Testcontainers.Nats; | ||
|
||
/// <inheritdoc cref="ContainerBuilder{TBuilderEntity, TContainerEntity, TConfigurationEntity}" /> | ||
[PublicAPI] | ||
public sealed class NatsBuilder : ContainerBuilder<NatsBuilder, NatsContainer, NatsConfiguration> | ||
{ | ||
public const string NatsImage = "nats:2.9"; | ||
|
||
public const ushort ClientPort = 4222; | ||
public const ushort RoutingPort = 6222; | ||
public const ushort MonitoringPort = 8222; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="NatsBuilder" /> class. | ||
/// </summary> | ||
public NatsBuilder() | ||
: this(new NatsConfiguration()) | ||
{ | ||
DockerResourceConfiguration = Init().DockerResourceConfiguration; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="NatsBuilder" /> class. | ||
/// </summary> | ||
/// <param name="resourceConfiguration">The Docker resource configuration.</param> | ||
private NatsBuilder(NatsConfiguration resourceConfiguration) | ||
: base(resourceConfiguration) | ||
{ | ||
DockerResourceConfiguration = resourceConfiguration; | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override NatsConfiguration DockerResourceConfiguration { get; } | ||
|
||
/// <summary> | ||
/// Sets the Nats Server password. | ||
/// </summary> | ||
/// <param name="password">The Nats Server password.</param> | ||
/// <returns>A configured instance of <see cref="NatsBuilder" />.</returns> | ||
public NatsBuilder WithPassword(string password) | ||
{ | ||
return Merge(DockerResourceConfiguration, new NatsConfiguration(password: password)) | ||
.WithCommand("-pass", password); | ||
} | ||
|
||
/// <summary> | ||
/// Sets the Nats Server username. | ||
/// </summary> | ||
/// <param name="username">The Nats Server username.</param> | ||
/// <returns>A configured instance of <see cref="NatsBuilder" />.</returns> | ||
public NatsBuilder WithUsername(string username) | ||
{ | ||
return Merge(DockerResourceConfiguration, new NatsConfiguration(username: username)) | ||
.WithCommand("-user", username); | ||
} | ||
|
||
/// <summary> | ||
/// Sets the Nats config. | ||
/// </summary> | ||
/// <param name="config">The Nats config.</param> | ||
/// <returns>A configured instance of <see cref="NatsBuilder" />.</returns> | ||
public NatsBuilder WithNatsConfig(NatsConfiguration config) | ||
{ | ||
// Extends the ContainerBuilder capabilities and holds a custom configuration in NatsConfiguration. | ||
// In case of a module requires other properties to represent itself, extend ContainerConfiguration. | ||
return Merge(DockerResourceConfiguration, new NatsConfiguration(config)); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public override NatsContainer Build() | ||
{ | ||
Validate(); | ||
return new NatsContainer(DockerResourceConfiguration, TestcontainersSettings.Logger); | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override NatsBuilder Init() | ||
{ | ||
return base.Init() | ||
.WithImage(NatsImage) | ||
.WithPortBinding(ClientPort, true) | ||
.WithPortBinding(MonitoringPort, true) | ||
.WithPortBinding(RoutingPort, true) | ||
.WithCommand("-m", MonitoringPort.ToString()) // Enable monitoring endpoint. | ||
.WithCommand("-js") // Enable JetStream functionality. | ||
.WithCommand("-DV") // Enable both debug and protocol trace messages | ||
.WithWaitStrategy(Wait.ForUnixContainer() | ||
.UntilMessageIsLogged("Listening for client connections on 0.0.0.0:4222")); | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override NatsBuilder Clone(IResourceConfiguration<CreateContainerParameters> resourceConfiguration) | ||
{ | ||
return Merge(DockerResourceConfiguration, new NatsConfiguration(resourceConfiguration)); | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override NatsBuilder Clone(IContainerConfiguration resourceConfiguration) | ||
{ | ||
return Merge(DockerResourceConfiguration, new NatsConfiguration(resourceConfiguration)); | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override NatsBuilder Merge(NatsConfiguration oldValue, NatsConfiguration newValue) | ||
{ | ||
return new NatsBuilder(new NatsConfiguration(oldValue, newValue)); | ||
} | ||
} |
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,72 @@ | ||
namespace Testcontainers.Nats; | ||
|
||
/// <inheritdoc cref="ContainerConfiguration" /> | ||
[PublicAPI] | ||
public sealed class NatsConfiguration : ContainerConfiguration | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="NatsConfiguration" /> class. | ||
/// </summary> | ||
/// <param name="username">The nats server user name.</param> | ||
/// <param name="password">The nats server password.</param> | ||
public NatsConfiguration( | ||
string username = null, | ||
string password = null) | ||
{ | ||
Username = username; | ||
Password = password; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="NatsConfiguration" /> class. | ||
/// </summary> | ||
/// <param name="resourceConfiguration">The Docker resource configuration.</param> | ||
public NatsConfiguration(IResourceConfiguration<CreateContainerParameters> resourceConfiguration) | ||
: base(resourceConfiguration) | ||
{ | ||
// Passes the configuration upwards to the base implementations to create an updated immutable copy. | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="NatsConfiguration" /> class. | ||
/// </summary> | ||
/// <param name="resourceConfiguration">The Docker resource configuration.</param> | ||
public NatsConfiguration(IContainerConfiguration resourceConfiguration) | ||
: base(resourceConfiguration) | ||
{ | ||
// Passes the configuration upwards to the base implementations to create an updated immutable copy. | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="NatsConfiguration" /> class. | ||
/// </summary> | ||
/// <param name="resourceConfiguration">The Docker resource configuration.</param> | ||
public NatsConfiguration(NatsConfiguration resourceConfiguration) | ||
: this(new NatsConfiguration(), resourceConfiguration) | ||
{ | ||
// Passes the configuration upwards to the base implementations to create an updated immutable copy. | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="NatsConfiguration" /> class. | ||
/// </summary> | ||
/// <param name="oldValue">The old Docker resource configuration.</param> | ||
/// <param name="newValue">The new Docker resource configuration.</param> | ||
public NatsConfiguration(NatsConfiguration oldValue, NatsConfiguration newValue) | ||
: base(oldValue, newValue) | ||
{ | ||
// // Create an updated immutable copy of the module configuration. | ||
Username = BuildConfiguration.Combine(oldValue.Username, newValue.Username); | ||
Password = BuildConfiguration.Combine(oldValue.Password, newValue.Password); | ||
} | ||
|
||
/// <summary> | ||
/// The nats server user name. | ||
/// </summary> | ||
public string Username { get; } | ||
|
||
/// <summary> | ||
/// The nats server password. | ||
/// </summary> | ||
public string Password { get; } | ||
} |
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,44 @@ | ||
namespace Testcontainers.Nats; | ||
|
||
/// <inheritdoc cref="DockerContainer" /> | ||
[PublicAPI] | ||
public sealed class NatsContainer : DockerContainer | ||
{ | ||
private readonly NatsConfiguration _natsConfig; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="NatsContainer" /> class. | ||
/// </summary> | ||
/// <param name="configuration">The container configuration.</param> | ||
/// <param name="logger">The logger.</param> | ||
public NatsContainer(NatsConfiguration configuration, ILogger logger) | ||
: base(configuration, logger) | ||
{ | ||
_natsConfig = configuration; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the nats connection string | ||
/// </summary> | ||
/// <returns>A nats connection string in the form: nats://hostname:mappedPort/>.</returns> | ||
/// <remarks> | ||
/// If either username or password is set, the connection string will contain the credentials. | ||
/// </remarks> | ||
public string GetConnectionString() | ||
{ | ||
return new UriBuilder("nats", Hostname, GetMappedPublicPort(NatsBuilder.ClientPort)) | ||
{ | ||
UserName = _natsConfig.Username, | ||
Password = _natsConfig.Password, | ||
}.ToString(); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the nats monitor url | ||
/// </summary> | ||
/// <returns>A url in the form: http://hostname:mappedPort/>.</returns> | ||
public string GetMonitorUrl() | ||
{ | ||
return new UriBuilder("http", Hostname, GetMappedPublicPort(NatsBuilder.MonitoringPort)).ToString(); | ||
} | ||
} |
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,13 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks> | ||
<LangVersion>latest</LangVersion> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All"/> | ||
<PackageReference Include="JetBrains.Annotations" Version="2022.3.1" PrivateAssets="All"/> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<ProjectReference Include="$(SolutionDir)src/Testcontainers/Testcontainers.csproj"/> | ||
</ItemGroup> | ||
</Project> |
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,7 @@ | ||
global using System; | ||
global using Docker.DotNet.Models; | ||
global using DotNet.Testcontainers.Builders; | ||
global using DotNet.Testcontainers.Configurations; | ||
global using DotNet.Testcontainers.Containers; | ||
global using JetBrains.Annotations; | ||
global using Microsoft.Extensions.Logging; |
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 @@ | ||
root = true |
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,75 @@ | ||
namespace Testcontainers.Nats; | ||
|
||
public sealed class NatsContainerTest : IAsyncLifetime | ||
{ | ||
private readonly NatsContainer _natsContainer = new NatsBuilder().Build(); | ||
|
||
public Task InitializeAsync() | ||
{ | ||
return _natsContainer.StartAsync(); | ||
} | ||
|
||
public Task DisposeAsync() | ||
{ | ||
return _natsContainer.DisposeAsync().AsTask(); | ||
} | ||
|
||
[Fact] | ||
[Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))] | ||
public async Task ContainerIsStartedWithCorrectParameters() | ||
{ | ||
using var client = new ConnectionFactory() | ||
.CreateConnection(_natsContainer.GetConnectionString()); | ||
|
||
Assert.Equal(ConnState.CONNECTED, client.State); | ||
Assert.True(client.ServerInfo.JetStreamAvailable); | ||
|
||
using var monitorClient = new HttpClient() | ||
{ | ||
BaseAddress = new Uri(_natsContainer.GetMonitorUrl()), | ||
}; | ||
|
||
using var response = await monitorClient.GetAsync("/healthz"); | ||
var s = await response.Content.ReadAsStringAsync(); | ||
Assert.True(response.IsSuccessStatusCode); | ||
} | ||
|
||
[Fact] | ||
[Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))] | ||
public async Task PubSubSendsAndReturnsMessages() | ||
{ | ||
using var client = new ConnectionFactory() | ||
.CreateConnection(_natsContainer.GetConnectionString()); | ||
|
||
using ISyncSubscription subSync = client.SubscribeSync("greet.pam"); | ||
client.Publish("greet.pam", Encoding.UTF8.GetBytes("hello pam 1")); | ||
|
||
var msg = subSync.NextMessage(1000); | ||
var text = Encoding.UTF8.GetString(msg.Data); | ||
|
||
|
||
Assert.Equal("hello pam 1", text); | ||
await client.DrainAsync(); | ||
} | ||
|
||
[Fact] | ||
[Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))] | ||
public async Task BuilderShouldBuildWithUserNameAndPassword() | ||
{ | ||
var builder = new NatsBuilder() | ||
.WithUsername("test") | ||
.WithPassword("testpass"); | ||
await using var container = builder.Build(); | ||
|
||
await container.StartAsync(); | ||
|
||
var uri = new Uri(container.GetConnectionString()); | ||
|
||
Assert.Equal("test:testpass", uri.UserInfo); | ||
|
||
using var client = new ConnectionFactory() | ||
.CreateConnection(_natsContainer.GetConnectionString()); | ||
|
||
Assert.Equal(ConnState.CONNECTED, client.State); | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
tests/Testcontainers.Nats.Tests/Testcontainers.Nats.Tests.csproj
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,18 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFrameworks>net6.0</TargetFrameworks> | ||
<IsPackable>false</IsPackable> | ||
<IsPublishable>false</IsPublishable> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2"/> | ||
<PackageReference Include="coverlet.collector" Version="6.0.0"/> | ||
<PackageReference Include="NATS.Client" Version="1.0.8" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0"/> | ||
<PackageReference Include="xunit" Version="2.5.0"/> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<ProjectReference Include="$(SolutionDir)src/Testcontainers.Nats/Testcontainers.Nats.csproj"/> | ||
<ProjectReference Include="$(SolutionDir)tests/Testcontainers.Commons/Testcontainers.Commons.csproj"/> | ||
</ItemGroup> | ||
</Project> |
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,7 @@ | ||
global using System; | ||
global using System.Net.Http; | ||
global using System.Text; | ||
global using System.Threading.Tasks; | ||
global using DotNet.Testcontainers.Commons; | ||
global using NATS.Client; | ||
global using Xunit; |