xamarin-macios/tests/run-with-timeout.csharp

83 строки
2.6 KiB
Plaintext
Executable File

#!/usr/bin/env /Library/Frameworks/Mono.framework/Commands/csharp -s
// arguments are: <platform> <outputPath>
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Xml;
var args = Environment.GetCommandLineArgs ();
var initialArgumentCount = 3;
if (args.Length <= initialArgumentCount + 1 /* 3 default arguments (executable + script + -s) */) {
// first arg is "/Library/Frameworks/Mono.framework/Versions/4.8.0/lib/mono/4.5/csharp.exe"
// second arg the script itself
// third argument is -s
// then comes the ones we care about
Console.WriteLine ($"Need two arguments (the timeout + the command to launch), got {args.Length - initialArgumentCount} argument(s)");
Environment.Exit (1);
return;
}
var launchTimeout = TimeSpan.FromSeconds (10); // must launch within a few seconds.
var argIndex = initialArgumentCount;
var executionTimeout = TimeSpan.FromSeconds (int.Parse (args [argIndex++]));
var commands = args.Skip (argIndex).ToArray ();
var pid = Process.GetCurrentProcess ().Id;
var maxLaunchAttempts = 10;
var exitCode = -1;
for (var attempt = 0; attempt < maxLaunchAttempts; attempt++) {
var launchTimeoutFile = Path.GetFullPath ($"launch-timeout-sentinel-{pid}-{attempt}.txt");
var launchTimedOut = new ManualResetEvent (false);
var p = new Process ();
var launchTimer = new Thread (() => {
if (p.WaitForExit ((int) launchTimeout.TotalMilliseconds)) {
Console.WriteLine ($"App finished before launch timeout triggered.");
} else if (!File.Exists (launchTimeoutFile)) {
Console.WriteLine ($"Launch timed out after {launchTimeout.TotalSeconds} seconds.");
launchTimedOut.Set ();
p.Kill ();
}
}) {
IsBackground = true,
};
try {
p.StartInfo.FileName = commands [0];
p.StartInfo.Arguments = string.Join (" ", commands.Skip (1));
p.StartInfo.UseShellExecute = false;
p.StartInfo.EnvironmentVariables ["LAUNCH_SENTINEL_FILE"] = launchTimeoutFile;
Console.WriteLine ($"Launching (attempt #{attempt + 1}):");
Console.WriteLine ($" {p.StartInfo.FileName} {p.StartInfo.Arguments}");
p.Start ();
launchTimer.Start ();
if (!p.WaitForExit ((int) executionTimeout.TotalMilliseconds)) {
Console.WriteLine ($"Execution timed out after {executionTimeout.TotalSeconds} seconds.");
p.Kill ();
p.WaitForExit ();
}
launchTimer.Join ();
exitCode = p.ExitCode;
if (launchTimedOut.WaitOne (0)) {
Console.WriteLine ($"Launching again since the launch timeout triggered.");
continue;
}
Console.WriteLine ($"Execution completed with exit code {exitCode}");
} finally {
File.Delete (launchTimeoutFile);
p.Dispose ();
}
break;
}
Environment.Exit (exitCode);