/// <summary> /// Setup a NamedEventWaitHandle that will be used to signal the end of /// all tests and the need to shutdown all launched servers. /// </summary> public LauncherFixture() { string ewhAllSuspendName = Guid.NewGuid().ToString(); var args = new string[] { $"ewhAllSuspend={ewhAllSuspendName}" }; ewh = new NamedEventWaitHandle(false, EventResetMode.ManualReset, ewhAllSuspendName); new TLauncher().Launch(args, false, false); }
/// <summary> /// Builds a dictionary of Launchable objects, which contains all of the relevant /// information for launching the web applications /// </summary> /// <param name="args">global arguments</param> /// <param name="programMains">an array of Program.Main methods to invoke</param> /// <param name="dirs">a dictionary of project locations, keyed by the project names</param> /// <returns></returns> private static Dictionary <string, Launchable> InitializeLaunchables(string[] args, Action <string[]>[] programMains, Dictionary <string, string> dirs) { var launchables = new Dictionary <string, Launchable>(); var kvpArgs = args .Where(a => a.Contains("=")) .Select(a => new KeyValuePair <string, string>(a.Split('=')[0], a.Split('=')[1])) .ToDictionary(x => x.Key, x => x.Value); NamedEventWaitHandle ewhReady = null; NamedEventWaitHandle ewhAllSuspend = null; //used with pinging -- may not be needed ewhReady = new NamedEventWaitHandle(false, EventResetMode.ManualReset); //used to suspend all web application from the caller (typically xunit runner/test host) if (kvpArgs.TryGetValue("ewhAllSuspend", out string ewhAllSuspendName)) { ewhAllSuspend = new NamedEventWaitHandle(false, EventResetMode.ManualReset, ewhAllSuspendName); } //loop over all Program.Main methods, building a launchable for each method foreach (var programMain in programMains) { var projectName = programMain.Method.DeclaringType.Assembly.GetName().Name; var launchable = new Launchable { ProgramMain = programMain, LaunchProfile = new LaunchProfile(), ReadyEvent = ewhReady, AllSuspendEvent = ewhAllSuspend }; //the full launch profile will be retrieved and populated later. //For now, just store the requested profile name. if (kvpArgs.TryGetValue(projectName, out string requestedProfile)) { launchable.LaunchProfile.Name = requestedProfile; } else { throw new ArgumentException($"Launch profile name not supplied for {projectName}. Launcher requires a command-line argument like {projectName}=MyLaunchProfile with a valid launch profile name. This also applies to other launched projects. They must have a launch profile as a commandline argument, keyed by the project name."); } //set the project directory. if (dirs.TryGetValue(projectName, out string dir)) { launchable.ProjectDirectory = dir; } else { throw new ArgumentException($"{projectName} not a referenced project in Launcher's .csproj"); } launchables.Add(projectName, launchable); } return(launchables); }