testcontainers-dotnet icon indicating copy to clipboard operation
testcontainers-dotnet copied to clipboard

Add callback that is called after wait strategies have been executed

Open harrhp opened this issue 3 years ago • 4 comments

Is your feature request related to a problem? Please describe. Existing StartupCallback is called after container started but before wait strategies, that's not very usefull because most of the time service inside container is not ready to accept requests yet. I propose to add callback that is called after wait strategies have been executed. At this point service is ready, so it's possible to run database migrations, create kafka topics, etc.

Describe the solution you'd like Add callback that is called after wait strategies have been executed

Describe alternatives you've considered Configure service inside container after StartAsync completed

Additional context

harrhp avatar Jun 08 '22 09:06 harrhp

that's not very usefull because most of the time service inside container is not ready to accept requests yet

It's necessary to configure Kafka.

What's the benefit of the callback? Why not run the migration after StartAsync or inherit from TestcontainersContainer and override StartAsync? You can even use fixtures incl. IAsyncLifetime.

HofmeisterAn avatar Jun 08 '22 10:06 HofmeisterAn

The benefit, i think, is that it allows to keep code that builds test container and runs after start configuration very close. It also allows to plug in configuration into StartAsync so that after it returns service inside container is configured. Right now i call configuration code manually after StartAsync like you suggested. I didn't think about inheritance, but i think callback is better option. IAsyncLifetime is test framework (i use mstest) specific

harrhp avatar Jun 10 '22 11:06 harrhp

To override the TestcontainersContainer class we need to update the reflection call in the builder. Relates to #474.

HofmeisterAn avatar Jun 13 '22 19:06 HofmeisterAn

Adding a callback requires much more code. We need to extend the builder incl. the configuration and pass the callback through the library. The callback won't be able to access the running container instance. Therefore, we need to pass the running instance again to the callback. Finally, we need to cover everything with tests.

IMO, inheritance would be much easier and supported with #474. I'm preparing the pull request right now. If you still would like to use a callback, please consider contributing.

HofmeisterAn avatar Jun 14 '22 16:06 HofmeisterAn

Since 2.4.0 Testcontainers for .NET allows to override or subscribe to the lifecycle events of resources, like:

public sealed class MyContainer: DockerContainer
{
    ...

    public override Task StartAsync(CancellationToken ct = default)
    {
        return base.StartAsync(ct);
    }

    public override Task StopAsync(CancellationToken ct = default)
    {
        return base.StopAsync(ct);
    }

    protected override Task UnsafeCreateAsync(CancellationToken ct = default)
    {
        return base.UnsafeCreateAsync(ct);
    }

    protected override Task UnsafeDeleteAsync(CancellationToken ct = default)
    {
        return base.UnsafeDeleteAsync(ct);
    }
}

Overrides the container's lifecycles.

var myContainer = new ContainerBuilder().Build();
myContainer.Creating += (_, _) => { };
myContainer.Created += (_, _) => { };
myContainer.Starting += (_, _) => { };
myContainer.Started += (_, _) => { };
myContainer.Stopping += (_, _) => { };
myContainer.Stopped += (_, _) => { };

Subscribes to the container's lifecycles.

HofmeisterAn avatar Feb 10 '23 09:02 HofmeisterAn