Test suite: add --config-dir isolation, --smoke-test alias, and a cold-start/close gate step
Adopted from Andre's RemSound-smoke-test-agent-brief.md - the gaps our pack didn't already cover: - --config-dir <folder>: redirect ALL user state (config, profiles, logs, cue sounds) to an explicit folder for this process only, applied at the very start of Program.Main before the layout migration runs. Lets a test exercise a real build without touching the user's live settings (the brief's safety rule 1). Works with every command. AppConfig gains SetUserDataDirectoryOverride / an override on UserDataDirectory; CommandLine.TryGetConfigDir parses it early. - --smoke-test / --smoketest: alias for --selftest, matching the brief's vocabulary. - run-tests.ps1: a cold-start + clean-close smoke (brief baseline steps 3-4) - launches the GUI minimized against an isolated --config-dir, confirms it stays up, that it used the isolated folder (real settings untouched), and that --close shuts it down with no orphan process. SKIPs cleanly if a RemSound instance is already running (machine-wide single-instance lock). Manual + --help updated for both switches. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
141c5e8ce1
commit
832ed40bf7
@@ -40,6 +40,25 @@ internal static class CommandLine
|
||||
[DllImport("kernel32.dll")] private static extern bool AttachConsole(int dwProcessId);
|
||||
private const int ATTACH_PARENT_PROCESS = -1;
|
||||
|
||||
/// <summary>The folder given after <c>--config-dir</c>, or null. Read at the very start of
|
||||
/// <see cref="Program"/> - before the layout migration and any config/profile/log/sound access -
|
||||
/// so it can redirect ALL user state via <see cref="AppConfig.SetUserDataDirectoryOverride"/>.
|
||||
/// Applies to every command (e.g. <c>--selftest --config-dir</c>, <c>--diagnostics --config-dir</c>)
|
||||
/// and to a normal GUI launch, so a test can exercise a real build without touching live settings.</summary>
|
||||
public static bool TryGetConfigDir(string[] args, out string dir)
|
||||
{
|
||||
dir = "";
|
||||
for (var i = 0; i < args.Length - 1; i++)
|
||||
{
|
||||
if (args[i].Equals("--config-dir", StringComparison.OrdinalIgnoreCase) && !args[i + 1].StartsWith('-'))
|
||||
{
|
||||
dir = args[i + 1];
|
||||
return !string.IsNullOrWhiteSpace(dir);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process the command line. Returns a non-null exit code when a do-and-exit command ran (the
|
||||
/// caller should <c>Environment.Exit</c> it); returns null to continue into the GUI launch with
|
||||
@@ -61,7 +80,7 @@ internal static class CommandLine
|
||||
return WithConsole(PrintVersion);
|
||||
case "--devices": case "--list-devices":
|
||||
return WithConsole(() => { WriteDevices(Console.Out); return 0; });
|
||||
case "--selftest": case "--self-test":
|
||||
case "--selftest": case "--self-test": case "--smoke-test": case "--smoketest":
|
||||
return WithConsole(() => SelfTest.Run(args));
|
||||
case "--diagnostics": case "--diag":
|
||||
return WithConsole(() => RunDiagnostics(ValueAfter(args, raw)));
|
||||
@@ -130,7 +149,7 @@ internal static class CommandLine
|
||||
Console.WriteLine(" --devices List all microphones, outputs and ASIO drivers,");
|
||||
Console.WriteLine(" with their formats and device ids.");
|
||||
Console.WriteLine(" --selftest [--seconds N] Run the built-in self-test - a localhost audio");
|
||||
Console.WriteLine(" round-trip plus checks of encryption, the wire format,");
|
||||
Console.WriteLine(" (or --smoke-test) round-trip plus checks of encryption, the wire format,");
|
||||
Console.WriteLine(" settings, profiles and bundled files - and report PASS/FAIL.");
|
||||
Console.WriteLine(" --diagnostics [path] Write a diagnostics report (version, config, profiles,");
|
||||
Console.WriteLine(" devices, mic-privacy check, recent log) and exit. With");
|
||||
@@ -145,6 +164,10 @@ internal static class CommandLine
|
||||
Console.WriteLine(" --connect <ip[:port]> Start and connect to a peer at this address. With no");
|
||||
Console.WriteLine(" --profile, starts on a fresh profile connected to it.");
|
||||
Console.WriteLine(" --minimized, --tray Start minimized to the notification area.");
|
||||
Console.WriteLine(" --config-dir <folder> Use an explicit folder for this run's settings, profiles,");
|
||||
Console.WriteLine(" logs and sounds, instead of the usual location. Lets a test");
|
||||
Console.WriteLine(" exercise RemSound without touching your real settings.");
|
||||
Console.WriteLine(" Works with any command (e.g. --selftest --config-dir ...).");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Examples:");
|
||||
Console.WriteLine(" RemSound.exe --devices");
|
||||
|
||||
@@ -25,6 +25,16 @@ internal static class Program
|
||||
return;
|
||||
}
|
||||
|
||||
// --config-dir <folder> (test / portable isolation): redirect ALL user state - config,
|
||||
// profiles, logs, cue sounds - to an explicit folder for THIS process only. Applied first,
|
||||
// before the layout migration and sound consolidation below read or write the default
|
||||
// location, so a smoke test can run a real build without touching the user's settings
|
||||
// (smoke-test brief, safety rule 1).
|
||||
if (CommandLine.TryGetConfigDir(args, out var configDir))
|
||||
{
|
||||
AppConfig.SetUserDataDirectoryOverride(configDir);
|
||||
}
|
||||
|
||||
// SustainedLowLatency tells the GC to avoid full (gen 2) collections while audio is streaming.
|
||||
// Gen 0/1 collections still happen but are sub-millisecond; the long pauses that were causing
|
||||
// the receiver to fall behind in clusters of 4-5 underruns at a time were almost certainly
|
||||
|
||||
Reference in New Issue
Block a user