diff --git a/.github/workflows/dotnet-core-master.yml b/.github/workflows/dotnet-core-master.yml index eb04e03a..7e1fcc27 100644 --- a/.github/workflows/dotnet-core-master.yml +++ b/.github/workflows/dotnet-core-master.yml @@ -268,16 +268,6 @@ jobs: - uses: actions/checkout@v3 - name: Create docker network run: docker network create --driver bridge --attachable data - - name: Start MariaDB - run: | - docker pull mariadb:10.8 - docker run --name mariadbtest --network data -e MYSQL_ROOT_PASSWORD=secretpassword -p 3306:3306 -d mariadb:10.8 - - name: Start rabbitmq - run: | - docker pull rabbitmq:latest - docker run -d --hostname my-rabbit --name some-rabbit --network data -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=password -p 5672:5672 rabbitmq:latest - - name: Sleep 15 - run: sleep 15 - name: Setup .NET Core uses: actions/setup-dotnet@v3 with: diff --git a/.github/workflows/dotnet-core-pr.yml b/.github/workflows/dotnet-core-pr.yml index 37a5c069..814b458a 100644 --- a/.github/workflows/dotnet-core-pr.yml +++ b/.github/workflows/dotnet-core-pr.yml @@ -257,16 +257,6 @@ jobs: - uses: actions/checkout@v3 - name: Create docker network run: docker network create --driver bridge --attachable data - - name: Start MariaDB - run: | - docker pull mariadb:10.8 - docker run --name mariadbtest --network data -e MYSQL_ROOT_PASSWORD=secretpassword -p 3306:3306 -d mariadb:10.8 - - name: Start rabbitmq - run: | - docker pull rabbitmq:latest - docker run -d --hostname my-rabbit --name some-rabbit --network data -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=password -p 5672:5672 rabbitmq:latest - - name: Sleep 15 - run: sleep 15 - name: Setup .NET Core uses: actions/setup-dotnet@v3 with: diff --git a/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/TestBaseSetup.cs b/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/TestBaseSetup.cs index 2e47df43..022e9288 100644 --- a/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/TestBaseSetup.cs +++ b/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/TestBaseSetup.cs @@ -122,8 +122,57 @@ protected TimePlanningPnDbContext CreateTimePlanningPnDbContext() return new TimePlanningPnDbContext(optionsBuilder.Options); } + /// + /// Provisions the SDK database (420_SDK) the first time it is needed and + /// memoizes the schema/connection for the lifetime of this fixture + /// instance — (~44-48s) + /// is the expensive part and only needs to run ONCE per fixture, not once + /// per test. This method ONLY provisions; it never resets SDK data, so + /// calling more than once within a single test is + /// harmless. Per-test data isolation is handled separately, in + /// (see ResetSdkDbDataAsync below) — resetting here, + /// on every call, wiped out data a test had just written via an earlier + /// GetCore() call in the same test (Stage 0 review round 2). + /// + private async Task EnsureSdkDbProvisionedAsync() + { + if (_mariadbTestcontainer.State == TestcontainersStates.Undefined) + { + await _mariadbTestcontainer.StartAsync(); + } + + if (MicrotingDbContext == null) + { + var dbContext = GetContext(_mariadbTestcontainer.GetConnectionString()); + dbContext.Database.SetCommandTimeout(300); + MicrotingDbContext = dbContext; + } + } + + /// + /// Resets SDK *data* to the dump's known-good snapshot (~7s) by + /// replaying the SQL dump against the already-migrated schema, WITHOUT + /// re-running Migrate() (~44-48s, kept once-per-fixture). Called once per + /// test from — not from — so a + /// test that calls GetCore() more than once doesn't have its own SDK + /// writes wiped out mid-test, while every *new* test still starts from + /// clean SDK data. + /// + private async Task ResetSdkDbDataAsync() + { + var file = Path.Combine("SQL", "420_SDK.sql"); + var rawSql = await File.ReadAllTextAsync(file); + await MicrotingDbContext!.Database.ExecuteSqlRawAsync(rawSql); + } + protected async Task GetCore() { + // Core.StartSqlOnly only connects and validates settings - it does not + // migrate - so the SDK database must already be provisioned before it runs. + // This only provisions (once per fixture) and never resets data -- see + // EnsureSdkDbProvisionedAsync's doc comment. + await EnsureSdkDbProvisionedAsync(); + var core = new Core(); await core.StartSqlOnly(_mariadbTestcontainer.GetConnectionString().Replace("myDb", "420_SDK") .Replace("bla", "root")); @@ -138,29 +187,28 @@ public async Task Setup() await _mariadbTestcontainer.StartAsync(); } - // ConnectionString = _mariadbTestcontainer.GetConnectionString(); - - var DbContext = GetContext(_mariadbTestcontainer.GetConnectionString()); + // Reset SDK data once per test -- but only if an earlier test in this + // fixture already provisioned it (MicrotingDbContext != null). On the + // first test of a fixture, provisioning (triggered lazily by that + // test's own GetCore() call, if it makes one) already leaves the SDK + // database freshly loaded from the dump, so resetting here too would + // just be a redundant ~7s replay. + if (MicrotingDbContext != null) + { + await ResetSdkDbDataAsync(); + } - DbContext!.Database.SetCommandTimeout(300); - // Console.WriteLine($"{DateTime.Now} : Starting MariaDb Container..."); - // await _mariadbTestcontainer.StartAsync(); - // Console.WriteLine($"{DateTime.Now} : Started MariaDb Container"); - // TimePlanningPnDbContext = GetTimePlanningPnDbContext(_mariadbTestcontainer.GetConnectionString()); - // - // TimePlanningPnDbContext!.Database.SetCommandTimeout(300); - // - // MicrotingDbContext = GetContext(_mariadbTestcontainer.GetConnectionString()); - // - // MicrotingDbContext!.Database.SetCommandTimeout(300); - } [OneTimeTearDown] public async Task OneTimeTearDown() { Console.WriteLine($"{DateTime.Now} : Stopping MariaDb Container..."); + if (MicrotingDbContext != null) + { + await MicrotingDbContext.DisposeAsync(); + } await _mariadbTestcontainer.StopAsync(); await _mariadbTestcontainer.DisposeAsync(); Console.WriteLine($"{DateTime.Now} : Stopped MariaDb Container");