diff --git a/README.md b/README.md index 9b4d23fa8..d1c6de3f3 100755 --- a/README.md +++ b/README.md @@ -35,12 +35,17 @@ Keep in mind to enable the correct Docker engine on Windows host systems to matc - `WithCleanUp` removes a stopped container automatically. - `WithDockerEndpoint` sets the Docker API endpoint e. g. `-H tcp://0.0.0.0:2376`. - `WithRegistryAuthentication` basic authentication against a private Docker registry. -- `WithOutputConsumer` redirects `stdout` and `stderr` to capture the Testcontainer output. -- `WithWaitStrategy` sets the wait strategy to complete the Testcontainer start and indicates when it is ready. -- `WithStartupCallback` sets the startup callback to invoke after the Testcontainer start. +- `WithOutputConsumer` redirects `stdout` and `stderr` to capture the Testcontainers output. +- `WithWaitStrategy` sets the wait strategy to complete the Testcontainers start and indicates when it is ready. +- `WithStartupCallback` sets the startup callback to invoke after the Testcontainers start. +- `WithResourceReaperSessionId` sets the resource reaper session id. - `WithDockerfileDirectory` builds a Docker image based on a Dockerfile (`ImageFromDockerfileBuilder`). - `WithDeleteIfExists` removes the Docker image before it is rebuilt (`ImageFromDockerfileBuilder`). +## Resource Reaper + +Testcontainers assigns each Docker resource a Resource Reaper session id. After the tests are finished, [Ryuk][moby-ryuk] will take care of remaining Docker resources and removes them. You can change the Resource Reaper session and group Docker resources together with `WithResourceReaperSessionId`. Right now, only Linux containers are supported. + ## Pre-configured containers The pre-configured Testcontainers below are supported. Further examples can be found in [TestcontainersContainerTest][1] as well as in [database][2] or [message broker][3] tests. @@ -67,9 +72,9 @@ var testcontainersBuilder = new TestcontainersBuilder() .WithPortBinding(80) .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(80)); -await using (var testcontainer = testcontainersBuilder.Build()) +await using (var testcontainers = testcontainersBuilder.Build()) { - await testcontainer.StartAsync(); + await testcontainers.StartAsync(); var request = WebRequest.Create("http://localhost:80"); } ``` @@ -84,13 +89,13 @@ var testcontainersBuilder = new TestcontainersBuilder() .WithCommand("/bin/bash", "-c", "hostname > /tmp/hostname") .WithWaitStrategy(Wait.ForUnixContainer().UntilFileExists("/tmp/hostname")); -await using (var testcontainer = testcontainersBuilder.Build()) +await using (var testcontainers = testcontainersBuilder.Build()) { - await testcontainer.StartAsync(); + await testcontainers.StartAsync(); } ``` -Here is an example of a pre-configured Testcontainer. In the example, Testcontainers starts a PostgreSQL database and executes a SQL query. +Here is an example of a pre-configured Testcontainers. In the example, Testcontainers starts a PostgreSQL database and executes a SQL query. ```csharp var testcontainersBuilder = new TestcontainersBuilder() @@ -101,11 +106,11 @@ var testcontainersBuilder = new TestcontainersBuilder() Password = "postgres", }); -await using (var testcontainer = testcontainersBuilder.Build()) +await using (var testcontainers = testcontainersBuilder.Build()) { - await testcontainer.StartAsync(); + await testcontainers.StartAsync(); - using (var connection = new NpgsqlConnection(testcontainer.ConnectionString)) + using (var connection = new NpgsqlConnection(testcontainers.ConnectionString)) { connection.Open(); @@ -153,6 +158,7 @@ Many thanks to [JetBrains](https://www.jetbrains.com/?from=dotnet-testcontainers This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. -[1]: https://github.com/HofmeisterAn/dotnet-testcontainers/blob/develop/src/DotNet.Testcontainers.Tests/Unit/Containers/Unix/TestcontainersContainerTest.cs -[2]: https://github.com/HofmeisterAn/dotnet-testcontainers/blob/develop/src/DotNet.Testcontainers.Tests/Unit/Containers/Unix/Database -[3]: https://github.com/HofmeisterAn/dotnet-testcontainers/blob/develop/src/DotNet.Testcontainers.Tests/Unit/Containers/Unix/MessageBroker +[1]: https://github.com/HofmeisterAn/dotnet-testcontainers/blob/develop/tests/DotNet.Testcontainers.Tests/Unit/Containers/Unix/TestcontainersContainerTest.cs +[2]: https://github.com/HofmeisterAn/dotnet-testcontainers/blob/develop/tests/DotNet.Testcontainers.Tests/Unit/Containers/Unix/Modules/Databases +[3]: https://github.com/HofmeisterAn/dotnet-testcontainers/blob/develop/tests/DotNet.Testcontainers.Tests/Unit/Containers/Unix/Modules/MessageBrokers +[moby-ryuk]: https://github.com/testcontainers/moby-ryuk diff --git a/build.cake b/build.cake index 0826bb846..fddd9ab61 100644 --- a/build.cake +++ b/build.cake @@ -74,20 +74,25 @@ Task("Build") Task("Tests") .Does(() => { - DotNetTest(param.Solution, new DotNetTestSettings + foreach(var testProject in param.Projects.OnlyTests) { - Configuration = param.Configuration, - Verbosity = param.Verbosity, - NoRestore = true, - NoBuild = true, - Loggers = new[] { "trx" }, - Filter = param.TestFilter, - ResultsDirectory = param.Paths.Directories.TestResults, - ArgumentCustomization = args => args - .Append("/p:CollectCoverage=true") - .Append("/p:CoverletOutputFormat=opencover") - .Append($"/p:CoverletOutput=\"{MakeAbsolute(param.Paths.Directories.TestCoverage)}/\"") - }); + DotNetTest(testProject.Path.FullPath, new DotNetTestSettings + { + Configuration = param.Configuration, + Verbosity = param.Verbosity, + NoRestore = true, + NoBuild = true, + Loggers = new[] { "trx" }, + Filter = param.TestFilter, + ResultsDirectory = param.Paths.Directories.TestResults, + ArgumentCustomization = args => args + .Append("/p:Platform=AnyCPU") + .Append("/p:CollectCoverage=true") + .Append("/p:CoverletOutputFormat=\"json%2copencover\"") // https://github.com/coverlet-coverage/coverlet/pull/220#issuecomment-431507570. + .Append($"/p:MergeWith=\"{MakeAbsolute(param.Paths.Directories.TestCoverage)}/coverage.net6.0.json\"") + .Append($"/p:CoverletOutput=\"{MakeAbsolute(param.Paths.Directories.TestCoverage)}/\"") + }); + } }); Task("Sonar-Begin") diff --git a/tests/DotNet.Testcontainers.ResourceReaper.Tests/DefaultResourceReaperTest.cs b/tests/DotNet.Testcontainers.ResourceReaper.Tests/DefaultResourceReaperTest.cs index 9f61408e5..5a3599740 100644 --- a/tests/DotNet.Testcontainers.ResourceReaper.Tests/DefaultResourceReaperTest.cs +++ b/tests/DotNet.Testcontainers.ResourceReaper.Tests/DefaultResourceReaperTest.cs @@ -7,6 +7,8 @@ namespace DotNet.Testcontainers.ResourceReaper.Tests using DotNet.Testcontainers.Tests.Unit; using Xunit; + // NOTICE: These tests stop the static shared default Resource Reaper (dispose). Unit tests are executed parallel. + // We cannot stop the default Resource Reaper all of a sudden. Run these tests in an isolated assembly. public sealed class DefaultResourceReaperTest : IAsyncLifetime { private static readonly string DefaultRyukContainerName = $"testcontainers-ryuk-{ResourceReaper.DefaultSessionId:D}";