Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix potential NullReferenceException
While experimenting with Podman I tried to run tests with the following settings: ```sh cd testcontainers-dotnet/tests/Testcontainers.PostgreSql.Tests export DOCKER_HOST=unix://${HOME}/.local/share/containers/podman/machine/podman.sock export TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/run/user/501/podman/podman.sock dotnet test --filter ConnectionStateReturnsOpen ``` This lead to a `NullReferenceException` ``` [xUnit.net 00:00:01.52] Testcontainers.PostgreSql.PostgreSqlContainerTest.ConnectionStateReturnsOpen [FAIL] Failed Testcontainers.PostgreSql.PostgreSqlContainerTest.ConnectionStateReturnsOpen [1 ms] Error Message: System.NullReferenceException : Object reference not set to an instance of an object. Stack Trace: at DotNet.Testcontainers.Containers.DockerContainer.get_State() in ~/testcontainers-dotnet/src/Testcontainers/Containers/DockerContainer.cs:line 177 at DotNet.Testcontainers.Configurations.UntilContainerIsRunning.UntilAsync(IContainer container) in ~/testcontainers-dotnet/src/Testcontainers/Configurations/WaitStrategies/UntilContainerIsRunning.cs:line 12 at DotNet.Testcontainers.Configurations.WaitStrategy.UntilAsync(IContainer container, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Configurations/WaitStrategies/WaitStrategy.cs:line 102 at DotNet.Testcontainers.Containers.DockerContainer.CheckReadinessAsync(WaitStrategy waitStrategy, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/DockerContainer.cs:line 534 at DotNet.Testcontainers.Configurations.WaitStrategy.<>c__DisplayClass24_0.<<WaitUntilAsync>g__UntilAsync|0>d.MoveNext() in ~/testcontainers-dotnet/src/Testcontainers/Configurations/WaitStrategies/WaitStrategy.cs:line 184 --- End of stack trace from previous location --- at DotNet.Testcontainers.Configurations.WaitStrategy.WaitUntilAsync(Func`1 wait, TimeSpan interval, TimeSpan timeout, Int32 retries, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Configurations/WaitStrategies/WaitStrategy.cs:line 213 at DotNet.Testcontainers.Containers.DockerContainer.CheckReadinessAsync(IEnumerable`1 waitStrategies, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/DockerContainer.cs:line 552 at DotNet.Testcontainers.Containers.DockerContainer.UnsafeStartAsync(CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/DockerContainer.cs:line 479 at DotNet.Testcontainers.Containers.DockerContainer.StartAsync(CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/DockerContainer.cs:line 282 at DotNet.Testcontainers.Containers.ResourceReaper.GetAndStartNewAsync(Guid sessionId, IDockerEndpointAuthenticationConfiguration dockerEndpointAuthConfig, IImage resourceReaperImage, IMount dockerSocket, ILogger logger, Boolean requiresPrivilegedMode, TimeSpan initTimeout, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/ResourceReaper.cs:line 219 at DotNet.Testcontainers.Containers.ResourceReaper.GetAndStartNewAsync(Guid sessionId, IDockerEndpointAuthenticationConfiguration dockerEndpointAuthConfig, IImage resourceReaperImage, IMount dockerSocket, ILogger logger, Boolean requiresPrivilegedMode, TimeSpan initTimeout, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/ResourceReaper.cs:line 243 at DotNet.Testcontainers.Containers.ResourceReaper.GetAndStartDefaultAsync(IDockerEndpointAuthenticationConfiguration dockerEndpointAuthConfig, ILogger logger, Boolean isWindowsEngineEnabled, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/ResourceReaper.cs:line 135 at DotNet.Testcontainers.Clients.TestcontainersClient.RunAsync(IContainerConfiguration configuration, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Clients/TestcontainersClient.cs:line 294 at DotNet.Testcontainers.Containers.DockerContainer.UnsafeCreateAsync(CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/DockerContainer.cs:line 415 at DotNet.Testcontainers.Containers.DockerContainer.StartAsync(CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/DockerContainer.cs:line 279 ``` The problem with this configuration is that the reaper container doesn't start but this is undiagnosable because of the swallowed exception. So instead of swallowing the exception in `ByIdAsync` the `DockerApiException` is now caught inside `ExistsWithIdAsync` instead. Although not obvious, the exception after this commit is better and can put you on the right track to understand that the issue is about the reaper container not starting properly. ``` [xUnit.net 00:00:01.39] Testcontainers.PostgreSql.PostgreSqlContainerTest.ConnectionStateReturnsOpen [FAIL] Failed Testcontainers.PostgreSql.PostgreSqlContainerTest.ConnectionStateReturnsOpen [1 ms] Error Message: Docker.DotNet.DockerContainerNotFoundException : Docker API responded with status code=NotFound, response={"cause":"no such container","message":"no container with name or ID \"91ce0224526fddb896f2163e764e03891fce19120059fdbd04c2112cbab076a6\" found: no such container","response":404} Stack Trace: at Docker.DotNet.ContainerOperations.<>c.<.cctor>b__30_0(HttpStatusCode statusCode, String responseBody) at Docker.DotNet.DockerClient.HandleIfErrorResponseAsync(HttpStatusCode statusCode, HttpResponseMessage response, IEnumerable`1 handlers) at Docker.DotNet.DockerClient.MakeRequestAsync(IEnumerable`1 errorHandlers, HttpMethod method, String path, IQueryString queryString, IRequestContent body, IDictionary`2 headers, TimeSpan timeout, CancellationToken token) at Docker.DotNet.ContainerOperations.InspectContainerAsync(String id, CancellationToken cancellationToken) at DotNet.Testcontainers.Clients.DockerContainerOperations.ByIdAsync(String id, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Clients/DockerContainerOperations.cs:line 36 at DotNet.Testcontainers.Containers.DockerContainer.CheckReadinessAsync(WaitStrategy waitStrategy, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/DockerContainer.cs:line 531 at DotNet.Testcontainers.Configurations.WaitStrategy.<>c__DisplayClass24_0.<<WaitUntilAsync>g__UntilAsync|0>d.MoveNext() in ~/testcontainers-dotnet/src/Testcontainers/Configurations/WaitStrategies/WaitStrategy.cs:line 184 --- End of stack trace from previous location --- at DotNet.Testcontainers.Configurations.WaitStrategy.WaitUntilAsync(Func`1 wait, TimeSpan interval, TimeSpan timeout, Int32 retries, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Configurations/WaitStrategies/WaitStrategy.cs:line 213 at DotNet.Testcontainers.Containers.DockerContainer.CheckReadinessAsync(IEnumerable`1 waitStrategies, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/DockerContainer.cs:line 552 at DotNet.Testcontainers.Containers.DockerContainer.UnsafeStartAsync(CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/DockerContainer.cs:line 479 at DotNet.Testcontainers.Containers.DockerContainer.StartAsync(CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/DockerContainer.cs:line 282 at DotNet.Testcontainers.Containers.ResourceReaper.GetAndStartNewAsync(Guid sessionId, IDockerEndpointAuthenticationConfiguration dockerEndpointAuthConfig, IImage resourceReaperImage, IMount dockerSocket, ILogger logger, Boolean requiresPrivilegedMode, TimeSpan initTimeout, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/ResourceReaper.cs:line 219 at DotNet.Testcontainers.Containers.ResourceReaper.GetAndStartNewAsync(Guid sessionId, IDockerEndpointAuthenticationConfiguration dockerEndpointAuthConfig, IImage resourceReaperImage, IMount dockerSocket, ILogger logger, Boolean requiresPrivilegedMode, TimeSpan initTimeout, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/ResourceReaper.cs:line 243 at DotNet.Testcontainers.Containers.ResourceReaper.GetAndStartDefaultAsync(IDockerEndpointAuthenticationConfiguration dockerEndpointAuthConfig, ILogger logger, Boolean isWindowsEngineEnabled, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/ResourceReaper.cs:line 135 at DotNet.Testcontainers.Clients.TestcontainersClient.RunAsync(IContainerConfiguration configuration, CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Clients/TestcontainersClient.cs:line 294 at DotNet.Testcontainers.Containers.DockerContainer.UnsafeCreateAsync(CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/DockerContainer.cs:line 415 at DotNet.Testcontainers.Containers.DockerContainer.StartAsync(CancellationToken ct) in ~/testcontainers-dotnet/src/Testcontainers/Containers/DockerContainer.cs:line 27 ``` By the way, the solution is `export TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED=true`, thank you [Stack Overflow](https://stackoverflow.com/questions/71549856/testcontainers-with-podman-in-java-tests/75110548#75110548)!
- Loading branch information