From f0b35b2b8cce271deba991677353fc6764ade6a2 Mon Sep 17 00:00:00 2001 From: Ednunp <29843396+Ednunp@users.noreply.github.com> Date: Sun, 12 Jul 2026 22:51:47 +0100 Subject: [PATCH] Tests: remove the opt-in real-service-lifecycle test Local checkpoint - NOT for public release. Ed will test the real install/service and the sound by hand, so the elevated (admin-only) install/start/stop/uninstall self-test isn't worth keeping. Removed it and its IsAdministrator helper. The headless service tests stay (parity, app-yield, send host, registration args) - those run in the gate and guard the service against drifting from the main app. Gate 26/26. Co-Authored-By: Claude Opus 4.8 --- src/RemSound.App/SelfTest.cs | 54 ------------------------------------ 1 file changed, 54 deletions(-) diff --git a/src/RemSound.App/SelfTest.cs b/src/RemSound.App/SelfTest.cs index a4b920a..5814b3d 100644 --- a/src/RemSound.App/SelfTest.cs +++ b/src/RemSound.App/SelfTest.cs @@ -66,7 +66,6 @@ internal static class SelfTest RunStep(results, "Service sender parity (crypto + Opus frame)", ServiceSenderParity); RunStep(results, "Service send host (headless stream + yield)", ServiceSendHostStream); RunStep(results, "Service registration args", ServiceRegistrationArgs); - RunStep(results, "Service real lifecycle (install/start/stop/uninstall)", ServiceRealLifecycle); RunStep(results, "Recording engine (all formats + source gate + mono)", RecordingEngine); RunStep(results, "Recording split tracks (per-peer + own)", RecordingSplitTracks); RunStep(results, "Recording churn / soak", RecordingChurn); @@ -662,59 +661,6 @@ internal static class SelfTest return File.Exists(path) ? new FileInfo(path).Length : 0; } - /// The REAL Windows-service lifecycle end to end: install → started → stopped → uninstalled, - /// driving the actual SCM (sc.exe + ServiceController). Needs administrator rights, so it's OPT-IN via - /// REMSOUND_TEST_SERVICE=1 and skips cleanly otherwise — the normal gate runs unprivileged. It clears - /// any leftover registration first (so a stray copy from an aborted run can't fail it) and always - /// removes the service afterwards, even on failure. Run it elevated: - /// set REMSOUND_TEST_SERVICE=1 && RemSound.exe --selftest (from an elevated prompt) - private static string? ServiceRealLifecycle() - { - if (!string.Equals(Environment.GetEnvironmentVariable("REMSOUND_TEST_SERVICE"), "1", StringComparison.Ordinal)) - return Skip("set REMSOUND_TEST_SERVICE=1 (elevated) to run the real install/start/stop/uninstall lifecycle"); - if (!IsAdministrator()) - return Skip("the real service lifecycle needs administrator rights"); - - // Start from a known state — remove any service left over from a previous aborted run. DoUninstall - // stops it first, so this also clears a leftover RUNNING copy. - if (ServiceControl.IsInstalled()) ServiceControl.DoUninstall(); - Check(!ServiceControl.IsInstalled(), "pre-clean: no leftover RemSound service should remain"); - - try - { - Check(ServiceControl.DoInstall() == 0, "DoInstall should succeed"); - Check(ServiceControl.IsInstalled(), "the service should report installed after DoInstall"); - Check(ServiceControl.Query() == ServiceState.Stopped, "an auto-start service is Stopped until started"); - - Check(ServiceControl.DoStart() == 0, "DoStart should succeed"); - Check(ServiceControl.Query() == ServiceState.Running, "the service should be Running after DoStart"); - - Check(ServiceControl.DoStop() == 0, "DoStop should succeed"); - Check(ServiceControl.Query() == ServiceState.Stopped, "the service should be Stopped after DoStop"); - - Check(ServiceControl.DoUninstall() == 0, "DoUninstall should succeed"); - Check(!ServiceControl.IsInstalled(), "the service should be gone after DoUninstall"); - - return "installed → started → stopped → uninstalled (real SCM)"; - } - finally - { - // Safety net: never leave a service registered (its binPath would point at a throwaway exe). - try { if (ServiceControl.IsInstalled()) ServiceControl.DoUninstall(); } catch { /* best-effort */ } - } - } - - private static bool IsAdministrator() - { - try - { - using var id = System.Security.Principal.WindowsIdentity.GetCurrent(); - return new System.Security.Principal.WindowsPrincipal(id) - .IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator); - } - catch { return false; } - } - /// The sc.exe "create" argument string quotes a spaced exe path correctly — a real footgun /// (a broken binPath silently installs a service that can't start). Pure/side-effect-free, so it /// never touches the SCM or needs admin.