예제 #1
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;
                IProcessResult ClientProcess     = null;
                FileStream     ClientProcessLog  = null;
                StreamReader   ClientLogReader   = null;
                Log("Starting Client for unattended test....");
                ClientProcess = Run(ClientApp, ClientCmdLine + " -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);
                                    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)
                    {
                        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];
            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);
                }
            }
        }
    }
예제 #2
0
    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)
                {
                    Log("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")))
                                {
                                    Log("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++)
                                        {
                                            Log("Starting Extra Client....");
                                            OtherClients.Add(Run(ClientApp, ClientCmdLine, 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);
                                    }
                                }
                                else if (ClientProcess == null && !ServerProcess.HasExited)
                                {
                                    Log("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)
                                            {
                                                Log("Welcomed by server or client loaded, lets wait ten minutes...");
                                                Thread.Sleep(60000 * 10);
                                            }
                                            else
                                            {
                                                Log("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")))
                    {
                        Log("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++)
                            {
                                Log("Starting Extra Client....");
                                IProcessResult NewClient = SC.StageTargetPlatform.RunClient(ClientRunFlags | ERunOptions.NoWaitForExit, ClientApp, ClientCmdLine, Params);
                                OtherClients.Add(NewClient);
                            }
                        }
                    }
                }
                else if (ClientProcess == null && !ServerProcess.HasExited)
                {
                    Log("Waiting for server to start....");
                    Thread.Sleep(2000);
                }

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

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

                return(bKeepReading);                // Keep reading
            });
        }
        Log("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.");
            }
        }
    }
예제 #3
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);
                }
            }
        }
    }