Skip to content

Harden capability requirements tests and extract shared OS helper

Summary

Three focused improvements identified by the post-merge review of the static-capability-requirements series:

  1. Single source of truth for OS-string tolerance — extracted WindowsOsStringHelper.IsWindows so the dispatch-time guard (IISDeployActionHandler.LooksLikeWindowsOsString) and the plan-time projection (MachineCapabilitySet.IsWindows) no longer carry bit-identical copies of the logic. Existing method names kept as backward-compat wrappers. Cross-call-site drift detector (BackwardCompatibleWrappers_DelegateToHelper) pins identical behaviour across all three surfaces.

  2. Critical coverage gap closed — DeploymentPlanner.ValidateHandlerStaticRequirements now has dedicated unit coverage. Previously the new method introduced by the static-capability-requirements PR was only exercised transitively by tests that stubbed the action handler registry to return null; the new branch wasn't actually validated. 11 new tests drive the real DeploymentPlanner + real CapabilityValidator against stubbed handlers + cache, covering: empty requirements no-op, cold-cache optimistic-allow, warm-cache match/mismatch/slot-absent, OR-within-slot, AND-across-slots, multi-slot mixed outcomes, legacy long-form OS tolerance via projection, mixed-target plans, and Execute-mode throw.

  3. Smaller hygiene gaps —

    • ViolationCodesIntegrityTests: reflection-pinned All set membership + cardinality + emitted-code-must-be-in-All invariant. Catches "added new code but forgot to update All" at build time.
    • NuGetPackageSearchStrategyTests + NuGetPackageVersionStrategyTests: 13 new edge cases for auth failure (401/403), TaskCanceled timeout, URL encoding of special chars in queries, V2 pagination loop termination.
    • WindowsOsStringHelperTests: 33 consolidated cases (canonical, 8 legacy Windows version strings, non-Windows markers, anchoring guards against LinuxOnWindowsSubsystem / WindowsSomethingElse false-positives, null/empty edges).

Test plan

  • dotnet build Squid.sln → 0 errors
  • dotnet test Squid.UnitTests → 5495/5495 pass (was 5411 before this PR → +84 new tests, zero regression)
  • Drift detectors verified: cross-call-site OS-tolerance test passes; reflection-pinned ViolationCodes.All test passes
  • CI: full pipeline

Backward compatibility

  • No public/internal API removed; IISDeployActionHandler.LooksLikeWindowsOsString and MachineCapabilitySet.IsWindows remain available as forwarders to WindowsOsStringHelper.IsWindows
  • No semantic behaviour change — the two existing wrappers return bit-identical results to the previous implementation (verified by the drift detector)
  • No DI / constructor / interface change in this PR

Deferred (intentional)

  • E2E for preview blocking flow (operator creates IIS release against Linux target → preview shows MissingCapability blocking reason). The unit-tier coverage of the real DeploymentPlanner + real CapabilityValidator with stubbed cache/handler provides high confidence; full E2E adds marginal value relative to the fixture-seeding cost. Can be added later as a single focused test once the preview API surface has more E2E demand.

Merge request reports

Loading