eb5fa8f2bce56e2a5da2789be441cc89ee309580
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6667f345fa |
feat(configdb): add SiteCalls migration (#22, #23 M3)
Bundle B2 of Audit Log #23 M3: EF-generated migration that creates the SiteCalls operational-state table on [PRIMARY], with the simple clustered PK on TrackedOperationId and the two named indexes the entity config declares. No partition function / scheme / DB-role restriction — SiteCalls holds mutable operational state (insert-once + monotonic-status update at the repo layer), unlike the partitioned append-only AuditLog table from M1. - Migration: 20260520180431_AddSiteCallsTable.cs (auto-generated; EF emitted CREATE TABLE + 2 indexes without customisation needed). - Model snapshot updated alongside. - Integration test: tests/ScadaLink.ConfigurationDatabase.Tests/Migrations/ AddSiteCallsTableMigrationTests.cs. Uses the existing MsSqlMigrationFixture with [SkippableFact] + Skip.IfNot(fixture.Available). Asserts table + twelve columns + PK on TrackedOperationId + both named indexes. |
||
|
|
ce9d6301e3 |
fix(configdb-tests): use Assert.SkipUnless + fast-fail connect timeout for MSSQL fixture (#23)
Reviewer of Bundle C (#23 M1) flagged two blockers in the AddAuditLogTableMigration integration tests: 1. Tests used 'if (!await EnsureMigrationApplied()) return;' which made the xunit runner report them as Passed when the dev MSSQL container was absent — a CI false-positive risk. xunit 2.9.x does NOT ship the v3 Assert.Skip/SkipUnless/SkipWhen API surface (verified empirically against xunit.assert 2.9.3 — only v3.x exposes those static methods), so the canonical xunit-v2 equivalent is the Xunit.SkippableFact package. Replaced [Fact] with [SkippableFact] and the early-return pattern with 'Skip.IfNot(_fixture.Available, _fixture.SkipReason)' as the first statement of each of the 8 audit-log test methods. The runner now reports them as Skipped (not Passed) when MSSQL is down. 2. MsSqlMigrationFixture relied on SqlClient's 30s default connect timeout, so a no-container fixture construction hung ~30s. Added 'Connect Timeout=3' to DefaultAdminConnectionString. Verified fail-fast under ~4s end-to-end with a bad host via env-var override. Additional fixture cleanups: - Migration is now applied once in the fixture constructor (was per-test via EnsureMigrationApplied for idempotency). Tests reach a fully- migrated database with no extra setup. Removed the now-unused EnsureMigrationApplied helper from the test class. - Constructor narrowed its catch to SqlException + InvalidOperationException for the OpenAsync step (the only legitimate connect-failure surfaces); everything else (CREATE DATABASE, MigrateAsync) is treated as a hard fixture failure and bubbles up. Added a best-effort TryDropOrphanDatabase() pre-throw cleanup so partial construction cannot leak guid-suffixed databases. - Stale doc comments referencing the (non-existent) xunit 2.9.x Skip shim removed; replaced with accurate notes about Xunit.SkippableFact. Verified: - dotnet build ScadaLink.slnx: clean (0 warnings, 0 errors). - dotnet test ScadaLink.ConfigurationDatabase.Tests with MSSQL up: Passed 150 / Skipped 0 / Failed 0. - Same suite with SCADALINK_MSSQL_TEST_CONN pointed at a closed port: the 8 AddAuditLogTableMigration tests report as Skipped (visible '[SKIP]' lines in runner output), total elapsed ~3s. Files touched: - Directory.Packages.props: added Xunit.SkippableFact 1.5.61. - tests/ScadaLink.ConfigurationDatabase.Tests/ScadaLink.ConfigurationDatabase.Tests.csproj: added the SkippableFact PackageReference. - tests/ScadaLink.ConfigurationDatabase.Tests/Migrations/MsSqlMigrationFixture.cs: Connect Timeout=3, constructor refactor, doc-comment fixes. - tests/ScadaLink.ConfigurationDatabase.Tests/Migrations/AddAuditLogTableMigrationTests.cs: [SkippableFact] + Skip.IfNot pattern across all 8 tests. Untouched (per reviewer guidance): - Migration file (Bundle C main artifact unchanged). - Bundle B reconciliation (composite PK + UX_AuditLog_EventId). - SqlClient VersionOverride 6.1.1 in the test csproj. - infra/* (separate uncommitted local edits remain in working tree). |
||
|
|
d9c99242a3 |
feat(configdb): add AuditLog migration with monthly partitioning and DB roles (#23)
Bundle C of the #23 M1 foundation. Creates the centralized AuditLog table with the partition function, partition scheme, partition-aligned non-clustered indexes, and the two access-control roles documented in alog.md §4. Schema: - pf_AuditLog_Month: RANGE RIGHT, 24 monthly boundaries (Jan 2026 – Dec 2027). - ps_AuditLog_Month: ALL TO ([PRIMARY]) — dev/test parity. - dbo.AuditLog: created via raw SQL ON ps_AuditLog_Month(OccurredAtUtc). Composite clustered PK {EventId, OccurredAtUtc} (partition column must be part of the clustered key). 22 columns matching the EF AuditEvent model. - 5 reconciliation/query non-clustered indexes from alog.md §4 (Channel_Status_Occurred, CorrelationId filtered, OccurredAtUtc, Site_Occurred, Target_Occurred filtered) — all partition-aligned. - UX_AuditLog_EventId: non-aligned UNIQUE on EventId alone (preserves InsertIfNotExistsAsync idempotency from M1-T8). Non-aligned because partition-aligned unique indexes require the partition column in the key, which would weaken to composite uniqueness; the purge story (M2/M3) rebuilds this index around partition switches. Access control: - scadalink_audit_writer: GRANT INSERT + GRANT SELECT, DENY UPDATE + DENY DELETE on AuditLog. The explicit DENY guarantees later db_datawriter membership cannot quietly re-enable mutation. - scadalink_audit_purger: GRANT SELECT on AuditLog, GRANT ALTER on SCHEMA::dbo (enables ALTER PARTITION FUNCTION SWITCH and SWITCH PARTITION). Both role definitions are idempotent (IF DATABASE_PRINCIPAL_ID IS NULL). Down() drops in reverse dependency order with IF EXISTS guards. Integration tests (tests/ScadaLink.ConfigurationDatabase.Tests/Migrations/): - MsSqlMigrationFixture: connects to the running infra/mssql container (or the SCADALINK_MSSQL_TEST_CONN override), creates a unique per-fixture database, applies the migrations, drops the DB on dispose. Marks itself Available=false when MSSQL is unreachable so tests early-return cleanly on CI without the dev container. - AddAuditLogTableMigrationTests: 8 tests covering table existence, partition function/scheme, partition-aligned PK, the 5 named indexes, both roles' grants, and a smoke test that a writer-role user receives SqlException with "permission" on UPDATE AuditLog. ConfigurationDatabase tests: 142 passing -> 150 passing (8 new integration tests). Full solution builds clean. Package: tests project locally overrides Microsoft.Data.SqlClient to 6.1.1 (EF SqlServer 10.0.7 needs >= 6.1.1; central package version is pinned at 6.0.2 for the production ExternalSystemGateway). |