Add composite real-world .NET app deploy E2E (Phase 10.5)
Summary
One test that exercises EVERY operator-facing feature of Squid.DeployToIISWebSite in a SINGLE deploy action against a realistic .NET application artifact. This is the canonical "does the action work end-to-end on a real .NET artifact" test that validates feature composition — proving the 8 features work TOGETHER, not just in isolation.
Per-feature tests (147 of them across Phases 1-10) prove each feature works individually. This adds the missing capstone: feature ordering, state hand-off between rewriters, IIS metabase consistency after the full pipeline.
What the test exercises in one deploy
Package extraction (.zip with appsettings.json + web.config + web.Release.config + index.html + bin/OrderApi.dll)
↓ purges stale-from-previous-deploy.txt
PreDeploy custom script (writes sentinel)
↓
SubstituteInFiles (#{AppVersion}, #{EnvironmentTag} in appsettings.json)
↓
ConfigurationTransforms (XDT: web.Release.config sets MaxRetries=10 in web.config)
↓
ConfigurationVariables (appSettings[ApiUrl] and connectionStrings[OrdersDb] in web.config)
↓
StructuredConfigurationVariables (Logging:LogLevel:Default via COLON path; ConnectionStrings.CacheDb via DOT path)
↓
IIS configure (site + pool + binding + 3 auth toggles)
↓
PostDeploy custom script (queries Get-Website + writes sentinel proving site is Started)
12 stages of end-state verification
-
✅ Stale file purged (PurgeBeforeExtract) -
✅ Extracted files present incl. nestedbin/OrderApi.dll(recursive extraction) -
✅ PreDeploy sentinel exists with expected content -
✅ #{AppVersion}and#{EnvironmentTag}replaced in appsettings.json -
✅ Logging:LogLevel:Default→ "Debug" via colon path -
✅ ConnectionStrings.CacheDb→ "Redis=..." via dot path -
✅ web.config MaxRetries=10 (XDT applied) -
✅ web.config ApiUrl=https://api.prod (ConfigurationVariables) -
✅ web.config OrdersDb connectionString replaced -
✅ IIS site exists + pool state=Started -
✅ Auth flags: Anonymous=true, Basic=false, Windows=true -
✅ PostDeploy sentinel content includesstate=Started(proves ordering)
Test infrastructure
Self-contained:
-
StageNetAppArtifact()builds a realistic .NET app on disk + zips it -
IISTestContext(local copy, GUID-suffixed, self-cleaning) - Re-uses
IsMicrosoftWebXmlTransformAvailable()probe so test skips if XDT DLL absent
Cumulative state
- Unit: 74 (no change)
- Pipeline E2E: 15 (no change)
- Real-host: 58 → 59 (+1 composite — exercises ALL 8 features simultaneously)
The +1 is high-leverage: composite proves features work together, not just individually. Effective coverage multiplier ~8×.
Test plan
-
dotnet test --filter Category=IISDeployE2Eon macOS — 59 tests skip cleanly -
dotnet build0 errors -
CI run on windows-latest: composite test against real IIS + real XDT + real JSON walker
Breaking-change risk
None. New test class file. Zero production code changes.