vPOD: real-launch auto-restart watchdog + optional postinstall.bat
Two additions to the virtual launcher's real-process mode: - Auto-restart watchdog. Replaces the poll-on-query PruneExitedProcesses with a per-process watcher thread (StartWatcher): when a real-launched app exits on its own -- not via a Kill*/Uninstall, which untrack it first -- it is dropped from the running list and, if its LaunchData has AutoRestart and the "Auto-restart after the app exits (watchdog)" toggle is on, relaunched after the Agent's 2 s delay. A watchdog generation counter cancels pending restarts when the pod goes dark (power off / reboot / reprovision / WipeApps); the console's KillAllApps leaves them pending, matching the real Agent's race. - postinstall.bat toggle. A "Run postinstall.bat after install" checkbox (above "Actually launch apps", off by default) makes an install execute a packaged postinstall.bat via cmd /c (waited up to 5 min) before deleting it, like the real service. Off, it is logged and removed unrun as before -- it runs package script code on the host. Both are opt-in from the vPOD window. Verified against the real LauncherRpcServer over a loopback socket: the watchdog test relaunches an exited ping.exe with a new PID and stops once toggled off; a crafted package's postinstall.bat runs (and is removed) only when enabled. Full differential suite 103/103. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -230,6 +230,50 @@ namespace TeslaConsole.DiffTests
|
||||
Assert.Empty(mClient.GetLaunchedApps());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RealLaunch_Watchdog_Restarts_AutoRestart_Apps_That_Exit_On_Their_Own()
|
||||
{
|
||||
mLauncher.RealLaunch = true;
|
||||
mLauncher.RealAutoRestart = true;
|
||||
var app = new LaunchData
|
||||
{
|
||||
LaunchPair = new LaunchPair { LaunchKey = Guid.NewGuid(), DisplayName = "Short Pinger" },
|
||||
WorkingDirectory = Environment.SystemDirectory,
|
||||
ExeFile = Path.Combine(Environment.SystemDirectory, "ping.exe"),
|
||||
Arguments = "-n 3 127.0.0.1", // exits on its own after ~2 s
|
||||
AutoRestart = true
|
||||
};
|
||||
mClient.InstallApp(app);
|
||||
int firstPid = mClient.LaunchApp(app.LaunchPair.LaunchKey);
|
||||
Assert.True(firstPid > 0);
|
||||
|
||||
// The app exits by itself; the watchdog must bring up a NEW pid
|
||||
// (exit ~2 s + the Agent's 2 s restart delay).
|
||||
int restartedPid = 0;
|
||||
var deadline = DateTime.UtcNow + TimeSpan.FromSeconds(20);
|
||||
while (DateTime.UtcNow < deadline)
|
||||
{
|
||||
var launched = mClient.GetLaunchedApps();
|
||||
if (launched.Length == 1 && launched[0].ProcessId != firstPid)
|
||||
{
|
||||
restartedPid = launched[0].ProcessId;
|
||||
break;
|
||||
}
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
Assert.True(restartedPid > 0, "watchdog did not restart the exited app");
|
||||
|
||||
// Turning the watchdog off ends the cycle: the current instance
|
||||
// exits on its own and nothing relaunches it.
|
||||
mLauncher.RealAutoRestart = false;
|
||||
deadline = DateTime.UtcNow + TimeSpan.FromSeconds(15);
|
||||
while (DateTime.UtcNow < deadline && mClient.GetLaunchedApps().Length > 0)
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
Assert.Empty(mClient.GetLaunchedApps());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RealLaunch_Missing_Exe_Surfaces_The_Agents_Error()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user