Skip to content

[Bug]: The UntilMessageIsLogged wait strategy is incompatible with the reuse feature #1383

Description

@0xced

Testcontainers version

4.3.0

Using the latest Testcontainers version?

Yes

Host OS

Any

Host arch

Any

.NET version

Any (9.0.2)

Docker version

not relevant

Docker info

not relevant

What happened?

Running this app twice in a row succeeds the first time but fails the second and subsequent times.

The Oracle container was chosen because it's using the until message is logged wait strategy.

reuse.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Oracle.ManagedDataAccess.Core" Version="23.7.0" />
    <PackageReference Include="Testcontainers.Oracle" Version="4.3.0" />
  </ItemGroup>

</Project>

Program.cs

using System;
using Oracle.ManagedDataAccess.Client;
using Testcontainers.Oracle;

await using var container = new OracleBuilder()
    .WithImage("gvenzl/oracle-free:23-slim-faststart")
    .WithName("Oracle.Reuse")
    .WithReuse(true)
    .Build();
await container.StartAsync();

var connectionString = new OracleConnectionStringBuilder(container.GetConnectionString())
{
    UserID = "SYS",
    DBAPrivilege = "SYSDBA",
};
await using var dataSource = OracleClientFactory.Instance.CreateDataSource(connectionString.ConnectionString);
await using var command = dataSource.CreateCommand("select version from v$instance");

try
{
    Console.WriteLine($"✅ {await command.ExecuteScalarAsync()}");
}
catch (Exception exception)
{
    Console.WriteLine($"❌ {exception}");
}

Relevant log output

=== First run ===

[testcontainers.org 00:00:00.09] Connected to Docker:
  Host: unix:///Users/0xced/.orbstack/run/docker.sock
  Server Version: 27.5.1
  Kernel Version: 6.12.15-orbstack-00304-gd0ddcf70447d
  API Version: 1.47
  Operating System: OrbStack
  Total Memory: 15.66 GB
[testcontainers.org 00:00:00.10] Reuse is an experimental feature. For more information, visit: https://dotnet.testcontainers.org/api/resource_reuse/
[testcontainers.org 00:00:00.13] Reusable resource not found, create resource
[testcontainers.org 00:00:00.26] Docker container c569bd3ac50c created
[testcontainers.org 00:00:00.30] Start Docker container c569bd3ac50c
[testcontainers.org 00:00:00.46] Wait for Docker container c569bd3ac50c to complete readiness checks
[testcontainers.org 00:00:19.62] Docker container c569bd3ac50c ready
✅ 23.0.0.0.0
[testcontainers.org 00:00:20.05] Stop Docker container c569bd3ac50c

=== Second run ===

[testcontainers.org 00:00:00.08] Connected to Docker:
  Host: unix:///Users/0xced/.orbstack/run/docker.sock
  Server Version: 27.5.1
  Kernel Version: 6.12.15-orbstack-00304-gd0ddcf70447d
  API Version: 1.47
  Operating System: OrbStack
  Total Memory: 15.66 GB
[testcontainers.org 00:00:00.10] Reuse is an experimental feature. For more information, visit: https://dotnet.testcontainers.org/api/resource_reuse/
[testcontainers.org 00:00:00.13] Reusable resource found
[testcontainers.org 00:00:00.18] Start Docker container c569bd3ac50c
[testcontainers.org 00:00:00.36] Wait for Docker container c569bd3ac50c to complete readiness checks
[testcontainers.org 00:00:00.37] Docker container c569bd3ac50c ready
❌ Oracle.ManagedDataAccess.Client.OracleException (0x80004005): ORA-50201: Oracle Communication: Failed to connect to server or failed to parse connect string
 ---> OracleInternal.Network.NetworkException (0x80004005): ORA-50201: Oracle Communication: Failed to connect to server or failed to parse connect string
 ---> OracleInternal.Network.NetworkException (0x80004005): ORA-12514: Cannot connect to database. Service FREEPDB1 is not registered with the listener at host 127.0.0.1/127.0.0.1 port 32770. (CONNECTION_ID=XFFRzUa9YkmyOWXXcYF4Fw==)
https://docs.oracle.com/error-help/db/ora-12514/
   at OracleInternal.Network.OracleCommunication.SendConnectPacketAndProcessResponse(AddressResolution addrRes, Boolean bAsync)
   at OracleInternal.Network.OracleCommunication.ConnectViaCO(ConnectionOption connOption, AddressResolution addrRes, Boolean bAsync)
   at OracleInternal.Network.OracleCommunication.DoConnect(String tnsDescriptor, Boolean bAsync)
   at OracleInternal.Network.OracleCommunication.Connect(String tnsDescriptor, Boolean doNAHandshake, String IName, ConnectionOption CO, Boolean bAsync)
   at OracleInternal.ServiceObjects.OracleConnectionImpl.Connect(ConnectionString cs, Boolean bOpenEndUserSession, OracleConnection connRefForCriteria, String instanceName, Boolean bAsync)
   at OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPassw, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch, Boolean bAsync)
   at OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassw, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch, Boolean bAsync)
   at OracleInternal.ConnectionPool.PoolManager`3.WaitForPendingGet()
--- End of stack trace from previous location ---
   at OracleInternal.ConnectionPool.OracleConnectionDispenser`3.GetAsync(ConnectionString cs, PM conPM, ConnectionString pmCS, OracleOpaqueString opaquePassw, OracleOpaqueString securedProxyPassw, OracleConnection connRefForCriteria, Boolean bAsync)
   at Oracle.ManagedDataAccess.Client.OracleConnectionInternal.OpenInternalAsync(Boolean bAsync)
   at Oracle.ManagedDataAccess.Client.OracleConnectionInternal.OpenAsyncHelper(CancellationToken cancellationToken)
   at Oracle.ManagedDataAccess.Client.OracleConnectionInternal.OpenAsyncHelper(CancellationToken cancellationToken)
   at Oracle.ManagedDataAccess.Client.OracleConnectionInternal.OpenAsync(CancellationToken cancellationToken)
   at System.Data.Common.DbDataSource.DbCommandWrapper.ExecuteScalarAsync(CancellationToken cancellationToken)
   at Program.<Main>$(String[] args) in Program.cs:line 22
[testcontainers.org 00:00:00.57] Stop Docker container c569bd3ac50c

Additional information

This error occurs because the previous logs are still available when reusing a container. So checking for DATABASE IS READY TO USE! succeeds immediately as it's directly available in the logs of the reused container.

I think I know how to solve this issue. I'll be submitting a pull request soon.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions