Activate WebApplication + VirtualDirectory for IIS deploy (Phase 4)
Summary
Phase 1-3.5 covered the WebSite sub-feature exhaustively but left two PS1 branches dormant — WebApplication (lines 360-422) and VirtualDirectory (lines 311-358). All scaffolding was already in place (properties, RecognisedProperties list entries, PS1 branches, Octopus-aligned namespace); what was missing was end-to-end coverage proving the dormant branches actually work against real IIS.
Zero production code changes. Pure test additions across three tiers. The PS1 branches were ported verbatim from Octopus in Phase 1 — this PR proves they work against real IIS metabase.
What ships (12 new tests across 3 tiers)
Unit (3 new)
| Test | Pins |
|---|---|
Build_WebApplicationToggleOn_WebSiteToggleOff_* |
WebApp.* properties land in preamble independently of WebSite toggle |
Build_VirtualDirectoryToggleOn_WebSiteToggleOff_* |
Same for VirtDir |
Build_AllThreeSubFeatureTogglesOn_* |
All three toggles emit independently — no implicit defaulting |
Pipeline-tier E2E (3 new, 2 are 2-case Theories)
| Test | Pins |
|---|---|
FullPipeline_WebApplicationToggle_* (Theory × 2 styles) |
WebApp properties flow through full pipeline → captured request |
FullPipeline_VirtualDirectoryToggle_* (Theory × 2 styles) |
Same for VirtDir |
FullPipeline_WebAppVirtualPathReferencesSquidVariable_* |
#{WebAppVirtualPath} substitution resolves before serialization |
Real-host E2E (6 new, all 🟢 high-fidelity)
| Test | Pins |
|---|---|
RealIIS_WebApplication_CreatedUnderExistingParentSite |
New-Item -type Application produces metabase node with ElementTagName='application' + correct physicalPath |
RealIIS_VirtualDirectory_CreatedUnderExistingParentSite |
Same for -type VirtualDirectory
|
RealIIS_WebApplication_FrameworkVersionDifferentFromParent_AppliedIndependently |
Child WebApp pool framework independent of parent (v2.0 child + v4.0 parent) — proves PS1 reads WebApplication.ApplicationPoolFrameworkVersion, not parent's |
RealIIS_WebApplication_Redeploy_UpdatesPhysicalPath |
Idempotence + change-detection: second deploy hits the 'already exists' branch (line 396) but Set-Path (line 413) still updates physicalPath |
RealIIS_WebApplicationAndVirtualDirectory_BothInSingleAction_BothCreated |
Composite deploy: single Squid action creates both children under shared parent |
RealIIS_WebApplication_NoParentSite_FailsWithActionableError |
Assert-WebsiteExists (line 282) throws with 'does not exist in IIS' guidance string — operators grep this phrase |
Test infrastructure additions
-
IISTestContext.WebAppVirtualPath/WebAppPhysicalPath/WebAppPoolName/VirtDirVirtualPath/VirtDirPhysicalPath(GUID-suffixed) -
IISTestContext.EnsureWebAppPhysicalPathExists()/EnsureVirtDirPhysicalPathExists()— opt-in directory stagers (Phase 1-3.5 tests don't pay the cost) -
Remove-WebAppPoolcascade inDispose()extended to includeWebAppPoolName -
DeployParentSite(ctx)helper — Phase 4 tests rely on a pre-existing parent (PS1 contract viaAssert-WebsiteExists); helper consolidates the bootstrap call -
ReadIISElementType(sitePath)/ReadIISPhysicalPath(sitePath)— round-trip viaGet-Item .ElementTagName / .physicalPath
Cumulative coverage state (after this PR)
| PS1 branch | Phase | Status |
|---|---|---|
| WebSite create/update | 1 |
|
| HTTPS bindings (SNI + non-SNI + rebind) | 2 |
|
| Auth toggles (3 flags × combinations) | 3 |
|
| App pool identities (5 variants incl. SpecificUser) | 3.5 |
|
| Framework versions (v4.0 / v2.0 / No Managed Code) | 3.5 |
|
| ExistingBindings Merge + Empty bindings | 3.5 |
|
| WebApplication branch | 4 |
|
| VirtualDirectory branch | 4 |
|
| Path-conflict edges (WebApp on VirtDir path) | — |
|
| Squid certificate-variable system | — |
|
Tentacle-side \$SquidParameters bootstrap |
5 |
|
Test count
- Unit: 48 → 51 (+3)
- Pipeline E2E: 5 → 8 (+3)
- Real-host E2E: 25 → 31 (+6)
Test plan
-
dotnet test --filter FullyQualifiedName~IISDeployon macOS — 51 unit tests green -
dotnet test --filter Category=IISDeployE2Eon macOS — 31 real-host tests skip cleanly via OS guard -
dotnet build0 errors across all affected projects -
CI run on windows-latest: 6 new real-host tests against real IIS WebApp/VirtDir metabase
Breaking-change risk
None. Pure test additions. No PS1 changes, no production code changes, no public-API drift.