private static void RunClientWithServer(List <DeploymentContext> DeployContextList, string ServerLogFile, IProcessResult ServerProcess, string ClientApp, string ClientCmdLine, ERunOptions ClientRunFlags, string ClientLogFile, ProjectParams Params)
    {
        IProcessResult ClientProcess = null;
        var            OtherClients  = new List <IProcessResult>();

        bool   WelcomedCorrectly = false;
        int    NumClients        = Params.NumClients;
        string AllClientOutput   = "";
        int    LastAutoFailIndex = -1;

        if (Params.Unattended)
        {
            string LookFor = "Bringing up level for play took";
            if (Params.DedicatedServer)
            {
                LookFor = "Welcomed by server";
            }
            else if (Params.RunAutomationTest != "")
            {
                LookFor = "Automation Test Succeeded";
            }
            else if (Params.RunAutomationTests)
            {
                LookFor = "Automation Test Queue Empty";
            }
            {
                while (!FileExists(ServerLogFile) && !ServerProcess.HasExited)
                {
                    LogInformation("Waiting for logging process to start...");
                    Thread.Sleep(2000);
                }
                Thread.Sleep(1000);

                string AllServerOutput = "";
                using (FileStream ProcessLog = File.Open(ServerLogFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    StreamReader LogReader    = new StreamReader(ProcessLog);
                    bool         bKeepReading = true;

                    FileStream   ClientProcessLog = null;
                    StreamReader ClientLogReader  = null;

                    // Read until the process has exited.
                    while (!ServerProcess.HasExited && bKeepReading)
                    {
                        while (!LogReader.EndOfStream && bKeepReading && ClientProcess == null)
                        {
                            string Output = LogReader.ReadToEnd();
                            if (!String.IsNullOrEmpty(Output))
                            {
                                AllServerOutput += Output;
                                if (ClientProcess == null &&
                                    (AllServerOutput.Contains("Game Engine Initialized") || AllServerOutput.Contains("Unreal Network File Server is ready")))
                                {
                                    LogInformation("Starting Client for unattended test....");
                                    ClientProcess = Run(ClientApp, ClientCmdLine + " -testexit=\"" + LookFor + "\"", null, ClientRunFlags | ERunOptions.NoWaitForExit);
                                    //@todo no testing is done on these
                                    if (NumClients > 1 && NumClients < 9)
                                    {
                                        for (int i = 1; i < NumClients; i++)
                                        {
                                            LogInformation("Starting Extra Client....");
                                            OtherClients.Add(Run(ClientApp, ClientCmdLine, null, ClientRunFlags | ERunOptions.NoWaitForExit));
                                        }
                                    }
                                    while (!FileExists(ClientLogFile) && !ClientProcess.HasExited)
                                    {
                                        LogInformation("Waiting for client logging process to start...{0}", ClientLogFile);
                                        Thread.Sleep(2000);
                                    }
                                    if (!ClientProcess.HasExited)
                                    {
                                        Thread.Sleep(2000);
                                        LogInformation("Client logging process started...{0}", ClientLogFile);
                                        ClientProcessLog = File.Open(ClientLogFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                                        ClientLogReader  = new StreamReader(ClientProcessLog);
                                    }
                                }
                                else if (ClientProcess == null && !ServerProcess.HasExited)
                                {
                                    LogInformation("Waiting for server to start....");
                                    Thread.Sleep(2000);
                                }
                                if (ClientProcess != null && ClientProcess.HasExited)
                                {
                                    ServerProcess.StopProcess();
                                    throw new AutomationException("Client exited before we asked it to.");
                                }
                            }
                        }
                        if (ClientLogReader != null)
                        {
                            if (ClientProcess.HasExited)
                            {
                                ServerProcess.StopProcess();
                                throw new AutomationException("Client exited or closed the log before we asked it to.");
                            }
                            while (!ClientProcess.HasExited && !ServerProcess.HasExited && bKeepReading)
                            {
                                while (!ClientLogReader.EndOfStream && bKeepReading && !ServerProcess.HasExited && !ClientProcess.HasExited)
                                {
                                    string ClientOutput = ClientLogReader.ReadToEnd();
                                    if (!String.IsNullOrEmpty(ClientOutput))
                                    {
                                        AllClientOutput += ClientOutput;
                                        Console.Write(ClientOutput);

                                        if (AllClientOutput.LastIndexOf(LookFor) > AllClientOutput.IndexOf(LookFor))
                                        {
                                            if (Params.FakeClient)
                                            {
                                                LogInformation("Welcomed by server or client loaded, lets wait ten minutes...");
                                                Thread.Sleep(60000 * 10);
                                            }
                                            else
                                            {
                                                LogInformation("Welcomed by server or client loaded, lets wait 30 seconds...");
                                                Thread.Sleep(30000);
                                            }
                                            WelcomedCorrectly = true;
                                            bKeepReading      = false;
                                        }
                                        else if (Params.RunAutomationTests)
                                        {
                                            int FailIndex  = AllClientOutput.LastIndexOf("Automation Test Failed");
                                            int ParenIndex = AllClientOutput.LastIndexOf(")");
                                            if (FailIndex >= 0 && ParenIndex > FailIndex && FailIndex > LastAutoFailIndex)
                                            {
                                                string Tail            = AllClientOutput.Substring(FailIndex);
                                                int    CloseParenIndex = Tail.IndexOf(")");
                                                int    OpenParenIndex  = Tail.IndexOf("(");
                                                string Test            = "";
                                                if (OpenParenIndex >= 0 && CloseParenIndex > OpenParenIndex)
                                                {
                                                    Test = Tail.Substring(OpenParenIndex + 1, CloseParenIndex - OpenParenIndex - 1);
                                                    LogError("Automated test failed ({0}).", Test);
                                                    LastAutoFailIndex = FailIndex;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        else
        {
            LogFileReaderProcess(ServerLogFile, ServerProcess, (string Output) =>
            {
                bool bKeepReading = true;
                if (ClientProcess == null && !String.IsNullOrEmpty(Output))
                {
                    AllClientOutput += Output;
                    if (AllClientOutput.Contains("Game Engine Initialized") || AllClientOutput.Contains("Unreal Network File Server is ready"))
                    {
                        LogInformation("Starting Client....");
                        var SC        = DeployContextList[0];
                        ClientProcess = SC.StageTargetPlatform.RunClient(ClientRunFlags | ERunOptions.NoWaitForExit, ClientApp, ClientCmdLine, Params);
//						ClientProcess = Run(ClientApp, ClientCmdLine, null, ClientRunFlags | ERunOptions.NoWaitForExit);
                        if (NumClients > 1 && NumClients < 9)
                        {
                            for (int i = 1; i < NumClients; i++)
                            {
                                LogInformation("Starting Extra Client....");
                                IProcessResult NewClient = SC.StageTargetPlatform.RunClient(ClientRunFlags | ERunOptions.NoWaitForExit, ClientApp, ClientCmdLine, Params);
                                OtherClients.Add(NewClient);
                            }
                        }
                    }
                }
                else if (ClientProcess == null && !ServerProcess.HasExited)
                {
                    LogInformation("Waiting for server to start....");
                    Thread.Sleep(2000);
                }

                if (String.IsNullOrEmpty(Output) == false)
                {
                    Console.Write(Output);
                }

                if (ClientProcess != null && ClientProcess.HasExited)
                {
                    LogInformation("Client exited, stopping server....");
                    if (!GlobalCommandLine.NoKill)
                    {
                        ServerProcess.StopProcess();
                    }
                    bKeepReading = false;
                }

                return(bKeepReading);                // Keep reading
            });
        }
        LogInformation("Server exited....");
        if (ClientProcess != null && !ClientProcess.HasExited)
        {
            ClientProcess.StopProcess();
        }
        foreach (var OtherClient in OtherClients)
        {
            if (OtherClient != null && !OtherClient.HasExited)
            {
                OtherClient.StopProcess();
            }
        }
        if (Params.Unattended)
        {
            if (!WelcomedCorrectly)
            {
                throw new AutomationException("Server or client exited before we asked it to.");
            }
        }
    }
コード例 #2
0
        /// <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);
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
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="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 (!String.IsNullOrEmpty(Result.Output) && 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))
                      {
                          OutputFormat = AutomationExceptionOutputFormat.Minimal
                      };
            }
            if (!String.IsNullOrEmpty(Result.Output))
            {
                return(Result.Output);
            }
            return("");
        }
コード例 #5
0
	public override IProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
	{
		if (UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
		{
            if (Params.Devices.Count != 1)
            {
                throw new AutomationException("Can only run on a single specified device, but {0} were specified", Params.Devices.Count);
            }
			
			// This code only cares about connected devices so just call the run loop a few times to get the existing connected devices
			MobileDeviceInstanceManager.Initialize(MobileDeviceConnected, MobileDeviceDisconnected);
			for(int i = 0; i < 4; ++i)
			{
				System.Threading.Thread.Sleep(1);
				CoreFoundationRunLoop.RunLoopRunInMode(CoreFoundationRunLoop.kCFRunLoopDefaultMode(), 0.25, 0);
			}
			
            /*			string AppDirectory = string.Format("{0}/Payload/{1}.app",
				Path.GetDirectoryName(Params.ProjectGameExeFilename), 
				Path.GetFileNameWithoutExtension(Params.ProjectGameExeFilename));
			string GameName = Path.GetFileNameWithoutExtension (ClientApp);
			if (GameName.Contains ("-IOS-"))
			{
				GameName = GameName.Substring (0, GameName.IndexOf ("-IOS-"));
			}
			string GameApp = AppDirectory + "/" + GameName;
			bWasGenerated = false;
			XcodeProj = EnsureXcodeProjectExists (Params.RawProjectPath, CmdEnv.LocalRoot, Params.ShortProjectName, GetDirectoryName(Params.RawProjectPath), Params.IsCodeBasedProject, out bWasGenerated);
			string Arguments = "UBT_NO_POST_DEPLOY=true /usr/bin/xcrun xcodebuild test -project \"" + XcodeProj + "\"";
			Arguments += " -scheme '";
			Arguments += GameName;
			Arguments += " - iOS'";
			Arguments += " -configuration " + Params.ClientConfigsToBuild [0].ToString();
			Arguments += " -destination 'platform=iOS,id=" + Params.Device.Substring(Params.Device.IndexOf("@")+1) + "'";
			Arguments += " TEST_HOST=\"";
			Arguments += GameApp;
			Arguments += "\" BUNDLE_LOADER=\"";
			Arguments += GameApp + "\"";*/
            string BundleIdentifier = "";
			if (File.Exists(Params.BaseStageDirectory + "/"+ PlatformName + "/Info.plist"))
			{
				string Contents = File.ReadAllText(Params.BaseStageDirectory + "/" + PlatformName + "/Info.plist");
				int Pos = Contents.IndexOf("CFBundleIdentifier");
				Pos = Contents.IndexOf("<string>", Pos) + 8;
				int EndPos = Contents.IndexOf("</string>", Pos);
				BundleIdentifier = Contents.Substring(Pos, EndPos - Pos);
			}
			string Arguments = "/usr/bin/instruments";
			Arguments += " -w '" + Params.DeviceNames[0] + "'";
			Arguments += " -t 'Activity Monitor'";
			Arguments += " -D \"" + Params.BaseStageDirectory + "/" + PlatformName + "/launch.trace\"";
			Arguments += " '" + BundleIdentifier + "'";
			IProcessResult ClientProcess = Run ("/usr/bin/env", Arguments, null, ClientRunFlags | ERunOptions.NoWaitForExit);
			return new IOSClientProcess(ClientProcess, Params.DeviceNames[0]);
		}
		else
		{
			IProcessResult Result = new ProcessResult("DummyApp", null, false, null);
			Result.ExitCode = 0;
			return Result;
		}
	}
コード例 #6
0
    public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        if (!File.Exists(ClientApp))
        {
            if (Directory.Exists(ClientApp + ".app"))
            {
                ClientApp += ".app/Contents/MacOS/" + Path.GetFileName(ClientApp);
            }
            else
            {
                Int32 BaseDirLen = Params.BaseStageDirectory.Length;
                string StageSubDir = ClientApp.Substring(BaseDirLen, ClientApp.IndexOf("/", BaseDirLen + 1) - BaseDirLen);
                ClientApp = CombinePaths(Params.BaseStageDirectory, StageSubDir, Params.ShortProjectName + ".app/Contents/MacOS/" + Params.ShortProjectName);
            }
        }

        PushDir(Path.GetDirectoryName(ClientApp));
        // Always start client process and don't wait for exit.
        ProcessResult ClientProcess = Run(ClientApp, ClientCmdLine, null, ClientRunFlags | ERunOptions.NoWaitForExit);
        PopDir();

        return ClientProcess;
    }
コード例 #7
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="Input">Optional Input for the program (will be provided as stdin)</param>
        /// <param name="Options">Defines the options how to run. See ERunOptions.</param>
        public static string RunAndLog(string App, string CommandLine, string Logfile = null, int MaxSuccessCode = 0, string Input = null, ERunOptions Options = ERunOptions.Default)
        {
            ProcessResult Result = Run(App, CommandLine, Input, Options);

            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 > MaxSuccessCode || Result < 0)
            {
                ErrorReporter.Error(String.Format("Command failed (Result:{3}): {0} {1}. See logfile for details: '{2}' ",
                                                  App, CommandLine, Path.GetFileName(Logfile), Result.ExitCode), Result.ExitCode);
                throw new AutomationException(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("");
        }
コード例 #8
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="Input">Optional Input for the program (will be provided as stdin)</param>
        /// <param name="Options">Defines the options how to run. See ERunOptions.</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 Result = Run(App, CommandLine, Input, Options, EnvVars);
            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 > MaxSuccessCode || Result < 0)
            {
                throw new AutomationException((ErrorCodes)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 "";
        }
コード例 #9
0
        /// <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>
        /// <returns>Object containing the exit code of the program as well as it's stdout output.</returns>
        public static ProcessResult Run(string App, string CommandLine = null, string Input = null, ERunOptions Options = ERunOptions.Default, Dictionary <string, string> Env = 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;
            }

            if (Options.HasFlag(ERunOptions.AppMustExist) && !FileExists(Options.HasFlag(ERunOptions.NoLoggingOfRunCommand) ? true : false, App))
            {
                throw new AutomationException("BUILD FAILED: Couldn't find the executable to Run: {0}", App);
            }
            var StartTime = DateTime.UtcNow;

            TraceEventType SpewVerbosity = Options.HasFlag(ERunOptions.SpewIsVerbose) ? TraceEventType.Verbose : TraceEventType.Information;

            if (!Options.HasFlag(ERunOptions.NoLoggingOfRunCommand))
            {
                Log(SpewVerbosity, "Run: " + App + " " + (String.IsNullOrEmpty(CommandLine) ? "" : CommandLine));
            }
            ProcessResult Result = ProcessManager.CreateProcess(App, Options.HasFlag(ERunOptions.AllowSpew), Path.GetFileNameWithoutExtension(App), Env, SpewVerbosity: SpewVerbosity);
            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))
                {
                    Log(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);
        }
コード例 #10
0
 /// <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>
 public static void RunAndLog(CommandEnvironment Env, string App, string CommandLine, string LogName = null, int MaxSuccessCode = 0, string Input = null, ERunOptions Options = ERunOptions.Default)
 {
     RunAndLog(App, CommandLine, GetRunAndLogLogName(Env, App, LogName), MaxSuccessCode, Input, Options);
 }
コード例 #11
0
    public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        string ApkName = ClientApp + GetArchitecture(Params) + ".apk";
        if (!File.Exists(ApkName))
        {
            ApkName = GetFinalApkName(Params, Path.GetFileNameWithoutExtension(ClientApp), false);
        }

        Console.WriteLine("Apk='{0}', CLientApp='{1}', ExeName='{2}'", ApkName, ClientApp, Params.ProjectGameExeFilename);

        // run aapt to get the name of the intent
        string PackageName = GetPackageInfo(ApkName, false);
        if (PackageName == null)
        {
            throw new AutomationException("Failed to get package name from " + ClientApp);
        }

        string AdbCommand = GetAdbCommand(Params);
        string CommandLine = "shell am start -n " + PackageName + "/com.epicgames.ue4.GameActivity";

        // start the app on device!
        ProcessResult ClientProcess = Run(CmdEnv.CmdExe, AdbCommand + CommandLine, null, ClientRunFlags);

        return ClientProcess;
    }
コード例 #12
0
        /// <summary>
        /// Runs a commandlet using Engine/Binaries/Win64/UE4Editor-Cmd.exe.
        /// </summary>
        /// <param name="ProjectName">Project name.</param>
        /// <param name="UE4Exe">The name of the UE4 Editor executable to use.</param>
        /// <param name="Commandlet">Commandlet name.</param>
        /// <param name="Parameters">Command line parameters (without -run=)</param>
        public static void RunCommandlet(string ProjectName, string UE4Exe, string Commandlet, string Parameters = null)
        {
            Log("Running UE4Editor {0} for project {1}", Commandlet, ProjectName);

            var CWD = Path.GetDirectoryName(UE4Exe);

            string EditorExe = UE4Exe;

            if (String.IsNullOrEmpty(CWD))
            {
                EditorExe = HostPlatform.Current.GetUE4ExePath(UE4Exe);
                CWD       = CombinePaths(CmdEnv.LocalRoot, HostPlatform.Current.RelativeBinariesFolder);
            }

            PushDir(CWD);

            string LocalLogFile = LogUtils.GetUniqueLogName(CombinePaths(CmdEnv.EngineSavedFolder, Commandlet));

            Log("Commandlet log file is {0}", LocalLogFile);
            string Args = String.Format(
                "{0} -run={1} {2} -abslog={3} -stdout -FORCELOGFLUSH -CrashForUAT -unattended {5}{4}",
                (ProjectName == null) ? "" : CommandUtils.MakePathSafeToUseWithCommandLine(ProjectName),
                Commandlet,
                String.IsNullOrEmpty(Parameters) ? "" : Parameters,
                CommandUtils.MakePathSafeToUseWithCommandLine(LocalLogFile),
                IsBuildMachine ? "-buildmachine" : "",
                GlobalCommandLine.Verbose ? "-AllowStdOutLogVerbosity" : ""
                );
            ERunOptions Opts = ERunOptions.Default;

            if (GlobalCommandLine.UTF8Output)
            {
                Args += " -UTF8Output";
                Opts |= ERunOptions.UTF8Output;
            }
            var RunResult = Run(EditorExe, Args, Options: Opts);

            PopDir();

            // Draw attention to signal exit codes on Posix systems, rather than just printing the exit code
            if (RunResult.ExitCode > 128 && RunResult.ExitCode < 128 + 32)
            {
                if (RunResult.ExitCode == 139)
                {
                    CommandUtils.LogError("Editor terminated abnormally due to a segmentation fault");
                }
                else
                {
                    CommandUtils.LogError("Editor terminated abnormally with signal {0}", RunResult.ExitCode - 128);
                }
            }

            // Copy the local commandlet log to the destination folder.
            string DestLogFile = LogUtils.GetUniqueLogName(CombinePaths(CmdEnv.LogFolder, Commandlet));

            if (!CommandUtils.CopyFile_NoExceptions(LocalLogFile, DestLogFile))
            {
                CommandUtils.LogWarning("Commandlet {0} failed to copy the local log file from {1} to {2}. The log file will be lost.", Commandlet, LocalLogFile, DestLogFile);
            }

            // Whether it was copied correctly or not, delete the local log as it was only a temporary file.
            CommandUtils.DeleteFile_NoExceptions(LocalLogFile);

            if (RunResult.ExitCode != 0)
            {
                throw new AutomationException("BUILD FAILED: Failed while running {0} for {1}; see log {2}", Commandlet, ProjectName, DestLogFile);
            }
        }
コード例 #13
0
    public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        // look for browser
        var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine"));

        string DeviceSection;

        if (Utils.IsRunningOnMono)
        {
            DeviceSection = "HTML5DevicesMac";
        }
        else
        {
            DeviceSection = "HTML5DevicesWindows";
        }

        string browserPath;
        string DeviceName = Params.Device.Split('@')[1];

        DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on "));
        bool ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath);

        if (!ok)
        {
            throw new System.Exception("Incorrect browser configuration in HTML5Engine.ini ");
        }

        // open the webpage
        string directory = Path.GetDirectoryName(ClientApp);
        string url       = Path.GetFileName(ClientApp) + ".html";
        // Are we running via cook on the fly server?
        // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not.
        bool IsCookOnTheFly = false;

        // 9/24/2014 @fixme - All this is convoluted, clean up.
        // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT)
        // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly.

        if (ClientCmdLine.Contains("filehostip"))
        {
            IsCookOnTheFly = true;
            url            = "http://127.0.0.1:41898/" + url;
        }

        if (IsCookOnTheFly)
        {
            url += "?cookonthefly=true";
        }
        else
        {
            url = "http://127.0.0.1:8000/" + url;
            // this will be killed UBT instances dies.
            string input = String.Format(" -m SimpleHTTPServer 8000");

            string        PythonPath = HTML5SDKInfo.PythonPath();
            ProcessResult Result     = ProcessManager.CreateProcess(PythonPath, true, "html5server.log");
            Result.ProcessObject.StartInfo.FileName               = PythonPath;
            Result.ProcessObject.StartInfo.UseShellExecute        = false;
            Result.ProcessObject.StartInfo.RedirectStandardOutput = true;
            Result.ProcessObject.StartInfo.RedirectStandardInput  = true;
            Result.ProcessObject.StartInfo.WorkingDirectory       = directory;
            Result.ProcessObject.StartInfo.Arguments              = input;
            Result.ProcessObject.Start();

            Result.ProcessObject.OutputDataReceived += delegate(object sender, System.Diagnostics.DataReceivedEventArgs e)
            {
                System.Console.WriteLine(e.Data);
            };

            System.Console.WriteLine("Starting Browser Process");


            // safari specific hack.
            string argument = url;
            if (browserPath.Contains("Safari") && Utils.IsRunningOnMono)
            {
                argument = "";
            }

            // Chrome issue. Firefox may work like this in the future
            bool bBrowserWillSpawnProcess = browserPath.Contains("chrome") || (browserPath.Contains("Google Chrome") && Utils.IsRunningOnMono);

            ProcessResult SubProcess    = null;
            ProcessResult ClientProcess = Run(browserPath, argument, null, ClientRunFlags | ERunOptions.NoWaitForExit);
            var           ProcStartTime = ClientProcess.ProcessObject.StartTime;
            var           ProcName      = ClientProcess.ProcessObject.ProcessName;

            ClientProcess.ProcessObject.EnableRaisingEvents = true;
            ClientProcess.ProcessObject.Exited += delegate(System.Object o, System.EventArgs e)
            {
                System.Console.WriteLine("Browser Process Ended (PID={0})", ClientProcess.ProcessObject.Id);
                var bFoundChildProcess = false;
                if (bBrowserWillSpawnProcess)
                {
                    // Chrome spawns a process from the tab it opens and then lets the process we spawned die, so
                    // catch that process and attach to that instead.
                    var CurrentProcesses = Process.GetProcesses();
                    foreach (var item in CurrentProcesses)
                    {
                        if (item.Id != ClientProcess.ProcessObject.Id && item.ProcessName == ProcName && item.StartTime >= ProcStartTime && item.StartTime <= ClientProcess.ProcessObject.ExitTime)
                        {
                            var PID = item.Id;
                            System.Console.WriteLine("Found Process {0} with PID {1} which started at {2}. Waiting on that process to end.", item.ProcessName, item.Id, item.StartTime.ToString());
                            SubProcess = new ProcessResult(item.ProcessName, item, true, item.ProcessName);
                            item.EnableRaisingEvents = true;
                            item.Exited += delegate(System.Object o2, System.EventArgs e2)
                            {
                                System.Console.WriteLine("Browser Process Ended (PID={0}) - Killing Webserver", PID);
                                Result.ProcessObject.StandardInput.Close();
                                Result.ProcessObject.Kill();
                            };
                            bFoundChildProcess = true;
                        }
                    }
                }

                if (!bFoundChildProcess)
                {
                    System.Console.WriteLine("- Killing Webserver PID({0})", Result.ProcessObject.Id);
                    Result.ProcessObject.StandardInput.Close();
                    Result.ProcessObject.Kill();
                }
            };

            if (bBrowserWillSpawnProcess)
            {
                //Wait for it to do so...
                ClientProcess.ProcessObject.WaitForExit();
                ClientProcess = SubProcess;
            }

            // safari needs a hack.
            // http://superuser.com/questions/689315/run-safari-from-terminal-with-given-url-address-without-open-command

            if (browserPath.Contains("Safari") && Utils.IsRunningOnMono)
            {
                // ClientProcess.ProcessObject.WaitForInputIdle ();
                Thread.Sleep(2000);
                Process.Start("/usr/bin/osascript", " -e 'tell application \"Safari\" to open location \"" + url + "\"'");
            }

            return(ClientProcess);
        }

        System.Console.WriteLine("Browser Path " + browserPath);
        ProcessResult BrowserProcess = Run(browserPath, url, null, ClientRunFlags | ERunOptions.NoWaitForExit);

        return(BrowserProcess);
    }
コード例 #14
0
    private static void RunStandaloneClient(List<DeploymentContext> DeployContextList, string ClientLogFile, ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        if (Params.Unattended)
        {
            string LookFor = "Bringing up level for play took";
            if (Params.RunAutomationTest != "")
            {
                LookFor = "Automation Test Succeeded";
            }
            else if (Params.RunAutomationTests)
            {
                LookFor = "Automation Test Queue Empty";
            }
            else if (Params.EditorTest)
            {
                LookFor = "Asset discovery search completed in";
            }
            {

                string AllClientOutput = "";
                int LastAutoFailIndex = -1;
                ProcessResult ClientProcess = null;
                FileStream ClientProcessLog = null;
                StreamReader ClientLogReader = null;
                Log("Starting Client for unattended test....");
                ClientProcess = Run(ClientApp, ClientCmdLine + " -FORCELOGFLUSH -testexit=\"" + LookFor + "\"", null, ClientRunFlags | ERunOptions.NoWaitForExit);
                while (!FileExists(ClientLogFile) && !ClientProcess.HasExited)
                {
                    Log("Waiting for client logging process to start...{0}", ClientLogFile);
                    Thread.Sleep(2000);
                }
                if (FileExists(ClientLogFile))
                {
                    Thread.Sleep(2000);
                    Log("Client logging process started...{0}", ClientLogFile);
                    ClientProcessLog = File.Open(ClientLogFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    ClientLogReader = new StreamReader(ClientProcessLog);
                }
                if (ClientLogReader == null)
                {
                    throw new AutomationException("Client exited without creating a log file.");
                }
                bool bKeepReading = true;
                bool WelcomedCorrectly = false;
                bool bClientExited = false;
                DateTime ExitTime = DateTime.UtcNow;

                while (bKeepReading)
                {
                    if (!bClientExited && ClientProcess.HasExited)
                    {
                        ExitTime = DateTime.UtcNow;
                        bClientExited = true;
                    }
                    string ClientOutput = ClientLogReader.ReadToEnd();
                    if (!String.IsNullOrEmpty(ClientOutput))
                    {
                        if (bClientExited)
                        {
                            ExitTime = DateTime.UtcNow; // as long as it is spewing, we reset the timer
                        }
                        AllClientOutput += ClientOutput;
                        Console.Write(ClientOutput);

                        if (AllClientOutput.LastIndexOf(LookFor) > AllClientOutput.IndexOf(LookFor))
                        {
                            WelcomedCorrectly = true;
                            Log("Test complete...");
                            bKeepReading = false;
                        }
                        else if (Params.RunAutomationTests)
                        {
                            int FailIndex = AllClientOutput.LastIndexOf("Automation Test Failed");
                            int ParenIndex = AllClientOutput.LastIndexOf(")");
                            if (FailIndex >= 0 && ParenIndex > FailIndex && FailIndex > LastAutoFailIndex)
                            {
                                string Tail = AllClientOutput.Substring(FailIndex);
                                int CloseParenIndex = Tail.IndexOf(")");
                                int OpenParenIndex = Tail.IndexOf("(");
                                string Test = "";
                                if (OpenParenIndex >= 0 && CloseParenIndex > OpenParenIndex)
                                {
                                    Test = Tail.Substring(OpenParenIndex + 1, CloseParenIndex - OpenParenIndex - 1);
                                    Log(System.Diagnostics.TraceEventType.Error, "Automated test failed ({0}).", Test);
                                    LastAutoFailIndex = FailIndex;
                                }
                            }
                        }
                    }
                    else if (bClientExited && (DateTime.UtcNow - ExitTime).TotalSeconds > 30)
                    {
                        Log("Client exited and has been quiet for 30 seconds...exiting");
                        bKeepReading = false;
                    }
                }
                if (ClientProcess != null && !ClientProcess.HasExited)
                {
                    Log("Client is supposed to exit, lets wait a while for it to exit naturally...");
                    for (int i = 0; i < 120 && !ClientProcess.HasExited; i++)
                    {
                        Thread.Sleep(1000);
                    }
                }
                if (ClientProcess != null && !ClientProcess.HasExited)
                {
                    Log("Stopping client...");
                    ClientProcess.StopProcess();
                    Thread.Sleep(10000);
                }
                while (ClientLogReader != null && !ClientLogReader.EndOfStream)
                {
                    string ClientOutput = ClientLogReader.ReadToEnd();
                    if (!String.IsNullOrEmpty(ClientOutput))
                    {
                        Console.Write(ClientOutput);
                    }
                }

                if (!WelcomedCorrectly)
                {
                    throw new AutomationException("Client exited before we asked it to.");
                }
            }
        }
        else
        {
            var SC = DeployContextList[0];
            ProcessResult ClientProcess = SC.StageTargetPlatform.RunClient(ClientRunFlags, ClientApp, ClientCmdLine, Params);
            if (ClientProcess != null)
            {
                // If the client runs without StdOut redirect we're going to read the log output directly from log file on
                // a separate thread.
                if ((ClientRunFlags & ERunOptions.NoStdOutRedirect) == ERunOptions.NoStdOutRedirect)
                {
                    ClientLogReaderThread = new System.Threading.Thread(ClientLogReaderProc);
                    ClientLogReaderThread.Start(new object[] { ClientLogFile, ClientProcess });
                }

                do
                {
                    Thread.Sleep(100);
                }
                while (ClientProcess.HasExited == false);

                SC.StageTargetPlatform.PostRunClient(ClientProcess, Params);

                if (ClientProcess.ExitCode != 0)
                {
                    throw new AutomationException("Client exited with error code: " + ClientProcess.ExitCode);
                }
            }
        }
    }
コード例 #15
0
        /// <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>
        /// <returns>Object containing the exit code of the program as well as it's stdout output.</returns>
        public static ProcessResult Run(string App, string CommandLine = null, string Input = null, ERunOptions Options = ERunOptions.Default, Dictionary<string, string> Env = null)
        {
            App = ConvertSeparators(PathSeparator.Default, App);
            HostPlatform.Current.SetupOptionsForRun(ref App, ref Options, ref CommandLine);
            if (App == "ectool" || App == "zip")
            {
                Options &= ~ERunOptions.AppMustExist;
            }

            if (Options.HasFlag(ERunOptions.AppMustExist) && !FileExists(Options.HasFlag(ERunOptions.NoLoggingOfRunCommand) ? true : false, App))
            {
                throw new AutomationException("BUILD FAILED: Couldn't find the executable to Run: {0}", App);
            }
            var StartTime = DateTime.UtcNow;

            if (!Options.HasFlag(ERunOptions.NoLoggingOfRunCommand))
            {
                Log("Run: " + App + " " + (String.IsNullOrEmpty(CommandLine) ? "" : CommandLine));

            }
            ProcessResult Result = ProcessManager.CreateProcess(Options.HasFlag(ERunOptions.AllowSpew), Path.GetFileNameWithoutExtension(App), Env);
            Process Proc = Result.ProcessObject;

            bool bRedirectStdOut = (Options & ERunOptions.NoStdOutRedirect) != ERunOptions.NoStdOutRedirect;
            Proc.EnableRaisingEvents = false;
            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;
            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));
                if (!Options.HasFlag(ERunOptions.NoLoggingOfRunCommand))
                {
                    Log("Run: Took {0}s to run " + Path.GetFileName(App), BuildDuration / 1000);

                }
                Result.ExitCode = Proc.ExitCode;
                if (UnrealBuildTool.Utils.IsRunningOnMono)
                {
                    // Mono's detection of process exit status is broken. It doesn't clean up after the process and it doesn't call Exited callback.
                    Proc.Dispose();
                    ProcessManager.NewProcess_Exited(Proc, null);
                }
            }
            else
            {
                Result.ExitCode = -1;
            }

            return Result;
        }
コード例 #16
0
        /// <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>
        /// <returns>Object containing the exit code of the program as well as it's stdout output.</returns>
        public static ProcessResult Run(string App, string CommandLine = null, string Input = null, ERunOptions Options = ERunOptions.Default, Dictionary<string, string> Env = 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;
            }

            if (Options.HasFlag(ERunOptions.AppMustExist) && !FileExists(Options.HasFlag(ERunOptions.NoLoggingOfRunCommand) ? true : false, App))
            {
                throw new AutomationException("BUILD FAILED: Couldn't find the executable to Run: {0}", App);
            }
            var StartTime = DateTime.UtcNow;

            TraceEventType SpewVerbosity = Options.HasFlag(ERunOptions.SpewIsVerbose) ? TraceEventType.Verbose : TraceEventType.Information;
            if (!Options.HasFlag(ERunOptions.NoLoggingOfRunCommand))
            {
                Log(SpewVerbosity,"Run: " + App + " " + (String.IsNullOrEmpty(CommandLine) ? "" : CommandLine));
            }
            ProcessResult Result = ProcessManager.CreateProcess(App, Options.HasFlag(ERunOptions.AllowSpew), Path.GetFileNameWithoutExtension(App), Env, SpewVerbosity:SpewVerbosity);
            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))
                {
                    Log(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;
        }
コード例 #17
0
    private ProcessResult RunAdbCommand(ProjectParams Params, string Args, string Input = null, ERunOptions Options = ERunOptions.Default)
    {
        string AdbCommand = Environment.ExpandEnvironmentVariables("%ANDROID_HOME%/platform-tools/adb" + (Utils.IsRunningOnMono ? "" : ".exe"));

        return(Run(AdbCommand, GetAdbCommandLine(Params, Args), Input, Options));
    }
コード例 #18
0
	public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
	{
		return null;
	}
コード例 #19
0
    public override IProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        // look for browser
        string BrowserPath = Params.Devices[0].Replace("HTML5@", "");

        // open the webpage
        Int32 ServerPort = 8000;         // HTML5LaunchHelper default

        var ConfigCache = UnrealBuildTool.ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(Params.RawProjectPath), UnrealTargetPlatform.HTML5);

        ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "DeployServerPort", out ServerPort);         // LaunchOn via Editor or FrontEnd
        string WorkingDirectory = Path.GetDirectoryName(ClientApp);
        string url = Path.GetFileName(ClientApp) + ".html";

        // WARNING: splitting the following situation
        // if cookonthefly is used: tell the browser to use the PROXY at DEFAULT_HTTP_FILE_SERVING_PORT
        // leave the normal HTML5LaunchHelper port (ServerPort) alone -- otherwise it will collide with the PROXY port
        if (ClientCmdLine.Contains("filehostip"))
        {
            url += "?cookonthefly=true";
            Int32 ProxyPort = 41898;             // DEFAULT_HTTP_FILE_SERVING_PORT
            url = String.Format("http://localhost:{0}/{1}", ProxyPort, url);
        }
        else
        {
            url = String.Format("http://localhost:{0}/{1}", ServerPort, url);
        }

        // Check HTML5LaunchHelper source for command line args

        var LowerBrowserPath = BrowserPath.ToLower();
        var ProfileDirectory = Path.Combine(Utils.GetUserSettingDirectory().FullName, "UE4_HTML5", "user");

        string BrowserCommandline = url;

        if (LowerBrowserPath.Contains("chrome"))
        {
            ProfileDirectory = Path.Combine(ProfileDirectory, "chrome");
            // removing [--enable-logging] otherwise, chrome breaks with a bunch of the following errors:
            // > ERROR:process_info.cc(631)] range at 0x7848406c00000000, size 0x1a4 fully unreadable
            // leaving this note here for future reference: UE-45078
            BrowserCommandline += "  " + String.Format("--user-data-dir=\\\"{0}\\\"   --no-first-run", ProfileDirectory);
        }
        else if (LowerBrowserPath.Contains("firefox"))
        {
            ProfileDirectory    = Path.Combine(ProfileDirectory, "firefox");
            BrowserCommandline += "  " + String.Format("-no-remote -profile \\\"{0}\\\"", ProfileDirectory);
        }

        if (UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Linux)
        {
            // TODO: test on other platforms to remove this if() check
            if (!Directory.Exists(ProfileDirectory))
            {
                Directory.CreateDirectory(ProfileDirectory);
            }
        }

        string LauncherArguments = string.Format(" -Browser=\"{0}\" + -BrowserCommandLine=\"{1}\" -ServerPort=\"{2}\" -ServerRoot=\"{3}\" ",
                                                 new object[] { BrowserPath, BrowserCommandline, ServerPort, WorkingDirectory });

        var            LaunchHelperPath = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe");
        IProcessResult BrowserProcess   = Run(LaunchHelperPath, LauncherArguments, null, ClientRunFlags | ERunOptions.NoWaitForExit);

        return(BrowserProcess);
    }
コード例 #20
0
	private static void RunClientWithServer(List<DeploymentContext> DeployContextList, string ServerLogFile, ProcessResult ServerProcess, string ClientApp, string ClientCmdLine, ERunOptions ClientRunFlags, string ClientLogFile, ProjectParams Params)
	{
		ProcessResult ClientProcess = null;
		var OtherClients = new List<ProcessResult>();

		bool WelcomedCorrectly = false;
		int NumClients = Params.NumClients;
		string AllClientOutput = "";
		int LastAutoFailIndex = -1;

		if (Params.Unattended)
		{
			string LookFor = "Bringing up level for play took";
			if (Params.DedicatedServer)
			{
				LookFor = "Welcomed by server";
			}
			else if (Params.RunAutomationTest != "")
			{
				LookFor = "Automation Test Succeeded";
			}
			else if (Params.RunAutomationTests)
			{
				LookFor = "Automation Test Queue Empty";
			}
			{
				while (!FileExists(ServerLogFile) && !ServerProcess.HasExited)
				{
					LogConsole("Waiting for logging process to start...");
					Thread.Sleep(2000);
				}
				Thread.Sleep(1000);

				string AllServerOutput = "";
				using (FileStream ProcessLog = File.Open(ServerLogFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
				{
					StreamReader LogReader = new StreamReader(ProcessLog);
					bool bKeepReading = true;

					FileStream ClientProcessLog = null;
					StreamReader ClientLogReader = null;

					// Read until the process has exited.
					while (!ServerProcess.HasExited && bKeepReading)
					{
						while (!LogReader.EndOfStream && bKeepReading && ClientProcess == null)
						{
							string Output = LogReader.ReadToEnd();
							if (!String.IsNullOrEmpty(Output))
							{
								AllServerOutput += Output;
								if (ClientProcess == null &&
										(AllServerOutput.Contains("Game Engine Initialized") || AllServerOutput.Contains("Unreal Network File Server is ready")))
								{
									LogConsole("Starting Client for unattended test....");
									ClientProcess = Run(ClientApp, ClientCmdLine + " -FORCELOGFLUSH -testexit=\"" + LookFor + "\"", null, ClientRunFlags | ERunOptions.NoWaitForExit);
									//@todo no testing is done on these
									if (NumClients > 1 && NumClients < 9)
									{
										for (int i = 1; i < NumClients; i++)
										{
											LogConsole("Starting Extra Client....");
											OtherClients.Add(Run(ClientApp, ClientCmdLine, null, ClientRunFlags | ERunOptions.NoWaitForExit));
										}
									}
									while (!FileExists(ClientLogFile) && !ClientProcess.HasExited)
									{
										LogConsole("Waiting for client logging process to start...{0}", ClientLogFile);
										Thread.Sleep(2000);
									}
									if (!ClientProcess.HasExited)
									{
										Thread.Sleep(2000);
										LogConsole("Client logging process started...{0}", ClientLogFile);
										ClientProcessLog = File.Open(ClientLogFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
										ClientLogReader = new StreamReader(ClientProcessLog);
									}
								}
								else if (ClientProcess == null && !ServerProcess.HasExited)
								{
									LogConsole("Waiting for server to start....");
									Thread.Sleep(2000);
								}
								if (ClientProcess != null && ClientProcess.HasExited)
								{
									ServerProcess.StopProcess();
									throw new AutomationException("Client exited before we asked it to.");
								}
							}
						}
						if (ClientLogReader != null)
						{
							if (ClientProcess.HasExited)
							{
								ServerProcess.StopProcess();
								throw new AutomationException("Client exited or closed the log before we asked it to.");
							}
							while (!ClientProcess.HasExited && !ServerProcess.HasExited && bKeepReading)
							{
								while (!ClientLogReader.EndOfStream && bKeepReading && !ServerProcess.HasExited && !ClientProcess.HasExited)
								{
									string ClientOutput = ClientLogReader.ReadToEnd();
									if (!String.IsNullOrEmpty(ClientOutput))
									{
										AllClientOutput += ClientOutput;
										Console.Write(ClientOutput);

										if (AllClientOutput.LastIndexOf(LookFor) > AllClientOutput.IndexOf(LookFor))
										{
											if (Params.FakeClient)
											{
												LogConsole("Welcomed by server or client loaded, lets wait ten minutes...");
												Thread.Sleep(60000 * 10);
											}
											else
											{
												LogConsole("Welcomed by server or client loaded, lets wait 30 seconds...");
												Thread.Sleep(30000);
											}
											WelcomedCorrectly = true;
											bKeepReading = false;
										}
										else if (Params.RunAutomationTests)
										{
											int FailIndex = AllClientOutput.LastIndexOf("Automation Test Failed");
											int ParenIndex = AllClientOutput.LastIndexOf(")");
											if (FailIndex >= 0 && ParenIndex > FailIndex && FailIndex > LastAutoFailIndex)
											{
												string Tail = AllClientOutput.Substring(FailIndex);
												int CloseParenIndex = Tail.IndexOf(")");
												int OpenParenIndex = Tail.IndexOf("(");
												string Test = "";
												if (OpenParenIndex >= 0 && CloseParenIndex > OpenParenIndex)
												{
													Test = Tail.Substring(OpenParenIndex + 1, CloseParenIndex - OpenParenIndex - 1);
													LogError("Automated test failed ({0}).", Test);
													LastAutoFailIndex = FailIndex;
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
		else
		{

			LogFileReaderProcess(ServerLogFile, ServerProcess, (string Output) =>
			{
				bool bKeepReading = true;
				if (ClientProcess == null && !String.IsNullOrEmpty(Output))
				{
					AllClientOutput += Output;
					if (ClientProcess == null && (AllClientOutput.Contains("Game Engine Initialized") || AllClientOutput.Contains("Unreal Network File Server is ready")))
					{
						LogConsole("Starting Client....");
						var SC = DeployContextList[0];
						ClientProcess = SC.StageTargetPlatform.RunClient(ClientRunFlags | ERunOptions.NoWaitForExit, ClientApp, ClientCmdLine, Params);
//						ClientProcess = Run(ClientApp, ClientCmdLine, null, ClientRunFlags | ERunOptions.NoWaitForExit);
						if (NumClients > 1 && NumClients < 9)
						{
							for (int i = 1; i < NumClients; i++)
							{
								LogConsole("Starting Extra Client....");
								ProcessResult NewClient = SC.StageTargetPlatform.RunClient(ClientRunFlags | ERunOptions.NoWaitForExit, ClientApp, ClientCmdLine, Params);
								OtherClients.Add(NewClient);
							}
						}
					}
				}
				else if (ClientProcess == null && !ServerProcess.HasExited)
				{
					LogConsole("Waiting for server to start....");
					Thread.Sleep(2000);
				}

				if (String.IsNullOrEmpty(Output) == false)
				{
					Console.Write(Output);
				}

				if (ClientProcess != null && ClientProcess.HasExited)
				{

					LogConsole("Client exited, stopping server....");
					if (!GlobalCommandLine.NoKill)
					{
						ServerProcess.StopProcess();
					}
					bKeepReading = false;
				}

				return bKeepReading; // Keep reading
			});
		}
		LogConsole("Server exited....");
		if (ClientProcess != null && !ClientProcess.HasExited)
		{
			ClientProcess.StopProcess();
		}
		foreach (var OtherClient in OtherClients)
		{
			if (OtherClient != null && !OtherClient.HasExited)
			{
				OtherClient.StopProcess();
			}
		}
		if (Params.Unattended)
		{
			if (!WelcomedCorrectly)
			{
				throw new AutomationException("Server or client exited before we asked it to.");
			}
		}
	}
コード例 #21
0
    public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        // look for browser
        var           ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine"));
        bool          ok          = false;
        List <string> Devices;
        string        browserPath = "";
        string        DeviceName  = Params.Device.Split('@')[1];

        DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on "));

        if (ConfigCache.GetArray("/Script/HTML5PlatformEditor.HTML5SDKSettings", "DeviceMap", out Devices))
        {
            foreach (var Dev in Devices)
            {
                var Matched = Regex.Match(Dev, "\\(DeviceName=\"(.*)\",DevicePath=\\(FilePath=\"(.*)\"\\)\\)", RegexOptions.IgnoreCase);
                if (Matched.Success && Matched.Groups[1].ToString() == DeviceName)
                {
                    browserPath = Matched.Groups[2].ToString();
                    ok          = true;
                    break;
                }
            }
        }

        if (!ok && HTML5SDKInfo.bAllowFallbackSDKSettings)
        {
            string DeviceSection;

            if (Utils.IsRunningOnMono)
            {
                DeviceSection = "HTML5DevicesMac";
            }
            else
            {
                DeviceSection = "HTML5DevicesWindows";
            }

            ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath);
        }

        if (!ok)
        {
            throw new System.Exception("Incorrect browser configuration in HTML5Engine.ini ");
        }

        // open the webpage
        Int32 ServerPort = 8000;

        ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "DeployServerPort", out ServerPort);
        string WorkingDirectory = Path.GetDirectoryName(ClientApp);
        string url  = Path.GetFileName(ClientApp) + ".html";
        string args = "-m ";
        // Are we running via cook on the fly server?
        // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not.
        bool IsCookOnTheFly = false;

        // 9/24/2014 @fixme - All this is convoluted, clean up.
        // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT)
        // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly.

        if (ClientCmdLine.Contains("filehostip"))
        {
            IsCookOnTheFly = true;
            url            = "http://127.0.0.1:41898/" + url;
        }

        if (IsCookOnTheFly)
        {
            url += "?cookonthefly=true";
        }
        else
        {
            url   = String.Format("http://127.0.0.1:{0}/{1}", ServerPort, url);
            args += String.Format("-h -s {0} ", ServerPort);
        }

        // Check HTML5LaunchHelper source for command line args
        var LowerBrowserPath = browserPath.ToLower();

        args += String.Format("-b \"{0}\" -p \"{1}\" -w \"{2}\" ", browserPath, HTML5SDKInfo.PythonPath(), WorkingDirectory);
        args += url + " ";
        var ProfileDirectory = Path.Combine(Utils.GetUserSettingDirectory(), "UE4_HTML5", "user");

        if (LowerBrowserPath.Contains("chrome"))
        {
            args += String.Format("--user-data-dir=\"{0}\" --enable-logging --no-first-run", Path.Combine(ProfileDirectory, "chrome"));
        }
        else if (LowerBrowserPath.Contains("firefox"))
        {
            args += String.Format("-no-remote -profile \"{0}\"", Path.Combine(ProfileDirectory, "firefox"));
        }
        //else if (browserPath.Contains("Safari")) {}

        var           LaunchHelperPath = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe");
        ProcessResult BrowserProcess   = Run(LaunchHelperPath, args, null, ClientRunFlags | ERunOptions.NoWaitForExit);

        return(BrowserProcess);
    }
コード例 #22
0
    public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        // look for browser
        var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine"));

        string DeviceSection;

        if ( Utils.IsRunningOnMono )
        {
            DeviceSection = "HTML5DevicesMac";
        }
        else
        {
            DeviceSection = "HTML5DevicesWindows";
        }

        string browserPath;
        string DeviceName = Params.Device.Split('@')[1];
        DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on "));
        bool ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath);

        if (!ok)
            throw new System.Exception ("Incorrect browser configuration in HTML5Engine.ini ");

        // open the webpage
        string directory = Path.GetDirectoryName(ClientApp);
        string url = Path.GetFileName(ClientApp) +".html";
        // Are we running via cook on the fly server?
        // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not.
        bool IsCookOnTheFly = false;

        // 9/24/2014 @fixme - All this is convoluted, clean up.
        // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT)
        // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly.

        if (ClientCmdLine.Contains("filehostip"))
        {
            IsCookOnTheFly = true;
            url = "http://127.0.0.1:41898/" + url;
        }

        if (IsCookOnTheFly)
        {
            url += "?cookonthefly=true";
        }
        else
        {
            url = "http://127.0.0.1:8000/" + url;
            // this will be killed UBT instances dies.
            string input = String.Format(" -m SimpleHTTPServer 8000");

            string PythonPath = HTML5SDKInfo.PythonPath();
            ProcessResult Result = ProcessManager.CreateProcess(PythonPath, true, "html5server.log");
            Result.ProcessObject.StartInfo.FileName = PythonPath;
            Result.ProcessObject.StartInfo.UseShellExecute = false;
            Result.ProcessObject.StartInfo.RedirectStandardOutput = true;
            Result.ProcessObject.StartInfo.RedirectStandardInput = true;
            Result.ProcessObject.StartInfo.WorkingDirectory = directory;
            Result.ProcessObject.StartInfo.Arguments = input;
            Result.ProcessObject.Start();

            Result.ProcessObject.OutputDataReceived += delegate(object sender, System.Diagnostics.DataReceivedEventArgs e)
            {
                System.Console.WriteLine(e.Data);
            };

            System.Console.WriteLine("Starting Browser Process");

            // safari specific hack.
            string argument = url;
            if (browserPath.Contains ("Safari") && Utils.IsRunningOnMono)
                argument = "";

            // Chrome issue. Firefox may work like this in the future
            bool bBrowserWillSpawnProcess = browserPath.Contains("chrome") || (browserPath.Contains("Google Chrome") && Utils.IsRunningOnMono);

            ProcessResult SubProcess = null;
            ProcessResult ClientProcess = Run(browserPath, argument, null, ClientRunFlags | ERunOptions.NoWaitForExit);
            var ProcStartTime = ClientProcess.ProcessObject.StartTime;
            var ProcName = ClientProcess.ProcessObject.ProcessName;

            ClientProcess.ProcessObject.EnableRaisingEvents = true;
            ClientProcess.ProcessObject.Exited += delegate(System.Object o, System.EventArgs e)
            {
                System.Console.WriteLine("Browser Process Ended (PID={0})", ClientProcess.ProcessObject.Id);
                var bFoundChildProcess = false;
                if (bBrowserWillSpawnProcess)
                {
                    // Chrome spawns a process from the tab it opens and then lets the process we spawned die, so
                    // catch that process and attach to that instead.
                    var CurrentProcesses = Process.GetProcesses();
                    foreach (var item in CurrentProcesses)
                    {
                        if (item.Id != ClientProcess.ProcessObject.Id && item.ProcessName == ProcName && item.StartTime >= ProcStartTime && item.StartTime <= ClientProcess.ProcessObject.ExitTime)
                        {
                            var PID = item.Id;
                            System.Console.WriteLine("Found Process {0} with PID {1} which started at {2}. Waiting on that process to end.", item.ProcessName, item.Id, item.StartTime.ToString());
                            SubProcess = new ProcessResult(item.ProcessName, item, true, item.ProcessName);
                            item.EnableRaisingEvents = true;
                            item.Exited += delegate(System.Object o2, System.EventArgs e2)
                            {
                                System.Console.WriteLine("Browser Process Ended (PID={0}) - Killing Webserver", PID);
                                Result.ProcessObject.StandardInput.Close();
                                Result.ProcessObject.Kill();
                            };
                            bFoundChildProcess = true;
                        }
                    }
                }

                if (!bFoundChildProcess)
                {
                    System.Console.WriteLine("- Killing Webserver PID({0})", Result.ProcessObject.Id);
                    Result.ProcessObject.StandardInput.Close();
                    Result.ProcessObject.Kill();
                }
            };

            if (bBrowserWillSpawnProcess)
            {
                //Wait for it to do so...
                ClientProcess.ProcessObject.WaitForExit();
                ClientProcess = SubProcess;
            }

            // safari needs a hack.
            // http://superuser.com/questions/689315/run-safari-from-terminal-with-given-url-address-without-open-command

            if (browserPath.Contains ("Safari") && Utils.IsRunningOnMono)
            {
                // ClientProcess.ProcessObject.WaitForInputIdle ();
                Thread.Sleep (2000);
                Process.Start("/usr/bin/osascript"," -e 'tell application \"Safari\" to open location \"" + url + "\"'" );
            }

            return ClientProcess;
        }

        System.Console.WriteLine("Browser Path " + browserPath);
        ProcessResult BrowserProcess = Run(browserPath, url, null, ClientRunFlags | ERunOptions.NoWaitForExit);

        return BrowserProcess;
    }
コード例 #23
0
    public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        // look for firefox
        string[] PossiblePaths = new string[]
        {
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), @"Nightly\firefox.exe"),
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Nightly\firefox.exe"),
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), @"Mozilla Firefox\firefox.exe"),
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Mozilla Firefox\firefox.exe"),
        };

        // set up a directory for temp profile
        string FirefoxProfileCommand = " -no-remote ";

        // look for the best firefox to tun
        string FirefoxPath = null;
        foreach (string PossiblePath in PossiblePaths)
        {
            if (File.Exists(PossiblePath))
            {
                FirefoxPath = PossiblePath;
                break;
            }
        }

        // if we didn't find one, just use the shell to open it
        if (FirefoxPath == null)
        {
            FirefoxPath = CmdEnv.CmdExe;
            FirefoxProfileCommand = " ";
        }

           		// open the webpage
        // what to do with the commandline!??
        string HTMLPath = Path.ChangeExtension(ClientApp, "html");
        if  ( !File.Exists(HTMLPath) )  // its probably a content only game - then it exists in the UE4 directory and not in the game directory.
            HTMLPath = Path.Combine(CombinePaths(CmdEnv.LocalRoot, "Engine"), "Binaries", "HTML5", Path.GetFileName(HTMLPath));

        ProcessResult ClientProcess = Run(FirefoxPath, FirefoxProfileCommand + HTMLPath , null, ClientRunFlags | ERunOptions.NoWaitForExit);

        return ClientProcess;
    }
コード例 #24
0
 /// <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);
 }
コード例 #25
0
    // --------------------------------------------------------------------------------
    // RunProjectCommand.Automation.cs

    public override IProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        // look for browser
        string BrowserPath = Params.Devices[0].Replace("HTML5@", "");

        // open the webpage
        Int32 ServerPort = 8000;         // HTML5LaunchHelper default

        var ConfigCache = UnrealBuildTool.ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(Params.RawProjectPath), UnrealTargetPlatform.HTML5);

        ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "DeployServerPort", out ServerPort);         // LaunchOn via Editor or FrontEnd
        string WorkingDirectory = Path.GetDirectoryName(ClientApp);
        string url = Path.GetFileName(ClientApp) + ".html";

// UE-64628: seems proxy port is no longer used anymore -- leaving details here for future reference...
//		// WARNING: splitting the following situation
//		// if cookonthefly is used: tell the browser to use the PROXY at DEFAULT_HTTP_FILE_SERVING_PORT
//		// leave the normal HTML5LaunchHelper port (ServerPort) alone -- otherwise it will collide with the PROXY port
        if (ClientCmdLine.Contains("filehostip"))
        {
            url += "?cookonthefly=true";
//			Int32 ProxyPort = 41898; // DEFAULT_HTTP_FILE_SERVING_PORT
//			url = String.Format("http://localhost:{0}/{1}", ProxyPort, url);
        }
//		else
//		{
        url = String.Format("http://localhost:{0}/{1}", ServerPort, url);
//		}

        // Check HTML5LaunchHelper source for command line args

        var LowerBrowserPath = BrowserPath.ToLower();
        var ProfileDirectory = Path.Combine(Utils.GetUserSettingDirectory().FullName, "UE4_HTML5", "user");

        string BrowserCommandline = url;

        if (LowerBrowserPath.Contains("chrome"))
        {
            ProfileDirectory = Path.Combine(ProfileDirectory, "chrome");
            // removing [--enable-logging] otherwise, chrome breaks with a bunch of the following errors:
            // > ERROR:process_info.cc(631)] range at 0x7848406c00000000, size 0x1a4 fully unreadable
            // leaving this note here for future reference: UE-45078
            BrowserCommandline += "  " + String.Format("--user-data-dir=\\\"{0}\\\"   --no-first-run", ProfileDirectory);
        }
        else if (LowerBrowserPath.Contains("firefox"))
        {
            ProfileDirectory    = Path.Combine(ProfileDirectory, "firefox");
            BrowserCommandline += "  " + String.Format("-no-remote -profile \\\"{0}\\\"", ProfileDirectory);
        }
        else if (LowerBrowserPath.Contains("safari"))
        {
            // NOT SUPPORTED: cannot have a separate UE4 profile for safari
            // -- this "can" be done with a different user (e.g. guest) account...
            //    (which is not a turn key solution that can be done within UE4)
            // -- some have tried using symlinks to "mimic" this
            //    https://discussions.apple.com/thread/3327990
            // -- but, none of these are fool proof with an existing/running safari instance

            // -- also, "Safari Extensions JS" has been officially deprecated as of Safari 12
            //    (in favor of using "Safari App Extension")
            //    https://developer.apple.com/documentation/safariextensions

            // this means, Safari "LaunchOn" (UE4 Editor -> Launch -> Safari) will run with your FULL
            // Safari profile -- so, all of your "previously opened" tabs will all also be opened...
        }

        // TODO: test on other platforms to remove this first if() check
        if (UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Linux)
        {
            if (!Directory.Exists(ProfileDirectory))
            {
                Directory.CreateDirectory(ProfileDirectory);
            }
        }

        string LauncherArguments = string.Format(" -Browser=\"{0}\" + -BrowserCommandLine=\"{1}\" -ServerPort=\"{2}\" -ServerRoot=\"{3}\" ",
                                                 new object[] { BrowserPath, BrowserCommandline, ServerPort, WorkingDirectory });

        var            LaunchHelperPath = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe");
        IProcessResult BrowserProcess   = Run(LaunchHelperPath, LauncherArguments, null, ClientRunFlags | ERunOptions.NoWaitForExit);

        return(BrowserProcess);
    }
    private static void RunStandaloneClient(List <DeploymentContext> DeployContextList, string ClientLogFile, ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        if (Params.Unattended)
        {
            string LookFor     = "Bringing up level for play took";
            bool   bCommandlet = false;

            if (Params.RunAutomationTest != "")
            {
                LookFor = "Automation Test Succeeded";
            }
            else if (Params.RunAutomationTests)
            {
                LookFor = "Automation Test Queue Empty";
            }
            else if (Params.EditorTest)
            {
                LookFor = "Asset discovery search completed in";
            }
            // If running a commandlet, just detect a normal exit
            else if (ClientCmdLine.IndexOf("-run=", StringComparison.InvariantCultureIgnoreCase) >= 0)
            {
                LookFor     = "Game engine shut down";
                bCommandlet = true;
            }

            {
                string         AllClientOutput   = "";
                int            LastAutoFailIndex = -1;
                IProcessResult ClientProcess     = null;
                FileStream     ClientProcessLog  = null;
                StreamReader   ClientLogReader   = null;
                LogInformation("Starting Client for unattended test....");
                ClientProcess = Run(ClientApp, ClientCmdLine + " -testexit=\"" + LookFor + "\"", null, ClientRunFlags | ERunOptions.NoWaitForExit);
                while (!FileExists(ClientLogFile) && !ClientProcess.HasExited)
                {
                    LogInformation("Waiting for client logging process to start...{0}", ClientLogFile);
                    Thread.Sleep(2000);
                }
                if (FileExists(ClientLogFile))
                {
                    Thread.Sleep(2000);
                    LogInformation("Client logging process started...{0}", ClientLogFile);
                    ClientProcessLog = File.Open(ClientLogFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    ClientLogReader  = new StreamReader(ClientProcessLog);
                }
                if (ClientLogReader == null)
                {
                    throw new AutomationException("Client exited without creating a log file.");
                }
                bool     bKeepReading      = true;
                bool     WelcomedCorrectly = false;
                bool     bClientExited     = false;
                DateTime ExitTime          = DateTime.UtcNow;

                while (bKeepReading)
                {
                    if (!bClientExited && ClientProcess.HasExited)
                    {
                        ExitTime      = DateTime.UtcNow;
                        bClientExited = true;
                    }
                    string ClientOutput = ClientLogReader.ReadToEnd();
                    if (!String.IsNullOrEmpty(ClientOutput))
                    {
                        if (bClientExited)
                        {
                            ExitTime = DateTime.UtcNow;                             // as long as it is spewing, we reset the timer
                        }
                        AllClientOutput += ClientOutput;
                        Console.Write(ClientOutput);

                        if (AllClientOutput.LastIndexOf(LookFor) > AllClientOutput.IndexOf(LookFor))
                        {
                            WelcomedCorrectly = true;
                            LogInformation("Test complete...");
                            bKeepReading = false;
                        }
                        else if (Params.RunAutomationTests)
                        {
                            int FailIndex  = AllClientOutput.LastIndexOf("Automation Test Failed");
                            int ParenIndex = AllClientOutput.LastIndexOf(")");
                            if (FailIndex >= 0 && ParenIndex > FailIndex && FailIndex > LastAutoFailIndex)
                            {
                                string Tail            = AllClientOutput.Substring(FailIndex);
                                int    CloseParenIndex = Tail.IndexOf(")");
                                int    OpenParenIndex  = Tail.IndexOf("(");
                                string Test            = "";
                                if (OpenParenIndex >= 0 && CloseParenIndex > OpenParenIndex)
                                {
                                    Test = Tail.Substring(OpenParenIndex + 1, CloseParenIndex - OpenParenIndex - 1);
                                    LogError("Automated test failed ({0}).", Test);
                                    LastAutoFailIndex = FailIndex;
                                }
                            }
                        }
                        // Detect commandlet failure
                        else if (bCommandlet)
                        {
                            const string ResultLog = "Commandlet->Main return this error code: ";

                            int ResultStart  = AllClientOutput.LastIndexOf(ResultLog);
                            int ResultValIdx = ResultStart + ResultLog.Length;

                            if (ResultStart >= 0 && ResultValIdx < AllClientOutput.Length &&
                                AllClientOutput.Substring(ResultValIdx, 1) == "1")
                            {
                                // Parse the full commandlet warning/error summary
                                string FullSummary  = "";
                                int    SummaryStart = AllClientOutput.LastIndexOf("Warning/Error Summary");

                                if (SummaryStart >= 0 && SummaryStart < ResultStart)
                                {
                                    FullSummary = AllClientOutput.Substring(SummaryStart, ResultStart - SummaryStart);
                                }


                                if (FullSummary.Length > 0)
                                {
                                    LogError("Commandlet failed, summary:" + Environment.NewLine +
                                             FullSummary);
                                }
                                else
                                {
                                    LogError("Commandlet failed.");
                                }
                            }
                        }
                    }
                    else if (bClientExited && (DateTime.UtcNow - ExitTime).TotalSeconds > 30)
                    {
                        LogInformation("Client exited and has been quiet for 30 seconds...exiting");
                        bKeepReading = false;
                    }
                }
                if (ClientProcess != null && !ClientProcess.HasExited)
                {
                    LogInformation("Client is supposed to exit, lets wait a while for it to exit naturally...");
                    for (int i = 0; i < 120 && !ClientProcess.HasExited; i++)
                    {
                        Thread.Sleep(1000);
                    }
                }
                if (ClientProcess != null && !ClientProcess.HasExited)
                {
                    LogInformation("Stopping client...");
                    ClientProcess.StopProcess();
                    Thread.Sleep(10000);
                }
                while (!ClientLogReader.EndOfStream)
                {
                    string ClientOutput = ClientLogReader.ReadToEnd();
                    if (!String.IsNullOrEmpty(ClientOutput))
                    {
                        Console.Write(ClientOutput);
                    }
                }

                if (!WelcomedCorrectly)
                {
                    throw new AutomationException("Client exited before we asked it to.");
                }
            }
        }
        else
        {
            var            SC            = DeployContextList[0];
            IProcessResult ClientProcess = SC.StageTargetPlatform.RunClient(ClientRunFlags, ClientApp, ClientCmdLine, Params);
            if (ClientProcess != null)
            {
                // If the client runs without StdOut redirect we're going to read the log output directly from log file on
                // a separate thread.
                if ((ClientRunFlags & ERunOptions.NoStdOutRedirect) == ERunOptions.NoStdOutRedirect)
                {
                    ClientLogReaderThread = new System.Threading.Thread(ClientLogReaderProc);
                    ClientLogReaderThread.Start(new object[] { ClientLogFile, ClientProcess });
                }

                do
                {
                    Thread.Sleep(100);
                }while (ClientProcess.HasExited == false);

                SC.StageTargetPlatform.PostRunClient(ClientProcess, Params);

                // any non-zero exit code should propagate an exception. The Virtual function above may have
                // already thrown a more specific exception or given a more specific ErrorCode, but this catches the rest.
                if (ClientProcess.ExitCode != 0)
                {
                    throw new AutomationException("Client exited with error code: " + ClientProcess.ExitCode);
                }
            }
        }
    }
コード例 #27
0
    private static void RunStandaloneClient(List <DeploymentContext> DeployContextList, string ClientLogFile, ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        if (Params.Unattended)
        {
            string LookFor = "Bringing up level for play took";
            if (Params.RunAutomationTest != "")
            {
                LookFor = "Automation Test Succeeded";
            }
            else if (Params.RunAutomationTests)
            {
                LookFor = "Automation Test Queue Empty";
            }
            else if (Params.EditorTest)
            {
                LookFor = "Asset discovery search completed in";
            }
            {
                string        AllClientOutput   = "";
                int           LastAutoFailIndex = -1;
                ProcessResult ClientProcess     = null;
                FileStream    ClientProcessLog  = null;
                StreamReader  ClientLogReader   = null;
                Log("Starting Client for unattended test....");
                ClientProcess = Run(ClientApp, ClientCmdLine + " -FORCELOGFLUSH -testexit=\"" + LookFor + "\"", null, ClientRunFlags | ERunOptions.NoWaitForExit);
                while (!FileExists(ClientLogFile) && !ClientProcess.HasExited)
                {
                    Log("Waiting for client logging process to start...{0}", ClientLogFile);
                    Thread.Sleep(2000);
                }
                if (FileExists(ClientLogFile))
                {
                    Thread.Sleep(2000);
                    Log("Client logging process started...{0}", ClientLogFile);
                    ClientProcessLog = File.Open(ClientLogFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    ClientLogReader  = new StreamReader(ClientProcessLog);
                }
                if (ClientLogReader == null)
                {
                    throw new AutomationException("Client exited without creating a log file.");
                }
                bool     bKeepReading      = true;
                bool     WelcomedCorrectly = false;
                bool     bClientExited     = false;
                DateTime ExitTime          = DateTime.UtcNow;

                while (bKeepReading)
                {
                    if (!bClientExited && ClientProcess.HasExited)
                    {
                        ExitTime      = DateTime.UtcNow;
                        bClientExited = true;
                    }
                    string ClientOutput = ClientLogReader.ReadToEnd();
                    if (!String.IsNullOrEmpty(ClientOutput))
                    {
                        if (bClientExited)
                        {
                            ExitTime = DateTime.UtcNow;                             // as long as it is spewing, we reset the timer
                        }
                        AllClientOutput += ClientOutput;
                        Console.Write(ClientOutput);

                        if (AllClientOutput.LastIndexOf(LookFor) > AllClientOutput.IndexOf(LookFor))
                        {
                            WelcomedCorrectly = true;
                            Log("Test complete...");
                            bKeepReading = false;
                        }
                        else if (Params.RunAutomationTests)
                        {
                            int FailIndex  = AllClientOutput.LastIndexOf("Automation Test Failed");
                            int ParenIndex = AllClientOutput.LastIndexOf(")");
                            if (FailIndex >= 0 && ParenIndex > FailIndex && FailIndex > LastAutoFailIndex)
                            {
                                string Tail            = AllClientOutput.Substring(FailIndex);
                                int    CloseParenIndex = Tail.IndexOf(")");
                                int    OpenParenIndex  = Tail.IndexOf("(");
                                string Test            = "";
                                if (OpenParenIndex >= 0 && CloseParenIndex > OpenParenIndex)
                                {
                                    Test = Tail.Substring(OpenParenIndex + 1, CloseParenIndex - OpenParenIndex - 1);
                                    Log(System.Diagnostics.TraceEventType.Error, "Automated test failed ({0}).", Test);
                                    LastAutoFailIndex = FailIndex;
                                }
                            }
                        }
                    }
                    else if (bClientExited && (DateTime.UtcNow - ExitTime).TotalSeconds > 30)
                    {
                        Log("Client exited and has been quiet for 30 seconds...exiting");
                        bKeepReading = false;
                    }
                }
                if (ClientProcess != null && !ClientProcess.HasExited)
                {
                    Log("Client is supposed to exit, lets wait a while for it to exit naturally...");
                    for (int i = 0; i < 120 && !ClientProcess.HasExited; i++)
                    {
                        Thread.Sleep(1000);
                    }
                }
                if (ClientProcess != null && !ClientProcess.HasExited)
                {
                    Log("Stopping client...");
                    ClientProcess.StopProcess();
                    Thread.Sleep(10000);
                }
                while (ClientLogReader != null && !ClientLogReader.EndOfStream)
                {
                    string ClientOutput = ClientLogReader.ReadToEnd();
                    if (!String.IsNullOrEmpty(ClientOutput))
                    {
                        Console.Write(ClientOutput);
                    }
                }

                if (!WelcomedCorrectly)
                {
                    throw new AutomationException("Client exited before we asked it to.");
                }
            }
        }
        else
        {
            var           SC            = DeployContextList[0];
            ProcessResult ClientProcess = SC.StageTargetPlatform.RunClient(ClientRunFlags, ClientApp, ClientCmdLine, Params);
            if (ClientProcess != null)
            {
                // If the client runs without StdOut redirect we're going to read the log output directly from log file on
                // a separate thread.
                if ((ClientRunFlags & ERunOptions.NoStdOutRedirect) == ERunOptions.NoStdOutRedirect)
                {
                    ClientLogReaderThread = new System.Threading.Thread(ClientLogReaderProc);
                    ClientLogReaderThread.Start(new object[] { ClientLogFile, ClientProcess });
                }

                do
                {
                    Thread.Sleep(100);
                }while (ClientProcess.HasExited == false);

                if (ClientProcess.ExitCode != 0)
                {
                    throw new AutomationException("Client exited with error code: " + ClientProcess.ExitCode);
                }
            }
        }
    }
    private static void SetupClientParams(List <DeploymentContext> DeployContextList, ProjectParams Params, string ClientLogFile, out ERunOptions ClientRunFlags, out string ClientApp, out string ClientCmdLine)
    {
        if (Params.ClientTargetPlatforms.Count == 0)
        {
            throw new AutomationException("No ClientTargetPlatform set for SetupClientParams.");
        }

        //		var DeployContextList = CreateDeploymentContext(Params, false);

        if (DeployContextList.Count == 0)
        {
            throw new AutomationException("No DeployContextList for SetupClientParams.");
        }

        var SC = DeployContextList[0];

        // Get client app name and command line.
        ClientRunFlags = ERunOptions.AllowSpew | ERunOptions.AppMustExist;
        ClientApp      = "";
        ClientCmdLine  = "";
        string TempCmdLine  = SC.ProjectArgForCommandLines + " ";
        var    PlatformName = Params.ClientTargetPlatforms[0].ToString();

        if (Params.Cook || Params.CookOnTheFly)
        {
            List <FileReference> Exes = SC.StageTargetPlatform.GetExecutableNames(SC);
            ClientApp = Exes[0].FullName;

            if (!String.IsNullOrEmpty(Params.ClientCommandline))
            {
                TempCmdLine += Params.ClientCommandline + " ";
            }
            else
            {
                TempCmdLine += Params.MapToRun + " ";
            }

            if (Params.CookOnTheFly || Params.FileServer)
            {
                TempCmdLine += "-filehostip=";
                bool FirstParam = true;
                if (UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
                {
                    NetworkInterface[] Interfaces = NetworkInterface.GetAllNetworkInterfaces();
                    foreach (NetworkInterface adapter in Interfaces)
                    {
                        if (adapter.NetworkInterfaceType != NetworkInterfaceType.Loopback)
                        {
                            IPInterfaceProperties IP = adapter.GetIPProperties();
                            for (int Index = 0; Index < IP.UnicastAddresses.Count; ++Index)
                            {
                                if (IP.UnicastAddresses[Index].IsDnsEligible && IP.UnicastAddresses[Index].Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                                {
                                    if (!IsNullOrEmpty(Params.Port))
                                    {
                                        foreach (var Port in Params.Port)
                                        {
                                            if (!FirstParam)
                                            {
                                                TempCmdLine += "+";
                                            }
                                            FirstParam = false;
                                            string[] PortProtocol = Port.Split(new char[] { ':' });
                                            if (PortProtocol.Length > 1)
                                            {
                                                TempCmdLine += String.Format("{0}://{1}:{2}", PortProtocol[0], IP.UnicastAddresses[Index].Address.ToString(), PortProtocol[1]);
                                            }
                                            else
                                            {
                                                TempCmdLine += IP.UnicastAddresses[Index].Address.ToString();
                                                TempCmdLine += ":";
                                                TempCmdLine += Params.Port;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (!FirstParam)
                                        {
                                            TempCmdLine += "+";
                                        }
                                        FirstParam = false;

                                        // use default port
                                        TempCmdLine += IP.UnicastAddresses[Index].Address.ToString();
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    NetworkInterface[] Interfaces = NetworkInterface.GetAllNetworkInterfaces();
                    foreach (NetworkInterface adapter in Interfaces)
                    {
                        if (adapter.OperationalStatus == OperationalStatus.Up)
                        {
                            IPInterfaceProperties IP = adapter.GetIPProperties();
                            for (int Index = 0; Index < IP.UnicastAddresses.Count; ++Index)
                            {
                                if (IP.UnicastAddresses[Index].IsDnsEligible)
                                {
                                    if (!IsNullOrEmpty(Params.Port))
                                    {
                                        foreach (var Port in Params.Port)
                                        {
                                            if (!FirstParam)
                                            {
                                                TempCmdLine += "+";
                                            }
                                            FirstParam = false;
                                            string[] PortProtocol = Port.Split(new char[] { ':' });
                                            if (PortProtocol.Length > 1)
                                            {
                                                TempCmdLine += String.Format("{0}://{1}:{2}", PortProtocol[0], IP.UnicastAddresses[Index].Address.ToString(), PortProtocol[1]);
                                            }
                                            else
                                            {
                                                TempCmdLine += IP.UnicastAddresses[Index].Address.ToString();
                                                TempCmdLine += ":";
                                                TempCmdLine += Params.Port;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (!FirstParam)
                                        {
                                            TempCmdLine += "+";
                                        }
                                        FirstParam = false;

                                        // use default port
                                        TempCmdLine += IP.UnicastAddresses[Index].Address.ToString();
                                    }
                                }
                            }
                        }
                    }
                }

                const string LocalHost = "127.0.0.1";

                if (!IsNullOrEmpty(Params.Port))
                {
                    foreach (var Port in Params.Port)
                    {
                        if (!FirstParam)
                        {
                            TempCmdLine += "+";
                        }
                        FirstParam = false;
                        string[] PortProtocol = Port.Split(new char[] { ':' });
                        if (PortProtocol.Length > 1)
                        {
                            TempCmdLine += String.Format("{0}://{1}:{2}", PortProtocol[0], LocalHost, PortProtocol[1]);
                        }
                        else
                        {
                            TempCmdLine += LocalHost;
                            TempCmdLine += ":";
                            TempCmdLine += Params.Port;
                        }
                    }
                }
                else
                {
                    if (!FirstParam)
                    {
                        TempCmdLine += "+";
                    }
                    FirstParam = false;

                    // use default port
                    TempCmdLine += LocalHost;
                }
                TempCmdLine += " ";

                if (Params.CookOnTheFlyStreaming)
                {
                    TempCmdLine += "-streaming ";
                }
                else if (SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.IOS)
                {
                    // per josh, allowcaching is deprecated/doesn't make sense for iOS.
                    TempCmdLine += "-allowcaching ";
                }
            }
            else if (Params.UsePak(SC.StageTargetPlatform))
            {
                if (Params.SignedPak)
                {
                    TempCmdLine += "-signedpak ";
                }
                else
                {
                    TempCmdLine += "-pak ";
                }
            }
            else if (!Params.Stage)
            {
                var SandboxPath = CombinePaths(SC.RuntimeProjectRootDir.FullName, "Saved", "Cooked", SC.CookPlatform);
                if (!SC.StageTargetPlatform.LaunchViaUFE)
                {
                    TempCmdLine += "-sandbox=" + CommandUtils.MakePathSafeToUseWithCommandLine(SandboxPath) + " ";
                }
                else
                {
                    TempCmdLine += "-sandbox=\'" + SandboxPath + "\' ";
                }
            }
        }
        else
        {
            ClientApp = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries", PlatformName, "UE4Editor.exe");
            if (!Params.EditorTest)
            {
                TempCmdLine += "-game " + Params.MapToRun + " ";
            }
            else
            {
                TempCmdLine += Params.MapToRun + " ";
            }
        }
        if (Params.LogWindow)
        {
            // Without NoStdOutRedirect '-log' doesn't log anything to the window
            ClientRunFlags |= ERunOptions.NoStdOutRedirect;
            TempCmdLine    += "-log ";
        }
        else
        {
            TempCmdLine += "-stdout ";
        }
        if (Params.Unattended)
        {
            TempCmdLine += "-unattended ";
        }
        if (IsBuildMachine || Params.Unattended)
        {
            TempCmdLine += "-buildmachine ";
        }
        if (Params.CrashIndex > 0)
        {
            int RealIndex = Params.CrashIndex - 1;
            if (RealIndex >= CrashCommands.Count())
            {
                throw new AutomationException("CrashIndex {0} is out of range...max={1}", Params.CrashIndex, CrashCommands.Count());
            }
            TempCmdLine += String.Format("-execcmds=\"debug {0}\" ", CrashCommands[RealIndex]);
        }
        else if (Params.RunAutomationTest != "")
        {
            TempCmdLine += "-execcmds=\"automation list;runtests " + Params.RunAutomationTest + "\" ";
        }
        else if (Params.RunAutomationTests)
        {
            TempCmdLine += "-execcmds=\"automation list;runall\" ";
        }
        if (SC.StageTargetPlatform.UseAbsLog)
        {
            TempCmdLine += "-abslog=" + CommandUtils.MakePathSafeToUseWithCommandLine(ClientLogFile) + " ";
        }
        if (SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Win32 || SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Win64)
        {
            TempCmdLine += "-Messaging -Windowed ";
        }
        else
        {
            TempCmdLine += "-Messaging ";
        }
        if (Params.NullRHI && SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.Mac)         // all macs have GPUs, and currently the mac dies with nullrhi
        {
            TempCmdLine += "-nullrhi ";
        }
        TempCmdLine += SC.StageTargetPlatform.GetLaunchExtraCommandLine(Params);

        TempCmdLine += "-CrashForUAT ";
        TempCmdLine += Params.RunCommandline;

        // todo: move this into the platform
        if (SC.StageTargetPlatform.LaunchViaUFE)
        {
            ClientCmdLine  = "-run=Launch ";
            ClientCmdLine += "-Device=" + Params.Devices[0];
            for (int DeviceIndex = 1; DeviceIndex < Params.Devices.Count; DeviceIndex++)
            {
                ClientCmdLine += "+" + Params.Devices[DeviceIndex];
            }
            ClientCmdLine += " ";
            ClientCmdLine += "-Exe=\"" + ClientApp + "\" ";
            ClientCmdLine += "-Targetplatform=" + Params.ClientTargetPlatforms[0].ToString() + " ";
            ClientCmdLine += "-Params=\"" + TempCmdLine + "\"";
            ClientApp      = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/Win64/UnrealFrontend.exe");

            LogInformation("Launching via UFE:");
            LogInformation("\tClientCmdLine: " + ClientCmdLine + "");
        }
        else
        {
            ClientCmdLine = TempCmdLine;
        }
    }
コード例 #29
0
 public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
 {
     return(null);
 }
コード例 #30
0
	public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
	{
		if (UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
		{
			/*			string AppDirectory = string.Format("{0}/Payload/{1}.app",
				Path.GetDirectoryName(Params.ProjectGameExeFilename), 
				Path.GetFileNameWithoutExtension(Params.ProjectGameExeFilename));
			string GameName = Path.GetFileNameWithoutExtension (ClientApp);
			if (GameName.Contains ("-IOS-"))
			{
				GameName = GameName.Substring (0, GameName.IndexOf ("-IOS-"));
			}
			string GameApp = AppDirectory + "/" + GameName;
			bWasGenerated = false;
			XcodeProj = EnsureXcodeProjectExists (Params.RawProjectPath, CmdEnv.LocalRoot, Params.ShortProjectName, GetDirectoryName(Params.RawProjectPath), Params.IsCodeBasedProject, out bWasGenerated);
			string Arguments = "UBT_NO_POST_DEPLOY=true /usr/bin/xcrun xcodebuild test -project \"" + XcodeProj + "\"";
			Arguments += " -scheme '";
			Arguments += GameName;
			Arguments += " - iOS'";
			Arguments += " -configuration " + Params.ClientConfigsToBuild [0].ToString();
			Arguments += " -destination 'platform=iOS,id=" + Params.Device.Substring(4) + "'";
			Arguments += " TEST_HOST=\"";
			Arguments += GameApp;
			Arguments += "\" BUNDLE_LOADER=\"";
			Arguments += GameApp + "\"";*/
			string BundleIdentifier = "";
			if (File.Exists(Params.BaseStageDirectory + "/IOS/Info.plist"))
			{
				string Contents = File.ReadAllText(Params.BaseStageDirectory + "/IOS/Info.plist");
				int Pos = Contents.IndexOf("CFBundleIdentifier");
				Pos = Contents.IndexOf("<string>", Pos) + 8;
				int EndPos = Contents.IndexOf("</string>", Pos);
				BundleIdentifier = Contents.Substring(Pos, EndPos - Pos);
			}
			string Arguments = "/usr/bin/instruments";
			Arguments += " -w '" + Params.Device.Substring (4) + "'";
			Arguments += " -t 'Activity Monitor'";
			Arguments += " -D \"" + Params.BaseStageDirectory + "/IOS/launch.trace\"";
			Arguments += " '" + BundleIdentifier + "'";
			ProcessResult ClientProcess = Run ("/usr/bin/env", Arguments, null, ClientRunFlags | ERunOptions.NoWaitForExit);
			return ClientProcess;
		}
		else
		{
			ProcessResult Result = new ProcessResult("DummyApp", null, false, null);
			Result.ExitCode = 0;
			return Result;
		}
	}
コード例 #31
0
 public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
 {
     if (UnrealBuildTool.ExternalExecution.GetRuntimePlatform () == UnrealTargetPlatform.Mac)
     {
         string AppDirectory = string.Format("{0}/Payload/{1}.app",
             Path.GetDirectoryName(Params.ProjectGameExeFilename),
             Path.GetFileNameWithoutExtension(Params.ProjectGameExeFilename));
         string GameName = Path.GetFileNameWithoutExtension (ClientApp);
         string GameApp = AppDirectory + "/" + GameName;
         bool bWasGenerated = false;
         string XcodeProj = EnsureXcodeProjectExists (Params.RawProjectPath, out bWasGenerated);
         string Arguments = "UBT_NO_POST_DEPLOY=true /usr/bin/xcrun xcodebuild test -project \"" + XcodeProj + "\"";
         Arguments += " -scheme '";
         Arguments += GameName;
         Arguments += " - iOS (Run)'";
         Arguments += " -configuration " + Params.ClientConfigsToBuild [0].ToString();
         Arguments += " -destination 'platform=iOS,id=" + Params.Device.Substring(4) + "'";
         Arguments += " TEST_HOST=\"";
         Arguments += GameApp;
         Arguments += "\" BUNDLE_LOADER=\"";
         Arguments += GameApp + "\"";
         ProcessResult ClientProcess = Run ("/usr/bin/env", Arguments, null, ClientRunFlags | ERunOptions.NoWaitForExit);
         return ClientProcess;
     }
     else
     {
         return base.RunClient(ClientRunFlags, ClientApp, ClientCmdLine, Params);
     }
 }
コード例 #32
0
		/// <summary>
		/// Run the client application on the platform
		/// </summary>
		/// <param name="ClientRunFlags"></param>
		/// <param name="ClientApp"></param>
		/// <param name="ClientCmdLine"></param>
		public virtual ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
		{
			PushDir(Path.GetDirectoryName(ClientApp));
			// Always start client process and don't wait for exit.
			ProcessResult ClientProcess = Run(ClientApp, ClientCmdLine, null, ClientRunFlags | ERunOptions.NoWaitForExit);
			PopDir();

			return ClientProcess;
		}
コード例 #33
0
		/// <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;
		}
コード例 #34
0
 /// <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>
 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)
 {
     RunAndLog(App, CommandLine, GetRunAndLogLogName(Env, App, LogName), MaxSuccessCode, Input, Options, EnvVars);
 }
コード例 #35
0
		/// <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);
		}
コード例 #36
0
	public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
	{
		// look for browser
		var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine"));
		bool ok = false;
		List<string> Devices;
		string browserPath = "";
		string DeviceName = Params.Device.Split('@')[1];
		DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on "));

		if (ConfigCache.GetArray("/Script/HTML5PlatformEditor.HTML5SDKSettings", "DeviceMap", out Devices))
		{
			foreach (var Dev in Devices)
			{
				var Matched = Regex.Match(Dev, "\\(DeviceName=\"(.*)\",DevicePath=\\(FilePath=\"(.*)\"\\)\\)", RegexOptions.IgnoreCase);
				if (Matched.Success && Matched.Groups[1].ToString() == DeviceName)
				{
					browserPath = Matched.Groups[2].ToString();
					ok = true;
					break;
				}
			}
		}

		if (!ok && HTML5SDKInfo.bAllowFallbackSDKSettings)
		{
			string DeviceSection;

			if (Utils.IsRunningOnMono)
			{
				DeviceSection = "HTML5DevicesMac";
			}
			else
			{
				DeviceSection = "HTML5DevicesWindows";
			}

			ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath);
		}

		if (!ok)
		{
			throw new System.Exception("Incorrect browser configuration in HTML5Engine.ini ");
		}

		// open the webpage
		Int32 ServerPort = 8000;
		ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "DeployServerPort", out ServerPort);
		string WorkingDirectory = Path.GetDirectoryName(ClientApp);
		string url = Path.GetFileName(ClientApp) +".html";
		// Are we running via cook on the fly server?
		// find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not.
		bool IsCookOnTheFly = false;

		// 9/24/2014 @fixme - All this is convoluted, clean up.
		// looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT)
		// This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly. 

		if (ClientCmdLine.Contains("filehostip"))
		{
			IsCookOnTheFly = true; 
			url = "http://127.0.0.1:41898/" + url; 
		}

		if (IsCookOnTheFly)
		{
			url += "?cookonthefly=true";
		}
		else
		{
			url = String.Format("http://{2}:{0}/{1}", ServerPort, url, Environment.MachineName);
		}

		// Check HTML5LaunchHelper source for command line args

		var LowerBrowserPath = browserPath.ToLower();
		var ProfileDirectory = Path.Combine(Utils.GetUserSettingDirectory(), "UE4_HTML5", "user");

		string BrowserCommandline = url; 

		if (LowerBrowserPath.Contains("chrome"))
		{
			BrowserCommandline  += "  " + String.Format("--user-data-dir=\"{0}\" --enable-logging --no-first-run", Path.Combine(ProfileDirectory, "chrome"));
		}
		else if (LowerBrowserPath.Contains("firefox"))
		{
			BrowserCommandline += "  " +  String.Format("-no-remote -profile \"{0}\"", Path.Combine(ProfileDirectory, "firefox"));
		}

		string LauncherArguments = string.Format( " -Browser=\"{0}\" + -BrowserCommandLine=\"{1}\" -ServerPort=\"{2}\" -ServerRoot=\"{3}\" ", new object[] { browserPath,BrowserCommandline,ServerPort,WorkingDirectory });

		var LaunchHelperPath = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe");
		ProcessResult BrowserProcess = Run(LaunchHelperPath, LauncherArguments, null, ClientRunFlags | ERunOptions.NoWaitForExit);
	
		return BrowserProcess;

	}
コード例 #37
0
    public override IProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        string BatchPath = GetBatchPath(Params, null);

        return(Run(BatchPath, ClientCmdLine, null, ERunOptions.Default));
    }
コード例 #38
0
    public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        // look for browser
        var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine"));

        string DeviceSection;

        if ( Utils.IsRunningOnMono )
        {
            DeviceSection = "HTML5DevicesMac";
        }
        else
        {
            DeviceSection = "HTML5DevicesWindows";
        }

        string browserPath;
        string DeviceName = Params.Device.Split('@')[1];
        DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on "));
        bool ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath);

        if (!ok)
            throw new System.Exception ("Incorrect browser configuration in HTML5Engine.ini ");

        // open the webpage
        string directory = Path.GetDirectoryName(ClientApp);
        string url = Path.GetFileName(ClientApp) +".html";
        // Are we running via cook on the fly server?
        // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not.
        bool IsCookOnTheFly = false;

        // 9/24/2014 @fixme - All this is convoluted, clean up.
        // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT)
        // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly.

        if (ClientCmdLine.Contains("filehostip"))
        {
            IsCookOnTheFly = true;
            url = "http://127.0.0.1:41898/" + url;
        }

        if (IsCookOnTheFly)
        {
            url += "?cookonthefly=true";
        }
        else
        {
            var EmscriptenSettings = ReadEmscriptenSettings();
            url = "http://127.0.0.1:8000/" + url;
            // this will be killed UBT instances dies.
            string input = String.Format(" -m SimpleHTTPServer 8000");

            string PythonName = null;
            // Check the .emscripten file for a possible python path
            if (EmscriptenSettings.ContainsKey("PYTHON"))
            {
                PythonName = EmscriptenSettings["PYTHON"];
                Log("Found python path {0} in emscripten file", PythonName);
            }
            // The AutoSDK defines this env var as part of its install. See setup.bat/unsetup.bat
            // If it's missing then just assume that python lives on the path
            if (PythonName == null && Environment.GetEnvironmentVariable("PYTHON") != null)
            {
                PythonName = Environment.GetEnvironmentVariable("PYTHON");
                Log("Found python path {0} in PYTHON Environment Variable", PythonName);
            }

            // Check if the exe exists
            if (!System.IO.File.Exists(PythonName))
            {
                Log("Either no python path can be found or it doesn't exist. Using python on PATH");
                PythonName = Utils.IsRunningOnMono ? "python" : "python.exe";
            }

            ProcessResult Result = ProcessManager.CreateProcess(PythonName, true, "html5server.log");
            Result.ProcessObject.StartInfo.FileName = PythonName;
            Result.ProcessObject.StartInfo.UseShellExecute = false;
            Result.ProcessObject.StartInfo.RedirectStandardOutput = true;
            Result.ProcessObject.StartInfo.RedirectStandardInput = true;
            Result.ProcessObject.StartInfo.WorkingDirectory = directory;
            Result.ProcessObject.StartInfo.Arguments = input;
            Result.ProcessObject.Start();

            Result.ProcessObject.OutputDataReceived += delegate(object sender, System.Diagnostics.DataReceivedEventArgs e)
            {
                System.Console.WriteLine(e.Data);
            };

            System.Console.WriteLine("Starting Browser Process");

            // safari specific hack.
            string argument = url;
            if (browserPath.Contains ("Safari") && Utils.IsRunningOnMono)
                argument = "";

            ProcessResult ClientProcess = Run(browserPath, argument, null, ClientRunFlags | ERunOptions.NoWaitForExit);

            ClientProcess.ProcessObject.EnableRaisingEvents = true;
            ClientProcess.ProcessObject.Exited += delegate(System.Object o, System.EventArgs e)
            {
                System.Console.WriteLine("Browser Process Ended - Killing Webserver");
                // send kill.
                Result.ProcessObject.StandardInput.Close();
                Result.ProcessObject.Kill();
            };

            // safari needs a hack.
            // http://superuser.com/questions/689315/run-safari-from-terminal-with-given-url-address-without-open-command

            if (browserPath.Contains ("Safari") && Utils.IsRunningOnMono)
            {
                // ClientProcess.ProcessObject.WaitForInputIdle ();
                Thread.Sleep (2000);
                Process.Start("/usr/bin/osascript"," -e 'tell application \"Safari\" to open location \"" + url + "\"'" );
            }

            return ClientProcess;
        }

        System.Console.WriteLine("Browser Path " + browserPath);
        ProcessResult BrowserProcess = Run(browserPath, url, null, ClientRunFlags | ERunOptions.NoWaitForExit);

        return BrowserProcess;
    }
コード例 #39
0
    public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        if (UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
        {
            string AppDirectory = string.Format("{0}/Payload/{1}.app",
                Path.GetDirectoryName(Params.ProjectGameExeFilename),
                Path.GetFileNameWithoutExtension(Params.ProjectGameExeFilename));
            string GameName = Path.GetFileNameWithoutExtension (ClientApp);
            if (GameName.Contains ("-IOS-"))
            {
                GameName = GameName.Substring (0, GameName.IndexOf ("-IOS-"));
            }
            string GameApp = AppDirectory + "/" + GameName;
            bool bWasGenerated = false;
            string XcodeProj = EnsureXcodeProjectExists (Params.RawProjectPath, CmdEnv.LocalRoot, Params.ShortProjectName, GetDirectoryName(Params.RawProjectPath), Params.IsCodeBasedProject, out bWasGenerated);
            string Arguments = "UBT_NO_POST_DEPLOY=true /usr/bin/xcrun xcodebuild test -project \"" + XcodeProj + "\"";
            Arguments += " -scheme '";
            Arguments += GameName;
            Arguments += " - iOS'";
            Arguments += " -configuration " + Params.ClientConfigsToBuild [0].ToString();
            Arguments += " -destination 'platform=iOS,id=" + Params.Device.Substring(4) + "'";
            Arguments += " TEST_HOST=\"";
            Arguments += GameApp;
            Arguments += "\" BUNDLE_LOADER=\"";
            Arguments += GameApp + "\"";
            ProcessResult ClientProcess = Run ("/usr/bin/env", Arguments, null, ClientRunFlags | ERunOptions.NoWaitForExit);
            return ClientProcess;
        }
        else
        {
            // get the CFBundleIdentifier and modify the command line
            int Pos = ClientCmdLine.IndexOf("-Exe=") + 6;
            int EndPos = ClientCmdLine.IndexOf("-Targetplatform=") - 2;
            string Exe = ClientCmdLine.Substring(Pos, EndPos - Pos);

            // check for Info.plist
            if (string.IsNullOrEmpty(Params.StageDirectoryParam))
            {
                // need to crack open the ipa and read it from there - todo
            }
            else
            {
                if (File.Exists(Params.BaseStageDirectory+"/IOS/Info.plist"))
                {
                    string Contents = File.ReadAllText(Params.BaseStageDirectory + "/IOS/Info.plist");
                    Pos = Contents.IndexOf("CFBundleIdentifier");
                    Pos = Contents.IndexOf("<string>", Pos) + 8;
                    EndPos = Contents.IndexOf("</string>", Pos);
                    string id = Contents.Substring(Pos, EndPos - Pos);
                    id = id.Substring(id.LastIndexOf(".") + 1);
                    ClientCmdLine = ClientCmdLine.Replace(Exe, id + ".stub");
                }
            }

            return base.RunClient(ClientRunFlags, ClientApp, ClientCmdLine, Params);
        }
    }
コード例 #40
0
	private static void RunStandaloneClient(List<DeploymentContext> DeployContextList, string ClientLogFile, ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
	{
		if (Params.Unattended)
		{
			string LookFor = "Bringing up level for play took";
			bool bCommandlet = false;

			if (Params.RunAutomationTest != "")
			{
				LookFor = "Automation Test Succeeded";
			}
			else if (Params.RunAutomationTests)
			{
				LookFor = "Automation Test Queue Empty";
			}
			else if (Params.EditorTest)
			{
				LookFor = "Asset discovery search completed in";
			}
			// If running a commandlet, just detect a normal exit
			else if (ClientCmdLine.IndexOf("-run=", StringComparison.InvariantCultureIgnoreCase) >= 0)
			{
				LookFor = "Game engine shut down";
				bCommandlet = true;
			}

			{

				string AllClientOutput = "";
				int LastAutoFailIndex = -1;
				ProcessResult ClientProcess = null;
				FileStream ClientProcessLog = null;
				StreamReader ClientLogReader = null;
				LogConsole("Starting Client for unattended test....");
				ClientProcess = Run(ClientApp, ClientCmdLine + " -FORCELOGFLUSH -testexit=\"" + LookFor + "\"", null, ClientRunFlags | ERunOptions.NoWaitForExit);
				while (!FileExists(ClientLogFile) && !ClientProcess.HasExited)
				{
					LogConsole("Waiting for client logging process to start...{0}", ClientLogFile);
					Thread.Sleep(2000);
				}
				if (FileExists(ClientLogFile))
				{
					Thread.Sleep(2000);
					LogConsole("Client logging process started...{0}", ClientLogFile);
					ClientProcessLog = File.Open(ClientLogFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
					ClientLogReader = new StreamReader(ClientProcessLog);
				}
				if (ClientLogReader == null)
				{
					throw new AutomationException("Client exited without creating a log file.");
				}
				bool bKeepReading = true;
				bool WelcomedCorrectly = false;
				bool bClientExited = false;
				DateTime ExitTime = DateTime.UtcNow;

				while (bKeepReading)
				{
					if (!bClientExited && ClientProcess.HasExited)
					{
						ExitTime = DateTime.UtcNow;
						bClientExited = true;
					}
					string ClientOutput = ClientLogReader.ReadToEnd();
					if (!String.IsNullOrEmpty(ClientOutput))
					{
						if (bClientExited)
						{
							ExitTime = DateTime.UtcNow; // as long as it is spewing, we reset the timer
						}
						AllClientOutput += ClientOutput;
						Console.Write(ClientOutput);

						if (AllClientOutput.LastIndexOf(LookFor) > AllClientOutput.IndexOf(LookFor))
						{
							WelcomedCorrectly = true;
							LogConsole("Test complete...");
							bKeepReading = false;
						}
						else if (Params.RunAutomationTests)
						{
							int FailIndex = AllClientOutput.LastIndexOf("Automation Test Failed");
							int ParenIndex = AllClientOutput.LastIndexOf(")");
							if (FailIndex >= 0 && ParenIndex > FailIndex && FailIndex > LastAutoFailIndex)
							{
								string Tail = AllClientOutput.Substring(FailIndex);
								int CloseParenIndex = Tail.IndexOf(")");
								int OpenParenIndex = Tail.IndexOf("(");
								string Test = "";
								if (OpenParenIndex >= 0 && CloseParenIndex > OpenParenIndex)
								{
									Test = Tail.Substring(OpenParenIndex + 1, CloseParenIndex - OpenParenIndex - 1);
									LogError("Automated test failed ({0}).", Test);
									LastAutoFailIndex = FailIndex;
								}
							}
						}
						// Detect commandlet failure
						else if (bCommandlet)
						{
							const string ResultLog = "Commandlet->Main return this error code: ";

							int ResultStart = AllClientOutput.LastIndexOf(ResultLog);
							int ResultValIdx = ResultStart + ResultLog.Length;

							if (ResultStart >= 0 && ResultValIdx < AllClientOutput.Length &&
								AllClientOutput.Substring(ResultValIdx, 1) == "1")
							{
								// Parse the full commandlet warning/error summary
								string FullSummary = "";
								int SummaryStart = AllClientOutput.LastIndexOf("Warning/Error Summary");
								
								if (SummaryStart >= 0 && SummaryStart < ResultStart)
								{
									FullSummary = AllClientOutput.Substring(SummaryStart, ResultStart - SummaryStart);
								}


								if (FullSummary.Length > 0)
								{
									LogError("Commandlet failed, summary:" + Environment.NewLine +
																					FullSummary);
								}
								else
								{
									LogError("Commandlet failed.");
								}
							}
						}
					}
					else if (bClientExited && (DateTime.UtcNow - ExitTime).TotalSeconds > 30)
					{
						LogConsole("Client exited and has been quiet for 30 seconds...exiting");
						bKeepReading = false;
					}
				}
				if (ClientProcess != null && !ClientProcess.HasExited)
				{
					LogConsole("Client is supposed to exit, lets wait a while for it to exit naturally...");
					for (int i = 0; i < 120 && !ClientProcess.HasExited; i++)
					{
						Thread.Sleep(1000);
					}
				}
				if (ClientProcess != null && !ClientProcess.HasExited)
				{
					LogConsole("Stopping client...");
					ClientProcess.StopProcess();
					Thread.Sleep(10000);
				}
				while (ClientLogReader != null && !ClientLogReader.EndOfStream)
				{
					string ClientOutput = ClientLogReader.ReadToEnd();
					if (!String.IsNullOrEmpty(ClientOutput))
					{
						Console.Write(ClientOutput);
					}
				}

				if (!WelcomedCorrectly)
				{
					throw new AutomationException("Client exited before we asked it to.");
				}
			}
		}
		else
		{
			var SC = DeployContextList[0];
			ProcessResult ClientProcess = SC.StageTargetPlatform.RunClient(ClientRunFlags, ClientApp, ClientCmdLine, Params);
			if (ClientProcess != null)
			{
				// If the client runs without StdOut redirect we're going to read the log output directly from log file on
				// a separate thread.
				if ((ClientRunFlags & ERunOptions.NoStdOutRedirect) == ERunOptions.NoStdOutRedirect)
				{
					ClientLogReaderThread = new System.Threading.Thread(ClientLogReaderProc);
					ClientLogReaderThread.Start(new object[] { ClientLogFile, ClientProcess });
				}

				do
				{
					Thread.Sleep(100);
				}
				while (ClientProcess.HasExited == false);

				SC.StageTargetPlatform.PostRunClient(ClientProcess, Params);

                // any non-zero exit code should propagate an exception. The Virtual function above may have
                // already thrown a more specific exception or given a more specific ErrorCode, but this catches the rest.
				if (ClientProcess.ExitCode != 0)
				{
					throw new AutomationException("Client exited with error code: " + ClientProcess.ExitCode);
				}
			}
		}
	}
コード例 #41
0
    public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        string DeviceArchitecture = GetBestDeviceArchitecture(Params);
        string GPUArchitecture    = "";

        string ApkName = ClientApp + DeviceArchitecture + ".apk";

        if (!File.Exists(ApkName))
        {
            ApkName = GetFinalApkName(Params, Path.GetFileNameWithoutExtension(ClientApp), true, DeviceArchitecture, GPUArchitecture);
        }

        Console.WriteLine("Apk='{0}', ClientApp='{1}', ExeName='{2}'", ApkName, ClientApp, Params.ProjectGameExeFilename);

        // run aapt to get the name of the intent
        string PackageName = GetPackageInfo(ApkName, false);

        if (PackageName == null)
        {
            ErrorReporter.Error("Failed to get package name from " + ClientApp, (int)ErrorCodes.Error_FailureGettingPackageInfo);
            throw new AutomationException("Failed to get package name from " + ClientApp);
        }

        string AdbCommand  = GetAdbCommand(Params);
        string CommandLine = "shell am start -n " + PackageName + "/com.epicgames.ue4.GameActivity";

        if (Params.Prebuilt)
        {
            // clear the log
            Run(CmdEnv.CmdExe, AdbCommand + "logcat -c");
        }

        // Send a command to unlock the device before we try to run it
        string UnlockCommandLine = "shell input keyevent 82";

        Run(CmdEnv.CmdExe, AdbCommand + UnlockCommandLine, null);

        // start the app on device!
        ProcessResult ClientProcess = Run(CmdEnv.CmdExe, AdbCommand + CommandLine, null, ClientRunFlags);


        if (Params.Prebuilt)
        {
            // save the output to the staging directory
            string LogPath           = Path.Combine(Params.BaseStageDirectory, "Android\\logs");
            string LogFilename       = Path.Combine(LogPath, "devicelog" + Params.Device + ".log");
            string ServerLogFilename = Path.Combine(CmdEnv.LogFolder, "devicelog" + Params.Device + ".log");

            Directory.CreateDirectory(LogPath);

            // check if the game is still running
            // time out if it takes to long
            DateTime StartTime      = DateTime.Now;
            int      TimeOutSeconds = Params.RunTimeoutSeconds;

            while (true)
            {
                ProcessResult ProcessesResult = Run(CmdEnv.CmdExe, AdbCommand + "shell ps", null, ERunOptions.SpewIsVerbose);

                string RunningProcessList = ProcessesResult.Output;
                if (!RunningProcessList.Contains(PackageName))
                {
                    break;
                }
                Thread.Sleep(10);

                TimeSpan DeltaRunTime = DateTime.Now - StartTime;
                if ((DeltaRunTime.TotalSeconds > TimeOutSeconds) && (TimeOutSeconds != 0))
                {
                    Log("Device: " + Params.Device + " timed out while waiting for run to finish");
                    break;
                }
            }

            // this is just to get the ue4 log to go to the output
            Run(CmdEnv.CmdExe, AdbCommand + "logcat -d -s UE4 -s Debug");

            // get the log we actually want to save
            ProcessResult LogFileProcess = Run(CmdEnv.CmdExe, AdbCommand + "logcat -d", null, ERunOptions.AppMustExist);

            File.WriteAllText(LogFilename, LogFileProcess.Output);
            File.WriteAllText(ServerLogFilename, LogFileProcess.Output);
        }


        return(ClientProcess);
    }
コード例 #42
0
	private static void SetupClientParams(List<DeploymentContext> DeployContextList, ProjectParams Params, string ClientLogFile, out ERunOptions ClientRunFlags, out string ClientApp, out string ClientCmdLine)
	{
		if (Params.ClientTargetPlatforms.Count == 0)
		{
			throw new AutomationException("No ClientTargetPlatform set for SetupClientParams.");
		}

		//		var DeployContextList = CreateDeploymentContext(Params, false);

		if (DeployContextList.Count == 0)
		{
			throw new AutomationException("No DeployContextList for SetupClientParams.");
		}

		var SC = DeployContextList[0];

		// Get client app name and command line.
		ClientRunFlags = ERunOptions.AllowSpew | ERunOptions.AppMustExist;
		ClientApp = "";
		ClientCmdLine = "";
		string TempCmdLine = "";
		var PlatformName = Params.ClientTargetPlatforms[0].ToString();
		if (Params.Cook || Params.CookOnTheFly)
		{
			List<string> Exes = SC.StageTargetPlatform.GetExecutableNames(SC, true);
			ClientApp = Exes[0];
			if (SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.IOS)
			{
				TempCmdLine += SC.ProjectArgForCommandLines + " ";
			}
			TempCmdLine += Params.MapToRun + " ";

			if (Params.CookOnTheFly || Params.FileServer)
			{
				TempCmdLine += "-filehostip=";
				bool FirstParam = true;
				if (UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
				{
					NetworkInterface[] Interfaces = NetworkInterface.GetAllNetworkInterfaces();
					foreach (NetworkInterface adapter in Interfaces)
					{
						if (adapter.NetworkInterfaceType != NetworkInterfaceType.Loopback)
						{
							IPInterfaceProperties IP = adapter.GetIPProperties();
							for (int Index = 0; Index < IP.UnicastAddresses.Count; ++Index)
							{
								if (IP.UnicastAddresses[Index].IsDnsEligible && IP.UnicastAddresses[Index].Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
								{
									if (!IsNullOrEmpty(Params.Port))
									{
										foreach (var Port in Params.Port)
										{
											if (!FirstParam)
											{
												TempCmdLine += "+";
											}
											FirstParam = false;
											string[] PortProtocol = Port.Split(new char[] { ':' });
											if (PortProtocol.Length > 1)
											{
												TempCmdLine += String.Format("{0}://{1}:{2}", PortProtocol[0], IP.UnicastAddresses[Index].Address.ToString(), PortProtocol[1]);
											}
											else
											{
												TempCmdLine += IP.UnicastAddresses[Index].Address.ToString();
												TempCmdLine += ":";
												TempCmdLine += Params.Port;
											}
										}
									}
                                    else
                                    {
										if (!FirstParam)
										{
											TempCmdLine += "+";
										}
										FirstParam = false;
										
										// use default port
                                        TempCmdLine += IP.UnicastAddresses[Index].Address.ToString();
                                    }
								}
							}
						}
					}
				}
				else
				{
					NetworkInterface[] Interfaces = NetworkInterface.GetAllNetworkInterfaces();
					foreach (NetworkInterface adapter in Interfaces)
					{
						if (adapter.OperationalStatus == OperationalStatus.Up)
						{
							IPInterfaceProperties IP = adapter.GetIPProperties();
							for (int Index = 0; Index < IP.UnicastAddresses.Count; ++Index)
							{
								if (IP.UnicastAddresses[Index].IsDnsEligible)
								{
									if (!IsNullOrEmpty(Params.Port))
									{
										foreach (var Port in Params.Port)
										{
											if (!FirstParam)
											{
												TempCmdLine += "+";
											}
											FirstParam = false;
											string[] PortProtocol = Port.Split(new char[] { ':' });
											if (PortProtocol.Length > 1)
											{
												TempCmdLine += String.Format("{0}://{1}:{2}", PortProtocol[0], IP.UnicastAddresses[Index].Address.ToString(), PortProtocol[1]);
											}
											else
											{
												TempCmdLine += IP.UnicastAddresses[Index].Address.ToString();
												TempCmdLine += ":";
												TempCmdLine += Params.Port;
											}
										}
									}
                                    else
                                    {
										if (!FirstParam)
										{
											TempCmdLine += "+";
										}
										FirstParam = false;
										
										// use default port
                                        TempCmdLine += IP.UnicastAddresses[Index].Address.ToString();
                                    }
								}
							}
						}
					}
				}

				const string LocalHost = "127.0.0.1";

				if (!IsNullOrEmpty(Params.Port))
				{
					foreach (var Port in Params.Port)
					{
						if (!FirstParam)
						{
							TempCmdLine += "+";
						}
						FirstParam = false;
						string[] PortProtocol = Port.Split(new char[] { ':' });
						if (PortProtocol.Length > 1)
						{
							TempCmdLine += String.Format("{0}://{1}:{2}", PortProtocol[0], LocalHost, PortProtocol[1]);
						}
						else
						{
							TempCmdLine += LocalHost;
							TempCmdLine += ":";
							TempCmdLine += Params.Port;
						}

					}
				}
                else
                {
					if (!FirstParam)
					{
						TempCmdLine += "+";
					}
					FirstParam = false;
					
					// use default port
                    TempCmdLine += LocalHost;
                }
				TempCmdLine += " ";

				if (Params.CookOnTheFlyStreaming)
				{
					TempCmdLine += "-streaming ";
				}
				else if (SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.IOS)
				{
					// per josh, allowcaching is deprecated/doesn't make sense for iOS.
					TempCmdLine += "-allowcaching ";
				}
			}
			else if (Params.UsePak(SC.StageTargetPlatform) || Params.SignedPak)
			{
				if (Params.SignedPak)
				{
					TempCmdLine += "-signedpak ";
				}
				else
				{
					TempCmdLine += "-pak ";
				}
			}
			else if (!Params.Stage)
			{
				var SandboxPath = CombinePaths(SC.RuntimeProjectRootDir, "Saved", "Cooked", SC.CookPlatform);
				if (!SC.StageTargetPlatform.LaunchViaUFE)
				{
					TempCmdLine += "-sandbox=" + CommandUtils.MakePathSafeToUseWithCommandLine(SandboxPath) + " ";
				}
				else
				{
					TempCmdLine += "-sandbox=\'" + SandboxPath + "\' ";
				}
			}
		}
		else
		{
			ClientApp = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries", PlatformName, "UE4Editor.exe");
			TempCmdLine += SC.ProjectArgForCommandLines + " ";
			if (!Params.EditorTest)
			{
				TempCmdLine += "-game " + Params.MapToRun + " ";
			}
		}
		if (Params.LogWindow)
		{
			// Without NoStdOutRedirect '-log' doesn't log anything to the window
			ClientRunFlags |= ERunOptions.NoStdOutRedirect;
			TempCmdLine += "-log ";
		}
		else
		{
			TempCmdLine += "-stdout ";
		}
		if (Params.Unattended)
		{
			TempCmdLine += "-unattended ";
		}
		if (IsBuildMachine || Params.Unattended)
		{
			TempCmdLine += "-buildmachine ";
		}
		if (Params.CrashIndex > 0)
		{
			int RealIndex = Params.CrashIndex - 1;
			if (RealIndex < 0 || RealIndex >= CrashCommands.Count())
			{
				throw new AutomationException("CrashIndex {0} is out of range...max={1}", Params.CrashIndex, CrashCommands.Count());
			}
			TempCmdLine += String.Format("-execcmds=\"debug {0}\" ", CrashCommands[RealIndex]);
		}
		else if (Params.RunAutomationTest != "")
		{
			TempCmdLine += "-execcmds=\"automation list;runtests " + Params.RunAutomationTest + "\" ";
		}
		else if (Params.RunAutomationTests)
		{
			TempCmdLine += "-execcmds=\"automation list;runall\" ";
		}
		if (SC.StageTargetPlatform.UseAbsLog)
		{
			TempCmdLine += "-abslog=" + CommandUtils.MakePathSafeToUseWithCommandLine(ClientLogFile) + " ";
		}
		if (SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.IOS)
		{
			TempCmdLine += "-Messaging -nomcp -Windowed ";
		}
		else
		{
			// skip arguments which don't make sense for iOS
			TempCmdLine += "-Messaging -nomcp ";
		}
		if (Params.NullRHI && SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.Mac) // all macs have GPUs, and currently the mac dies with nullrhi
		{
			TempCmdLine += "-nullrhi ";
		}
		if (Params.Deploy && SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.PS4)
		{
			TempCmdLine += "-deployedbuild ";
		}

		TempCmdLine += "-CrashForUAT ";
		TempCmdLine += Params.RunCommandline;

		// todo: move this into the platform
		if (SC.StageTargetPlatform.LaunchViaUFE)
		{
			ClientCmdLine = "-run=Launch ";
			ClientCmdLine += "-Device=" + Params.Device + " ";
			ClientCmdLine += "-Exe=\"" + ClientApp + "\" ";
			ClientCmdLine += "-Targetplatform=" + Params.ClientTargetPlatforms[0].ToString() + " ";
			ClientCmdLine += "-Params=\"" + TempCmdLine + "\"";
			ClientApp = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/Win64/UnrealFrontend.exe");

			LogConsole("Launching via UFE:");
			LogConsole("\tClientCmdLine: " + ClientCmdLine + "");
		}
		else
		{
			ClientCmdLine = TempCmdLine;
		}
	}
コード例 #43
0
        /// <summary>
        /// Runs a commandlet using Engine/Binaries/Win64/UE4Editor-Cmd.exe.
        /// </summary>
        /// <param name="ProjectFile">Project name.</param>
        /// <param name="UE4Exe">The name of the UE4 Editor executable to use.</param>
        /// <param name="Commandlet">Commandlet name.</param>
        /// <param name="Parameters">Command line parameters (without -run=)</param>
        public static void RunCommandlet(FileReference ProjectName, string UE4Exe, string Commandlet, string Parameters = null)
        {
            Log("Running UE4Editor {0} for project {1}", Commandlet, ProjectName);

            var CWD = Path.GetDirectoryName(UE4Exe);

            string EditorExe = UE4Exe;

            if (String.IsNullOrEmpty(CWD))
            {
                EditorExe = HostPlatform.Current.GetUE4ExePath(UE4Exe);
                CWD       = CombinePaths(CmdEnv.LocalRoot, HostPlatform.Current.RelativeBinariesFolder);
            }

            PushDir(CWD);

            DateTime StartTime = DateTime.UtcNow;

            string LocalLogFile = LogUtils.GetUniqueLogName(CombinePaths(CmdEnv.EngineSavedFolder, Commandlet));

            Log("Commandlet log file is {0}", LocalLogFile);
            string Args = String.Format(
                "{0} -run={1} {2} -abslog={3} -stdout -CrashForUAT -unattended {5}{4}",
                (ProjectName == null) ? "" : CommandUtils.MakePathSafeToUseWithCommandLine(ProjectName.FullName),
                Commandlet,
                String.IsNullOrEmpty(Parameters) ? "" : Parameters,
                CommandUtils.MakePathSafeToUseWithCommandLine(LocalLogFile),
                IsBuildMachine ? "-buildmachine" : "",
                (GlobalCommandLine.Verbose || GlobalCommandLine.AllowStdOutLogVerbosity) ? "-AllowStdOutLogVerbosity " : ""
                );
            ERunOptions Opts = ERunOptions.Default;

            if (GlobalCommandLine.UTF8Output)
            {
                Args += " -UTF8Output";
                Opts |= ERunOptions.UTF8Output;
            }
            var RunResult = Run(EditorExe, Args, Options: Opts);

            PopDir();

            // Draw attention to signal exit codes on Posix systems, rather than just printing the exit code
            if (RunResult.ExitCode > 128 && RunResult.ExitCode < 128 + 32)
            {
                if (RunResult.ExitCode == 139)
                {
                    CommandUtils.LogError("Editor terminated abnormally due to a segmentation fault");
                }
                else
                {
                    CommandUtils.LogError("Editor terminated abnormally with signal {0}", RunResult.ExitCode - 128);
                }
            }

            // If we're running on a Mac, dump all the *.crash files that were generated while the editor was running.
            if (HostPlatform.Current.HostEditorPlatform == UnrealTargetPlatform.Mac)
            {
                // If the exit code indicates the main process crashed, introduce a small delay because the crash report is written asynchronously.
                // If we exited normally, still check without waiting in case SCW or some other child process crashed.
                if (RunResult.ExitCode > 128)
                {
                    CommandUtils.Log("Pausing before checking for crash logs...");
                    Thread.Sleep(10 * 1000);
                }

                // Create a list of directories containing crash logs, and add the system log folder
                List <string> CrashDirs = new List <string>();
                CrashDirs.Add("/Library/Logs/DiagnosticReports");

                // Add the user's log directory too
                string HomeDir = Environment.GetEnvironmentVariable("HOME");
                if (!String.IsNullOrEmpty(HomeDir))
                {
                    CrashDirs.Add(Path.Combine(HomeDir, "Library/Logs/DiagnosticReports"));
                }

                // Check each directory for crash logs
                List <FileInfo> CrashFileInfos = new List <FileInfo>();
                foreach (string CrashDir in CrashDirs)
                {
                    try
                    {
                        DirectoryInfo CrashDirInfo = new DirectoryInfo(CrashDir);
                        if (CrashDirInfo.Exists)
                        {
                            CrashFileInfos.AddRange(CrashDirInfo.EnumerateFiles("*.crash", SearchOption.TopDirectoryOnly).Where(x => x.LastWriteTimeUtc >= StartTime));
                        }
                    }
                    catch (UnauthorizedAccessException)
                    {
                        // Not all account types can access /Library/Logs/DiagnosticReports
                    }
                }

                // Dump them all to the log
                foreach (FileInfo CrashFileInfo in CrashFileInfos)
                {
                    // snmpd seems to often crash (suspect due to it being starved of CPU cycles during cooks)
                    if (!CrashFileInfo.Name.StartsWith("snmpd_"))
                    {
                        CommandUtils.Log("Found crash log - {0}", CrashFileInfo.FullName);
                        try
                        {
                            string[] Lines = File.ReadAllLines(CrashFileInfo.FullName);
                            foreach (string Line in Lines)
                            {
                                CommandUtils.Log("Crash: {0}", Line);
                            }
                        }
                        catch (Exception Ex)
                        {
                            CommandUtils.LogWarning("Failed to read file ({0})", Ex.Message);
                        }
                    }
                }
            }

            // Copy the local commandlet log to the destination folder.
            string DestLogFile = LogUtils.GetUniqueLogName(CombinePaths(CmdEnv.LogFolder, Commandlet));

            if (!CommandUtils.CopyFile_NoExceptions(LocalLogFile, DestLogFile))
            {
                CommandUtils.LogWarning("Commandlet {0} failed to copy the local log file from {1} to {2}. The log file will be lost.", Commandlet, LocalLogFile, DestLogFile);
            }
            string ProjectStatsDirectory = CombinePaths((ProjectName == null)? CombinePaths(CmdEnv.LocalRoot, "Engine") : Path.GetDirectoryName(ProjectName.FullName), "Saved", "Stats");

            if (Directory.Exists(ProjectStatsDirectory))
            {
                string DestCookerStats = CmdEnv.LogFolder;
                foreach (var StatsFile in Directory.EnumerateFiles(ProjectStatsDirectory, "*.csv"))
                {
                    if (!CommandUtils.CopyFile_NoExceptions(StatsFile, CombinePaths(DestCookerStats, Path.GetFileName(StatsFile))))
                    {
                        CommandUtils.LogWarning("Commandlet {0} failed to copy the local log file from {1} to {2}. The log file will be lost.", Commandlet, StatsFile, CombinePaths(DestCookerStats, Path.GetFileName(StatsFile)));
                    }
                }
            }
//			else
//			{
//				CommandUtils.LogWarning("Failed to find directory {0} will not save stats", ProjectStatsDirectory);
//			}

            // Whether it was copied correctly or not, delete the local log as it was only a temporary file.
            CommandUtils.DeleteFile_NoExceptions(LocalLogFile);

            if (RunResult.ExitCode != 0)
            {
                throw new CommandletException(DestLogFile, RunResult.ExitCode, "BUILD FAILED: Failed while running {0} for {1}; see log {2}", Commandlet, ProjectName, DestLogFile);
            }
        }
コード例 #44
0
    public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        // look for browser
        string BrowserPath = Params.Device.Replace("HTML5@", "");

        // open the webpage
        Int32 ServerPort = 8000;

        var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine"));
        ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "DeployServerPort", out ServerPort);
        string WorkingDirectory = Path.GetDirectoryName(ClientApp);
        string url = Path.GetFileName(ClientApp) +".html";
        // Are we running via cook on the fly server?
        // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not.
        bool IsCookOnTheFly = false;

        // 9/24/2014 @fixme - All this is convoluted, clean up.
        // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT)
        // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly.

        if (ClientCmdLine.Contains("filehostip"))
        {
            IsCookOnTheFly = true;
            url = "http://127.0.0.1:41898/" + url;
        }

        if (IsCookOnTheFly)
        {
            url += "?cookonthefly=true";
        }
        else
        {
            url = String.Format("http://localhost:{0}/{1}", ServerPort, url);
        }

        // Check HTML5LaunchHelper source for command line args

        var LowerBrowserPath = BrowserPath.ToLower();
        var ProfileDirectory = Path.Combine(Utils.GetUserSettingDirectory(), "UE4_HTML5", "user");

        string BrowserCommandline = url;

        if (LowerBrowserPath.Contains("chrome"))
        {
            BrowserCommandline  += "  " + String.Format("--user-data-dir=\"{0}\" --enable-logging --no-first-run", Path.Combine(ProfileDirectory, "chrome"));
        }
        else if (LowerBrowserPath.Contains("firefox"))
        {
            BrowserCommandline += "  " +  String.Format("-no-remote -profile \"{0}\"", Path.Combine(ProfileDirectory, "firefox"));
        }

        string LauncherArguments = string.Format(" -Browser=\"{0}\" + -BrowserCommandLine=\"{1}\" -ServerPort=\"{2}\" -ServerRoot=\"{3}\" ", new object[] { BrowserPath, BrowserCommandline, ServerPort, WorkingDirectory });

        var LaunchHelperPath = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe");
        ProcessResult BrowserProcess = Run(LaunchHelperPath, LauncherArguments, null, ClientRunFlags | ERunOptions.NoWaitForExit);

        return BrowserProcess;
    }
コード例 #45
0
    private static void RunStandaloneClient(List<DeploymentContext> DeployContextList, string ClientLogFile, ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params)
    {
        if (Params.Unattended)
        {
            int Timeout = 60 * 30;
            if (Params.RunAutomationTests)
            {
                Timeout = 6 * 60 * 60;
            }
            using (var Watchdog = new WatchdogTimer(Timeout))
            {

                string AllClientOutput = "";
                ProcessResult ClientProcess = null;
                FileStream ClientProcessLog = null;
                StreamReader ClientLogReader = null;
                Log("Starting Client for unattended test....");
                ClientProcess = Run(ClientApp, ClientCmdLine + " -FORCELOGFLUSH", null, ClientRunFlags | ERunOptions.NoWaitForExit);
                while (!FileExists(ClientLogFile) && !ClientProcess.HasExited)
                {
                    Log("Waiting for client logging process to start...{0}", ClientLogFile);
                    Thread.Sleep(2000);
                }
                if (!ClientProcess.HasExited)
                {
                    Thread.Sleep(2000);
                    Log("Client logging process started...{0}", ClientLogFile);
                    ClientProcessLog = File.Open(ClientLogFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    ClientLogReader = new StreamReader(ClientProcessLog);
                }
                if (ClientProcess.HasExited || ClientLogReader == null)
                {
                    throw new AutomationException("Client exited before we asked it to.");
                }
                bool bKeepReading = true;
                bool WelcomedCorrectly = false;
                while (!ClientProcess.HasExited && bKeepReading)
                {
                    while (!ClientLogReader.EndOfStream && bKeepReading && !ClientProcess.HasExited)
                    {
                        string ClientOutput = ClientLogReader.ReadToEnd();
                        if (!String.IsNullOrEmpty(ClientOutput))
                        {
                            AllClientOutput += ClientOutput;
                            Console.Write(ClientOutput);

                            string LookFor = "Bringing up level for play took";
                            if (Params.RunAutomationTest != "")
                            {
                                LookFor = "Automation Test Succeeded";
                            }
                            else if (Params.RunAutomationTests)
                            {
                                LookFor = "Automation Test Queue Empty";
                            }
                            else if (Params.EditorTest)
                            {
                                LookFor = "Asset discovery search completed in";
                            }

                            if (AllClientOutput.Contains(LookFor))
                            {
                                Log("Client loaded, lets wait 30 seconds...");
                                Thread.Sleep(30000);
                                if (!ClientProcess.HasExited)
                                {
                                    WelcomedCorrectly = true;
                                }
                                Log("Test complete...");
                                bKeepReading = false;
                            }
                            else if (Params.RunAutomationTests)
                            {
                                int FailIndex = AllClientOutput.IndexOf("Automation Test Failed");
                                int ParenIndex = AllClientOutput.LastIndexOf(")");
                                if (FailIndex >= 0 && ParenIndex > FailIndex)
                                {
                                    string Tail = AllClientOutput.Substring(FailIndex);
                                    int CloseParenIndex = Tail.IndexOf(")");
                                    int OpenParenIndex = Tail.IndexOf("(");
                                    string Test = "";
                                    if (OpenParenIndex >= 0 && CloseParenIndex > OpenParenIndex)
                                    {
                                        Test = Tail.Substring(OpenParenIndex + 1, CloseParenIndex - OpenParenIndex - 1);
                                    }
        #if true
                                    Log("Stopping client...");
                                    ClientProcess.StopProcess();
                                    if (IsBuildMachine)
                                    {
                                        Thread.Sleep(70000);
                                    }
        #endif
                                    throw new AutomationException("Automated test failed ({0}).", Test);
                                }
                            }
                        }
                    }
                }
                if (ClientProcess != null && !ClientProcess.HasExited)
                {
                    Log("Stopping client...");
                    ClientProcess.StopProcess();
                }

                // this is hack that prevents a hang
                if (IsBuildMachine)
                {
                    Thread.Sleep(70000);
                }
                if (!WelcomedCorrectly)
                {
                    throw new AutomationException("Client exited before we asked it to.");
                }
            }
        }
        else
        {
            var SC = DeployContextList[0];
            ProcessResult ClientProcess = SC.StageTargetPlatform.RunClient(ClientRunFlags, ClientApp, ClientCmdLine, Params);
            if (ClientProcess != null)
            {
                // If the client runs without StdOut redirect we're going to read the log output directly from log file on
                // a separate thread.
                if ((ClientRunFlags & ERunOptions.NoStdOutRedirect) == ERunOptions.NoStdOutRedirect)
                {
                    ClientLogReaderThread = new System.Threading.Thread(ClientLogReaderProc);
                    ClientLogReaderThread.Start(new object[] { ClientLogFile, ClientProcess });
                }

                do
                {
                    Thread.Sleep(100);
                }
                while (ClientProcess.HasExited == false);
            }
        }
    }