Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement]: Make the container name part of the reuse hash #1161

Closed
0xced opened this issue Apr 25, 2024 · 0 comments · Fixed by #1162
Closed

[Enhancement]: Make the container name part of the reuse hash #1161

0xced opened this issue Apr 25, 2024 · 0 comments · Fixed by #1162
Labels
enhancement New feature or request

Comments

@0xced
Copy link
Contributor

0xced commented Apr 25, 2024

Problem

Since the reuse feature became available I started using Testcontainers to automate setting up a development database. I have created a hosted service that goes like this:

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Testcontainers.MsSql;

namespace SampleCode;

internal class DockerDatabaseService : IHostedService
{
    private readonly IDbContextFactory<MyDbContext> _dbContextFactory;
    private readonly MsSqlContainer _container;

    public DockerDatabaseService(IHostEnvironment environment, IDbContextFactory<MyDbContext> dbContextFactory, ILoggerFactory loggerFactory)
    {
        if (!environment.IsDevelopment())
        {
            throw new NotSupportedException($"{nameof(DockerDatabaseService)} must only be used in the development environment but the current environment is \"{environment.EnvironmentName}\"");
        }

        _dbContextFactory = dbContextFactory;
        _container = new MsSqlBuilder()
            .WithLogger(loggerFactory.CreateLogger("Testcontainers"))
            .WithReuse(true)
            .WithName(environment.ApplicationName)
            .WithPortBinding(hostPort: 1433, containerPort: 1433)
            .Build();
    }

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        await _container.StartAsync(cancellationToken);

        await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
        await dbContext.Database.MigrateAsync(cancellationToken);
    }

    public async Task StopAsync(CancellationToken cancellationToken)
    {
        await _container.StopAsync(cancellationToken);
    }
}

The Testcontainers.MsSql package is included conditionally for debug builds only:

<ItemGroup Condition="$(Configuration) == 'Debug'">
  <PackageReference Include="Testcontainers.MsSql" Version="3.8.0" />
</ItemGroup>
<ItemGroup Condition="$(Configuration) != 'Debug'">
  <Compile Remove="DockerDatabaseService.cs" />
</ItemGroup>

And the hosted service is also registered conditionally for debug builds in the development environment:

#if DEBUG
    if (environment.IsDevelopment())
    {
        services.AddHostedService<DockerDatabaseService>();
    }
#endif

It worked so well that I used it in several projects. But then the same container was reused across different projects. Since I explicitly set a container name (WithName(environment.ApplicationName)) I assumed that the reuse mechanism would use it but it does not.

Solution

I think the container name (just like network and volume names) should be part of the reuse hash.

Benefit

Container reuse would work out of the box by just setting an explicit container name.

Alternatives

Currently I'm working around this issue by configuring the container with a reuse-id label:

_container = new MsSqlBuilder()
    .WithLogger(loggerFactory.CreateLogger("Testcontainers"))
    .WithReuse(true)
    .WithLabel("reuse-id", environment.ApplicationName) // 👈 goes into the reuse hash
    .WithName(environment.ApplicationName)
    .WithPortBinding(hostPort: 1433, containerPort: 1433)
    .Build();

Would you like to help contributing this enhancement?

Yes: #1162

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant