Files
ScadaBridge/docs/plans/2026-05-24-second-environment-verification.md
T

5.7 KiB

Env2 + Transport Manual Verification Checklist

RETIRED 2026-08-01 — never run as written; superseded by automated suites + a live cross-environment run. The step list below predates the M8 import-wizard Map step and was never annotated. Instead of refreshing ~48 stale steps, the core scenario this checklist exists for was run live on 2026-08-01 (rig session, task #12): CLI bundle export from the primary cluster (encrypted, --include-dependencies, template closure + shared scripts + external system + site-a + instances) → bundle preview against the empty env2 (correct Map requirements surfaced) → bundle import --create-missing-sites --create-missing-connections into env2 → 20 entities added, secrets (AuthConfiguration) intact, instances landed NotDeployed, connection FK wired to the created site. The run caught a real bug (create-missing site id never materialised before the connection insert → FK 547 on real SQL Server, masked by the in-memory test provider) — fixed the same day with an SQLite regression test (CreateMissingSiteRelationalTests, commit 0c9dffed). Env2 boot/PSK/LocalDb were separately proven PASS 3/3 by Gitea #31 (2026-07-23). Remaining coverage lives in tests/ZB.MOM.WW.ScadaBridge.Transport.IntegrationTests (RoundTrip/RoundTripEquivalence/ ConflictResolution/ValidationFailure/SiteInstanceImport/CreateMissingSiteRelational). This checklist is retired — do not run or refresh it.

Date created: 2026-05-24 Companion to: 2026-05-24-second-environment-design.md, Component-Transport.md Goal: Exercise the Transport (#24) bundle export/import flow against two real running environments (primary + env2).

Prerequisites

  • infra/ services running: cd infra && docker compose up -d
  • Primary stack running and healthy: bash docker/deploy.sh && bash docker/seed-sites.sh
  • scadabridge-mssql reachable (docker ps | grep scadabridge-mssql)

Step 0: Bring up env2

  • bash docker-env2/deploy.sh completes without error
  • docker ps --format '{{.Names}}' shows 5 new scadabridge-env2-* containers
  • curl -s http://localhost:9101/health/ready returns 200 with "status": "Healthy"
  • curl -s http://localhost:9100/health/active is routed through Traefik
  • http://localhost:9100 loads the env2 login page in a browser
  • Login as multi-role / password succeeds
  • Env2 dashboard renders, Sites page is empty

Step 1: Seed env2's test site

  • bash docker-env2/seed-sites.sh completes without error
  • Env2 UI → Sites page shows site-x (Env2 Site X)
  • Within ~30s, site-x health turns green

Step 2: Prepare bundle source on primary

  • Primary UI (http://localhost:9000) → Design → Templates contains at least one template (create one if empty)
  • Optional: prepare at least one shared script and one external system for fuller round-trip coverage

Step 3: Export from primary

  • Primary UI → Design → Export Bundle
  • Selection step: tick at least one template (folder + items)
  • Review step: confirm selected entity counts
  • Encrypt step: set passphrase test-passphrase-1
  • Download step: receive a .scadabundle file (note exact filename)
  • Verify the manifest's SourceEnvironment field equals docker-cluster (peek inside the zip; manifest.json is plaintext)

Step 4: Import into env2

  • Env2 UI (http://localhost:9101) → Admin → Import Bundle
  • Upload step: select the bundle file from Step 3
  • Passphrase step: enter test-passphrase-1 → diff loads successfully
  • Diff step: all rows are "Create" (env2 was empty for these entities)
  • Confirm step: import succeeds; result step shows the per-row outcome
  • Env2 audit log row(s) are tagged with the bundle's BundleImportId

Step 5: Verify imported artifacts in env2

  • Env2 UI → Design → Templates shows the imported template(s)
  • Env2 UI → Audit → Configuration Audit Log filtered by BundleImportId shows the import events
  • (Optional) Deploy an imported template to env2's site-x to prove runtime validity

Step 6: Conflict-resolution probe

  • Re-upload the same .scadabundle to env2 with the same passphrase
  • Diff step: all rows are now "Update"
  • Pick mixed Skip / Overwrite / Rename per row; confirm
  • Verify the chosen resolutions land correctly (Skip rows unchanged, Overwrite rows match the bundle, Rename rows present under the new name)

Negative tests

  • Wrong passphrase: try wrong-passphrase → friendly error, no diff loaded
  • Wrong passphrase 3 times in one session → session lockout enforced (MaxUnlockAttemptsPerSession)
  • Bump primary's Transport.SchemaVersionMajor to 99, export, attempt env2 import → schema-version mismatch error
  • Tamper with manifest.json content hash (unzip → edit → re-zip) → content-hash mismatch error

Round-trip parity

  • Export the same templates from env2 (with Transport.SourceEnvironment = docker-cluster-env2)
  • Re-import into primary with Skip-on-conflict for all rows
  • Primary's audit log shows no actual mutations
  • Primary's template revision hashes are unchanged after the no-op import

Cleanup (optional)

  • bash docker-env2/teardown.sh stops env2 containers
  • Drop env2 databases if needed:
    docker exec scadabridge-mssql /opt/mssql-tools18/bin/sqlcmd \
        -S localhost -U sa -P 'ScadaBridge_Dev1#' -C \
        -Q "DROP DATABASE ScadaBridgeConfig2; DROP DATABASE ScadaBridgeMachineData2;"
    

Pass criteria

All checkboxes ticked, no defects found, both stacks remain healthy after the run.