Esempio n. 1
0
        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);
        }