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

Allow custom Database-name in MsSqlTestcontainerConfiguration #541

Closed
FelixSFD opened this issue Aug 1, 2022 · 3 comments
Closed

Allow custom Database-name in MsSqlTestcontainerConfiguration #541

FelixSFD opened this issue Aug 1, 2022 · 3 comments
Labels
enhancement New feature or request help wanted Extra attention is needed
Milestone

Comments

@FelixSFD
Copy link

FelixSFD commented Aug 1, 2022

Is your feature request related to a problem? Please describe.
I'm trying to switch all our tests to use Testcontainers instead of real databases on a server. However, at least one of our Entity Framework migrations contains code to alter the current database. This does not work, because MsSqlTestcontainerConfiguration defaults to the master-DB which may not be altered.

Microsoft.Data.SqlClient.SqlException : Cannot alter the database 'master' because it is a system database.

When I try to set the DB-name in the configuration, a NotImplementedException will be thrown.

TestcontainerDatabaseConfiguration containerConfig = new MsSqlTestcontainerConfiguration
{
  Password = Random.Shared.NextAlphaNumeric(16),
  Database = $"TestDb_{Random.Shared.NextAlphaNumeric(5)}"
};
System.NotImplementedException : The method or operation is not implemented.
MsSqlTestcontainerConfiguration.set_Database(String value)
TestStartupBase.GetTestDbContainer() line 174
TestStartupBase.StartTestDbContainer(Int32 timeout) line 142
TestStartupBase.GetTestDbConnectionString() line 156
Startup.ConfigureServices(IServiceCollection services) line 32

public override string Database
{
get => "master";
set => throw new NotImplementedException();
}

Describe the solution you'd like
MsSqlTestcontainerConfiguration.Database should be customizeable.

Describe alternatives you've considered
I don't know any alternatives (yet).

Additional context
This is probably the migration that fails when using the master-DB:

migrationBuilder.AlterDatabase(collation: "Latin1_General_CS_AS");
@FelixSFD
Copy link
Author

FelixSFD commented Aug 1, 2022

I should have checked the Pull-Requests before creating an issue... 🤦‍♂️
#521

@HofmeisterAn
Copy link
Collaborator

I should have checked the Pull-Requests before creating an issue... 🤦‍♂️ #521

Yep 😅. Would you like to take a look at that? Any help is more than welcome.

@HofmeisterAn HofmeisterAn added enhancement New feature or request help wanted Extra attention is needed labels Aug 1, 2022
enginexon added a commit to enginexon/testcontainers-dotnet that referenced this issue Aug 1, 2022
…nfiguration (creating database using SQL script execution)
HofmeisterAn added a commit that referenced this issue Aug 2, 2022
@HofmeisterAn HofmeisterAn added this to the 2.2.0 milestone Aug 2, 2022
@mrpmorris
Copy link

You can achieve this by calling ExecuteScriptAsync on your MsSqlContainer to create a database, and then replacing Database=master with your own value.

Here is some code I use in my unit tests.

internal static class TestSqlServerDatabaseFactory
{
    private static readonly Lazy<ValueTask<MsSqlContainer>> GetServerInstance = new(CreateServerInstanceAsync);
    private static int? Port;

    public static async ValueTask<string> CreateDatabaseAndGetConnectionStringAsync()
    {
        MsSqlContainer serverInstance = await GetServerInstance.Value;
        string databaseName = "Test" + Guid.NewGuid().ToString().Replace("-", "");
        await serverInstance.ExecScriptAsync($"create database [{databaseName}]");
        string connectionString =
            serverInstance
                .GetConnectionString()
                .Replace("Database=master", $"Database={databaseName}");
        return connectionString;
    }

    public static void SetPort(int port)
    {
        if (Port is not null && Port != port)
            Port = port;
    }

    private static async ValueTask<MsSqlContainer> CreateServerInstanceAsync()
    {
        var result =
            new MsSqlBuilder()
                .WithAutoRemove(autoRemove: true)
                .WithExposedPort(Port ?? 54465)
                .Build();

        await result.StartAsync();
        return result;
    }
}

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

No branches or pull requests

3 participants