Adds a MariaDB service to backend-test for SlpModularCms.Api.Tests
Continuous Integration / config (pull_request) Successful in 12s
Continuous Integration / changes (pull_request) Successful in 22s
Continuous Integration / backend-build (pull_request) Successful in 5m52s
Continuous Integration / vulnerability-scan (pull_request) Successful in 5m6s
Continuous Integration / frontend-prepare (pull_request) Successful in 1m24s
Continuous Integration / backend-test (pull_request) Failing after 8m24s
Continuous Integration / frontend-build (pull_request) Successful in 2m14s
Continuous Integration / frontend-test (pull_request) Successful in 4m28s
Continuous Integration / frontend-lint (pull_request) Successful in 2m5s
Continuous Integration / publish-test (pull_request) Skipped
Continuous Integration / publish-production (pull_request) Skipped
Continuous Integration / deploy-test (pull_request) Skipped
Continuous Integration / deploy-production (pull_request) Skipped

The new pipeline regression tests boot the real Api host via
WebApplicationFactory, which unconditionally runs the startup database
migration -- unlike every other test project here, which mocks or uses EF
Core InMemory. CI had no MariaDB service at all, so those tests failed on
the connection itself. Adds a mariadb service container to the backend-test
job plus a ConnectionStrings__DefaultConnection override for that step,
which overrides the appsettings.Development.json placeholder via standard
config layering without touching any committed appsettings file or
affecting local test runs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FWyStNL2ZsjrS7FLd7xvvN
This commit is contained in:
2026-08-02 10:46:25 +02:00
co-authored by Claude Sonnet 5
parent fa389e42ee
commit 0feedf9c01
3 changed files with 43 additions and 0 deletions
@@ -128,12 +128,37 @@ jobs:
needs: [changes, backend-build]
if: needs.changes.outputs.backend == 'true'
runs-on: ubuntu-latest
# Added for SlpModularCms.Api.Tests (slpsoftware-api feature, NFR-CS-01): its pipeline
# regression tests boot the real Api host via WebApplicationFactory, which unconditionally
# runs CmsHost.ConfigurePipeline's startup migration (MigrateCoreDatabase) -- unlike every
# other test project here, which mocks/uses EF Core InMemory and never touches a real
# database. Without a real, reachable MariaDB, those tests fail on the connection itself
# before any assertion runs.
services:
mariadb:
image: mariadb:11
env:
MARIADB_ROOT_PASSWORD: ci_test_password
MARIADB_DATABASE: SlpModularCms
ports:
- 3306:3306
options: >-
--health-cmd="mysqladmin ping --silent"
--health-interval=10s
--health-timeout=5s
--health-retries=5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Test (Release)
env:
# Overrides the placeholder in SlpModularCms.Api/appsettings.Development.json for this
# CI run only -- ASP.NET Core's configuration layering applies environment variables
# after appsettings.*.json, so this reaches SlpModularCms.Api.Tests' WebApplicationFactory
# without touching any committed appsettings file.
ConnectionStrings__DefaultConnection: "Server=127.0.0.1;Port=3306;Database=SlpModularCms;Uid=root;Pwd=ci_test_password"
run: dotnet test SlpModularCms.sln -c Release
# --- Gate 3: vulnerability scan ---
@@ -563,3 +563,15 @@
**Context**: Local dev/test database only, explicitly requested by the user, low-risk and reversible (test data). Returning to the Unit 1 Code Generation approval gate.
---
## CI Fix: backend-test Had No Database for the New Pipeline Tests
**Timestamp**: 2026-08-02T12:00:00Z
**User Input**: Pasted the Gitea Actions `backend-test` job log — all 4 `SlpModularCms.Api.Tests` failed with `MySqlException: Access denied for user 'root'@'localhost'`.
**AI Response**: "Read `.gitea/workflows/continuous_integration.yaml`'s `backend-test` job: it runs `dotnet test SlpModularCms.sln -c Release` with no MariaDB service container at all — every other test project (Core.Tests, Module.*.Tests) mocks or uses EF Core InMemory and never needed one. The new `SlpModularCms.Api.Tests` boots the real `Api` host via `WebApplicationFactory`, which unconditionally runs `CmsHost.ConfigurePipeline`'s startup migration -- there is no way to exercise the real pipeline (this unit's whole NFR-CS-01 point) without a real, reachable database, and CI never had one. This is a design gap in the original NFR Requirements/Design for this unit, not something introduced by a later change -- should have been anticipated when Q1=C committed to a real WebApplicationFactory test rather than a fully mocked one. Added a `mariadb` service container to the `backend-test` job plus a `ConnectionStrings__DefaultConnection` environment-variable override for the test step only, which overrides the placeholder in `Api/appsettings.Development.json` via ASP.NET Core's standard configuration layering (env vars win over appsettings.*.json) -- no committed appsettings file changes needed, and zero effect on local `dotnet test` runs (developers' own `appsettings.local.json` continues to apply there, unaffected by a CI-only env var). Verified the override mechanism works by reproducing it locally against the existing local MariaDB container before trusting it in CI."
**Context**: Real bug fix, and a boundary call: `.gitea/workflows/continuous_integration.yaml` is nominally owned by the `gitea-deployment-workflow` feature, but this specific change (making the `backend-test` gate pass for a test project this feature introduced) is Construction/Build-and-Test correctness for `slpsoftware-api`, not a deploy-target retarget (D-15, still deferred to Operations) -- judged in-scope to fix directly rather than blocking the PR on a separate feature's process.
---
@@ -43,6 +43,12 @@ Added (frontend, not part of the original per-unit plan, but a direct, symmetric
Pre-existing bug, unrelated to this feature's own scope (not introduced by the `CmsHost` extraction) but surfaced by testing the new instance: `src/SlpModularCms.Core/Exceptions/GlobalExceptionHandler.cs` logged every exception at `LogError` before mapping it to a status code, so a routine `UnauthorizedException` (e.g. an invalid/missing refresh token — the normal state for a fresh, never-logged-in session) was indistinguishable from a genuine unhandled 500 in the console and in Sentry. Fixed: exceptions that map to a status below 500 now log at `LogWarning`; only genuinely unmapped exceptions (500) log at `LogError`. Affects every Client project equally (`Api`, `Api.Slave`, `Api.SlpSoftware`), not just this feature. No existing test asserted log level; full suite reran green (196 + 4).
## Post-Completion Fix: CI's backend-test Job Had No Database
The Gitea Actions `backend-test` job (`.gitea/workflows/continuous_integration.yaml`) just ran `dotnet test` with no MariaDB service — every pre-existing test project mocks or uses EF Core InMemory, so none of them ever needed one. `SlpModularCms.Api.Tests` boots the real `Api` host via `WebApplicationFactory`, which unconditionally runs the startup migration, so it genuinely needs a reachable database — a design gap in this unit's own NFR Requirements/Design that should have been anticipated when committing to a real pipeline test (Q1 = C) rather than a mocked one. Fixed by adding a `mariadb` service container to `backend-test` plus a `ConnectionStrings__DefaultConnection` environment-variable override for that step only (overrides the placeholder in `Api/appsettings.Development.json` via standard ASP.NET Core config layering — env vars win over `appsettings.*.json`). No committed appsettings changed; local `dotnet test` runs are unaffected (developers' own `appsettings.local.json` still applies there). Verified the override mechanism directly against the local MariaDB container before trusting it in CI.
**Scope note**: `continuous_integration.yaml` is nominally owned by the `gitea-deployment-workflow` feature. This specific change (making the test gate pass for a test project this feature introduced) was judged in-scope to fix directly as Build-and-Test correctness — distinct from the actual deploy-target retarget (D-15), which remains deferred to this feature's own Operations phase.
## Build and Test Verification (Step 13.5)
Two real build fixes were needed and applied during this step (not deviations from the plan — the plan didn't anticipate these, since they only surface once the code actually compiles):