protected bool RunEditorAndWaitForMapLoad(bool bIsWarming) { string ProjectArg = ProjectFile != null?ProjectFile.ToString() : ""; string EditorPath = HostPlatform.Current.GetUE4ExePath("UE4Editor.exe"); string LogArg = string.Format("-log={0}.log", MakeValidFileName(GetFullTaskName()).Replace(" ", "_")); string Arguments = string.Format("{0} {1} -execcmds=\"automation runtest System.Maps.PIE;Quit\" -stdout -FullStdOutLogOutput -unattended {2}", ProjectArg, EditorArgs, LogArg); if (TaskOptions.HasFlag(DDCTaskOptions.NoSharedDDC)) { Arguments += (" -ddc=noshared"); } if (!bIsWarming && TaskOptions.HasFlag(DDCTaskOptions.NoShaderDDC)) { Arguments += (" -noshaderddc"); } if (TaskOptions.HasFlag(DDCTaskOptions.NoXGE)) { Arguments += (" -noxgeshadercompile"); } var RunOptions = CommandUtils.ERunOptions.AllowSpew | CommandUtils.ERunOptions.NoWaitForExit; var SpewDelegate = new ProcessResult.SpewFilterCallbackType(EndOnMapCheckFilter); //TestCompleted = false; LastStdOutTime = DateTime.Now; CurrentProcess = CommandUtils.Run(EditorPath, Arguments, Options: RunOptions, SpewFilterCallback: SpewDelegate); DateTime StartTime = DateTime.Now; int MaxWaitMins = 90; while (!CurrentProcess.HasExited) { Thread.Sleep(5 * 1000); lock (CurrentProcess) { if ((LastStdOutTime - StartTime).TotalMinutes >= MaxWaitMins) { Log.TraceError("Gave up waiting for task after {0} minutes of no output", MaxWaitMins); CurrentProcess.ProcessObject.Kill(); } } } int ExitCode = CurrentProcess.ExitCode; CurrentProcess = null; return(ExitCode == 0); }
/// <summary> /// Runs external program and writes the output to a logfile. /// </summary> /// <param name="App">Executable to run</param> /// <param name="CommandLine">Commandline to pass on to the executable</param> /// <param name="Logfile">Full path to the logfile, where the application output should be written to.</param> /// <param name="FilterCallback">Callback to filter log spew before output.</param> /// <returns>Whether the program executed successfully or not.</returns> public static string RunAndLog(string App, string CommandLine, out int SuccessCode, string Logfile = null, Dictionary <string, string> EnvVars = null, ProcessResult.SpewFilterCallbackType SpewFilterCallback = null) { IProcessResult Result = Run(App, CommandLine, Env: EnvVars, SpewFilterCallback: SpewFilterCallback); SuccessCode = Result.ExitCode; if (Result.Output.Length > 0 && Logfile != null) { WriteToFile(Logfile, Result.Output); } if (!String.IsNullOrEmpty(Result.Output)) { return(Result.Output); } return(""); }
/// <summary> /// Runs external program and writes the output to a logfile. /// </summary> /// <param name="Env">Environment to use.</param> /// <param name="App">Executable to run</param> /// <param name="CommandLine">Commandline to pass on to the executable</param> /// <param name="LogName">Name of the logfile ( if null, executable name is used )</param> /// <param name="FilterCallback">Callback to filter log spew before output.</param> /// <returns>Whether the program executed successfully or not.</returns> public static string RunAndLog(CommandEnvironment Env, string App, string CommandLine, out int SuccessCode, string LogName = null, Dictionary <string, string> EnvVars = null, ProcessResult.SpewFilterCallbackType SpewFilterCallback = null) { return(RunAndLog(App, CommandLine, out SuccessCode, GetRunAndLogOnlyName(Env, App, LogName), EnvVars, SpewFilterCallback)); }
/// <summary> /// Runs external program and writes the output to a logfile. /// </summary> /// <param name="App">Executable to run</param> /// <param name="CommandLine">Commandline to pass on to the executable</param> /// <param name="Logfile">Full path to the logfile, where the application output should be written to.</param> /// <param name="Input">Optional Input for the program (will be provided as stdin)</param> /// <param name="Options">Defines the options how to run. See ERunOptions.</param> /// <param name="FilterCallback">Callback to filter log spew before output.</param> public static string RunAndLog(string App, string CommandLine, string Logfile = null, int MaxSuccessCode = 0, string Input = null, ERunOptions Options = ERunOptions.Default, Dictionary <string, string> EnvVars = null, ProcessResult.SpewFilterCallbackType SpewFilterCallback = null) { IProcessResult Result = Run(App, CommandLine, Input, Options, EnvVars, SpewFilterCallback); if (Result.Output.Length > 0 && Logfile != null) { WriteToFile(Logfile, Result.Output); } else if (Logfile == null) { Logfile = "[No logfile specified]"; } else { Logfile = "[None!, no output produced]"; } if (Result.ExitCode > MaxSuccessCode || Result.ExitCode < 0) { throw new CommandFailedException((ExitCode)Result.ExitCode, String.Format("Command failed (Result:{3}): {0} {1}. See logfile for details: '{2}' ", App, CommandLine, Path.GetFileName(Logfile), Result.ExitCode)); } if (Result.Output.Length > 0) { return(Result.Output); } return(""); }
/// <summary> /// Runs external program and writes the output to a logfile. /// </summary> /// <param name="Env">Environment to use.</param> /// <param name="App">Executable to run</param> /// <param name="CommandLine">Commandline to pass on to the executable</param> /// <param name="LogName">Name of the logfile ( if null, executable name is used )</param> /// <param name="Input">Optional Input for the program (will be provided as stdin)</param> /// <param name="Options">Defines the options how to run. See ERunOptions.</param> /// <param name="FilterCallback">Callback to filter log spew before output.</param> public static void RunAndLog(CommandEnvironment Env, string App, string CommandLine, string LogName = null, int MaxSuccessCode = 0, string Input = null, ERunOptions Options = ERunOptions.Default, Dictionary <string, string> EnvVars = null, ProcessResult.SpewFilterCallbackType SpewFilterCallback = null) { RunAndLog(App, CommandLine, GetRunAndLogOnlyName(Env, App, LogName), MaxSuccessCode, Input, Options, EnvVars, SpewFilterCallback); }
/// <summary> /// Runs external program. /// </summary> /// <param name="App">Program filename.</param> /// <param name="CommandLine">Commandline</param> /// <param name="Input">Optional Input for the program (will be provided as stdin)</param> /// <param name="Options">Defines the options how to run. See ERunOptions.</param> /// <param name="Env">Environment to pass to program.</param> /// <param name="FilterCallback">Callback to filter log spew before output.</param> /// <returns>Object containing the exit code of the program as well as it's stdout output.</returns> public static IProcessResult Run(string App, string CommandLine = null, string Input = null, ERunOptions Options = ERunOptions.Default, Dictionary <string, string> Env = null, ProcessResult.SpewFilterCallbackType SpewFilterCallback = null) { App = ConvertSeparators(PathSeparator.Default, App); // Get the log name before allowing the platform to modify the app/command-line. We want mono apps to be written to a log named after the application and appear with the application prefix rather than "mono:". string LogName = Path.GetFileNameWithoutExtension(App); HostPlatform.Current.SetupOptionsForRun(ref App, ref Options, ref CommandLine); if (App == "ectool" || App == "zip" || App == "xcodebuild") { Options &= ~ERunOptions.AppMustExist; } // Check if the application exists, including the PATH directories. if (Options.HasFlag(ERunOptions.AppMustExist) && !FileExists(Options.HasFlag(ERunOptions.NoLoggingOfRunCommand) ? true : false, App)) { bool bExistsInPath = false; if (!App.Contains(Path.DirectorySeparatorChar) && !App.Contains(Path.AltDirectorySeparatorChar)) { string[] PathDirectories = Environment.GetEnvironmentVariable("PATH").Split(Path.PathSeparator); foreach (string PathDirectory in PathDirectories) { string TryApp = Path.Combine(PathDirectory, App); if (FileExists(Options.HasFlag(ERunOptions.NoLoggingOfRunCommand), TryApp)) { App = TryApp; bExistsInPath = true; break; } } } if (!bExistsInPath) { throw new AutomationException("BUILD FAILED: Couldn't find the executable to Run: {0}", App); } } var StartTime = DateTime.UtcNow; UnrealBuildTool.LogEventType SpewVerbosity = Options.HasFlag(ERunOptions.SpewIsVerbose) ? UnrealBuildTool.LogEventType.Verbose : UnrealBuildTool.LogEventType.Console; if (!Options.HasFlag(ERunOptions.NoLoggingOfRunCommand)) { LogWithVerbosity(SpewVerbosity, "Run: " + App + " " + (String.IsNullOrEmpty(CommandLine) ? "" : CommandLine)); } IProcessResult Result = ProcessManager.CreateProcess(App, Options.HasFlag(ERunOptions.AllowSpew), LogName, Env, SpewVerbosity: SpewVerbosity, SpewFilterCallback: SpewFilterCallback); Process Proc = Result.ProcessObject; bool bRedirectStdOut = (Options & ERunOptions.NoStdOutRedirect) != ERunOptions.NoStdOutRedirect; Proc.StartInfo.FileName = App; Proc.StartInfo.Arguments = String.IsNullOrEmpty(CommandLine) ? "" : CommandLine; Proc.StartInfo.UseShellExecute = false; if (bRedirectStdOut) { Proc.StartInfo.RedirectStandardOutput = true; Proc.StartInfo.RedirectStandardError = true; Proc.OutputDataReceived += Result.StdOut; Proc.ErrorDataReceived += Result.StdErr; } Proc.StartInfo.RedirectStandardInput = Input != null; Proc.StartInfo.CreateNoWindow = true; if ((Options & ERunOptions.UTF8Output) == ERunOptions.UTF8Output) { Proc.StartInfo.StandardOutputEncoding = new System.Text.UTF8Encoding(false, false); } Proc.Start(); if (bRedirectStdOut) { Proc.BeginOutputReadLine(); Proc.BeginErrorReadLine(); } if (String.IsNullOrEmpty(Input) == false) { Proc.StandardInput.WriteLine(Input); Proc.StandardInput.Close(); } if (!Options.HasFlag(ERunOptions.NoWaitForExit)) { Result.WaitForExit(); var BuildDuration = (DateTime.UtcNow - StartTime).TotalMilliseconds; AddRunTime(App, (int)(BuildDuration)); Result.ExitCode = Proc.ExitCode; if (!Options.HasFlag(ERunOptions.NoLoggingOfRunCommand) || Options.HasFlag(ERunOptions.LoggingOfRunDuration)) { LogWithVerbosity(SpewVerbosity, "Run: Took {0}s to run {1}, ExitCode={2}", BuildDuration / 1000, Path.GetFileName(App), Result.ExitCode); } Result.OnProcessExited(); Result.DisposeProcess(); } else { Result.ExitCode = -1; } return(Result); }
/// <summary> /// Creates a new process and adds it to the tracking list. /// </summary> /// <returns>New Process objects</returns> public static IProcessResult CreateProcess(string AppName, bool bAllowSpew, string LogName, Dictionary <string, string> Env = null, UnrealBuildTool.LogEventType SpewVerbosity = UnrealBuildTool.LogEventType.Console, ProcessResult.SpewFilterCallbackType SpewFilterCallback = null) { var NewProcess = HostPlatform.Current.CreateProcess(LogName); if (Env != null) { foreach (var EnvPair in Env) { if (NewProcess.StartInfo.EnvironmentVariables.ContainsKey(EnvPair.Key)) { NewProcess.StartInfo.EnvironmentVariables.Remove(EnvPair.Key); } if (!String.IsNullOrEmpty(EnvPair.Value)) { NewProcess.StartInfo.EnvironmentVariables.Add(EnvPair.Key, EnvPair.Value); } } } var Result = new ProcessResult(AppName, NewProcess, bAllowSpew, LogName, SpewVerbosity: SpewVerbosity, InSpewFilterCallback: SpewFilterCallback); AddProcess(Result); return(Result); }
/// <summary> /// Runs external program. /// </summary> /// <param name="App">Program filename.</param> /// <param name="CommandLine">Commandline</param> /// <param name="Input">Optional Input for the program (will be provided as stdin)</param> /// <param name="Options">Defines the options how to run. See ERunOptions.</param> /// <param name="Env">Environment to pass to program.</param> /// <param name="FilterCallback">Callback to filter log spew before output.</param> /// <returns>Object containing the exit code of the program as well as it's stdout output.</returns> public static IProcessResult Run(string App, string CommandLine = null, string Input = null, ERunOptions Options = ERunOptions.Default, Dictionary <string, string> Env = null, ProcessResult.SpewFilterCallbackType SpewFilterCallback = null, string Identifier = null) { App = ConvertSeparators(PathSeparator.Default, App); HostPlatform.Current.SetupOptionsForRun(ref App, ref Options, ref CommandLine); if (App == "ectool" || App == "zip" || App == "xcodebuild") { Options &= ~ERunOptions.AppMustExist; } // Check if the application exists, including the PATH directories. if (Options.HasFlag(ERunOptions.AppMustExist) && !FileExists(Options.HasFlag(ERunOptions.NoLoggingOfRunCommand) ? true : false, App)) { string ResolvedPath = WhichApp(App); if (string.IsNullOrEmpty(ResolvedPath)) { throw new AutomationException("BUILD FAILED: Couldn't find the executable to run: {0}", App); } App = ResolvedPath; } var StartTime = DateTime.UtcNow; LogEventType SpewVerbosity = Options.HasFlag(ERunOptions.SpewIsVerbose) ? LogEventType.Verbose : LogEventType.Console; if (!Options.HasFlag(ERunOptions.NoLoggingOfRunCommand)) { LogWithVerbosity(SpewVerbosity, "Running: " + App + " " + (String.IsNullOrEmpty(CommandLine) ? "" : CommandLine)); } string PrevIndent = null; if (Options.HasFlag(ERunOptions.AllowSpew)) { PrevIndent = Tools.DotNETCommon.Log.Indent; Tools.DotNETCommon.Log.Indent += " "; } IProcessResult Result = ProcessManager.CreateProcess(App, Options.HasFlag(ERunOptions.AllowSpew), !Options.HasFlag(ERunOptions.NoStdOutCapture), Env, SpewVerbosity: SpewVerbosity, SpewFilterCallback: SpewFilterCallback); try { Process Proc = Result.ProcessObject; bool bRedirectStdOut = (Options & ERunOptions.NoStdOutRedirect) != ERunOptions.NoStdOutRedirect; Proc.StartInfo.FileName = App; Proc.StartInfo.Arguments = String.IsNullOrEmpty(CommandLine) ? "" : CommandLine; Proc.StartInfo.UseShellExecute = false; if (bRedirectStdOut) { Proc.StartInfo.RedirectStandardOutput = true; Proc.StartInfo.RedirectStandardError = true; Proc.OutputDataReceived += Result.StdOut; Proc.ErrorDataReceived += Result.StdErr; } Proc.StartInfo.RedirectStandardInput = Input != null; Proc.StartInfo.CreateNoWindow = (Options & ERunOptions.NoHideWindow) == 0; if ((Options & ERunOptions.UTF8Output) == ERunOptions.UTF8Output) { Proc.StartInfo.StandardOutputEncoding = new System.Text.UTF8Encoding(false, false); } Proc.Start(); if (bRedirectStdOut) { Proc.BeginOutputReadLine(); Proc.BeginErrorReadLine(); } if (String.IsNullOrEmpty(Input) == false) { Proc.StandardInput.WriteLine(Input); Proc.StandardInput.Close(); } if (!Options.HasFlag(ERunOptions.NoWaitForExit)) { Result.WaitForExit(); } else { Result.ExitCode = -1; } } finally { if (PrevIndent != null) { Tools.DotNETCommon.Log.Indent = PrevIndent; } } if (!Options.HasFlag(ERunOptions.NoWaitForExit)) { var BuildDuration = (DateTime.UtcNow - StartTime).TotalMilliseconds; //AddRunTime(App, (int)(BuildDuration)); Result.ExitCode = Result.ProcessObject.ExitCode; if (!Options.HasFlag(ERunOptions.NoLoggingOfRunCommand) || Options.HasFlag(ERunOptions.LoggingOfRunDuration)) { LogWithVerbosity(SpewVerbosity, "Took {0}s to run {1}, ExitCode={2}", BuildDuration / 1000, Path.GetFileName(App), Result.ExitCode); } Result.OnProcessExited(); Result.DisposeProcess(); } return(Result); }