Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/Testcontainers.MongoDb/MongoDbBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,11 @@ private static async Task InitiateReplicaSetAsync(MongoDbContainer container, Mo
// with custom configurations as needed.
var options = new WaitStrategy();

var scriptContent = $"var r=rs.initiate({{_id:\"{configuration.ReplicaSetName}\",members:[{{_id:0,host:\"127.0.0.1:27017\"}}]}});quit(r.ok===1?0:1);";
// The startup callback runs on every start, so a container that is restarted or reused
// already holds an initiated replica set. Initiating it again throws instead of returning
// a result, which would otherwise be retried until the wait strategy times out:
// https://github.com/testcontainers/testcontainers-dotnet/issues/1722.
var scriptContent = $"try{{var r=rs.initiate({{_id:\"{configuration.ReplicaSetName}\",members:[{{_id:0,host:\"127.0.0.1:27017\"}}]}});quit(r.ok===1?0:1);}}catch(e){{quit(e.codeName===\"AlreadyInitialized\"?0:1);}}";

var initiate = async () =>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
namespace Testcontainers.MongoDb;

/// <summary>
/// Reusing a container runs the startup callback again against a replica set that is already
/// initiated (https://github.com/testcontainers/testcontainers-dotnet/issues/1722).
/// </summary>
public sealed class MongoDbReplicaSetReuseTest : IAsyncLifetime
{
private readonly string _labelKey = Guid.NewGuid().ToString("D");

private readonly string _labelValue = Guid.NewGuid().ToString("D");

private readonly IList<MongoDbContainer> _containers = new List<MongoDbContainer>();

public ValueTask InitializeAsync()
{
return ValueTask.CompletedTask;
}

public async ValueTask DisposeAsync()
{
foreach (var container in _containers.Distinct())
{
await container.DisposeAsync()
.ConfigureAwait(false);
}

GC.SuppressFinalize(this);
}

[Fact]
[Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))]
public async Task ReusedContainerStartsAgain()
{
// Given
// The default wait strategy timeout is one hour, so bound the wait to keep a regression
// from hanging the test run instead of failing it.
using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3));

var container = CreateContainer();
_containers.Add(container);

await container.StartAsync(cts.Token)
.ConfigureAwait(true);

// When
var reusedContainer = CreateContainer();
_containers.Add(reusedContainer);

await reusedContainer.StartAsync(cts.Token)
.ConfigureAwait(true);

// Then
Assert.Equal(container.Id, reusedContainer.Id);

const string scriptContent = "rs.status().ok;";

var execResult = await reusedContainer.ExecScriptAsync(scriptContent, cts.Token)
.ConfigureAwait(true);

Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
}

private MongoDbContainer CreateContainer()
{
return new MongoDbBuilder(TestSession.GetImageFromDockerfile())
.WithReplicaSet()
.WithLabel(_labelKey, _labelValue)
.WithReuse(true)
.Build();
}
}
3 changes: 3 additions & 0 deletions tests/Testcontainers.MongoDb.Tests/Usings.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading;
global using System.Threading.Tasks;
global using DotNet.Testcontainers.Commons;
global using DotNet.Testcontainers.Configurations;
Expand Down
Loading