1- using DotNet . Testcontainers . Builders ;
2- using DotNet . Testcontainers . Configurations ;
1+ using DotNet . Testcontainers . Configurations ;
32using Microsoft . Data . SqlClient ;
43using Microsoft . SqlServer . Dac ;
54using RepoDb ;
5+ using System . Security . Cryptography ;
66using Testcontainers . MsSql ;
77
88namespace TelemetryStash . Database . Tests ;
@@ -17,6 +17,7 @@ public class CollectionState : ICollectionFixture<SharedTestDbFixture>
1717public class SharedTestDbFixture : IAsyncLifetime
1818{
1919 private readonly MsSqlContainer _sqlContainer ;
20+ private readonly string _sqlDbPassword ;
2021 private readonly Dictionary < string , IDbProvider > _dbProviders = [ ] ;
2122 private readonly DacPackage _dacPackage ;
2223
@@ -27,12 +28,10 @@ public SharedTestDbFixture()
2728 // https://hub.docker.com/r/microsoft/mssql-server
2829 _sqlContainer = new MsSqlBuilder ( )
2930 . WithImage ( "mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04" )
30-
31- // https://github.com/testcontainers/testcontainers-dotnet/issues/1220
32- . WithWaitStrategy ( Wait . ForUnixContainer ( ) . UntilCommandIsCompleted ( "/opt/mssql-tools18/bin/sqlcmd" , "-C" , "-Q" , "SELECT 1;" ) )
3331 . Build ( ) ;
3432
3533 _dacPackage = DacPackage . Load ( "../../../../Ts.TelemetryDatabase.Sql/bin/Ts.TelemetryDatabase.Sql.dacpac" ) ;
34+ _sqlDbPassword = $ "{ Convert . ToBase64String ( RandomNumberGenerator . GetBytes ( 10 ) ) } -";
3635 }
3736
3837 public IDbProvider GetTestDbProvider ( string databaseName )
@@ -43,29 +42,42 @@ public IDbProvider GetTestDbProvider(string databaseName)
4342 using var connection = new SqlConnection ( masterDbConnectionString ) ;
4443
4544 // Drop database if exist
46- // Drop database if exist
47- const string sql =
48- """
49- IF DB_ID(@DatabaseName) IS NOT NULL
45+ var dropDbSql =
46+ $ """
47+ IF DB_ID('{ databaseName } ') IS NOT NULL
5048 BEGIN
51- DROP DATABASE [@DatabaseName ]
49+ DROP DATABASE [{ databaseName } ]
5250 END
5351 """ ;
54- connection . ExecuteScalar ( sql , new { DatabaseName = databaseName } ) ;
52+ connection . ExecuteNonQuery ( dropDbSql ) ;
5553
56- // Replace master with databaseName
57- var connectionString = new SqlConnectionStringBuilder ( masterDbConnectionString )
58- {
59- InitialCatalog = databaseName
60- } ;
54+ // Create database and apply dacpac SQL schema
55+ var services = new DacServices ( masterDbConnectionString . ToString ( ) ) ;
56+ services . Deploy ( _dacPackage , databaseName ) ;
6157
62- var services = new DacServices ( connectionString . ToString ( ) ) ;
58+ // Create user
59+ const string userId = "ts_test_user" ;
60+ var createUserSql =
61+ $ """
62+ USE [{ databaseName } ]
6363
64- services . Message += ( sender , args ) => Console . WriteLine ( args . Message ) ;
65- services . ProgressChanged += ( sender , args ) => Console . WriteLine ( args . Status ) ;
64+ IF SUSER_ID (' { userId } ') IS NULL
65+ CREATE LOGIN [ { userId } ] WITH PASSWORD = ' { _sqlDbPassword } '
6666
67- // Create database and apply dacpac SQL schema
68- services . Deploy ( _dacPackage , databaseName ) ;
67+ CREATE USER [{ userId } ] FOR LOGIN [{ userId } ]
68+ ALTER ROLE [db_execute_procedure_role] ADD MEMBER [{ userId } ]
69+ EXEC sp_addrolemember 'db_datareader', [{ userId } ]
70+ """ ;
71+
72+ connection . ExecuteNonQuery ( createUserSql ) ;
73+
74+ // Build connection string
75+ var connectionString = new SqlConnectionStringBuilder ( masterDbConnectionString )
76+ {
77+ InitialCatalog = databaseName ,
78+ UserID = userId ,
79+ Password = _sqlDbPassword
80+ } ;
6981
7082 value = new DbProvider ( connectionString . ToString ( ) ) ;
7183 _dbProviders [ databaseName ] = value ;
0 commit comments