예제 #1
0
        /// <summary>
        /// Returns a hash that represents the results of a role. Should be 0 if no fatal errors or ensures
        /// </summary>
        /// <param name="InArtifacts"></param>
        /// <returns></returns>
        protected virtual string GetRoleResultHash(UnrealRoleArtifacts InArtifacts)
        {
            const int MaxCallstackLines = 10;

            UnrealLogParser.LogSummary LogSummary = InArtifacts.LogSummary;

            string TotalString = "";

            //Func<int, string> ComputeHash = (string Str) => { return Hasher.ComputeHash(Encoding.UTF8.GetBytes(Str)); };

            if (LogSummary.FatalError != null)
            {
                TotalString += string.Join("\n", InArtifacts.LogSummary.FatalError.Callstack.Take(MaxCallstackLines));
                TotalString += "\n";
            }

            foreach (var Ensure in LogSummary.Ensures)
            {
                TotalString += string.Join("\n", Ensure.Callstack.Take(MaxCallstackLines));
                TotalString += "\n";
            }

            string Hash = Hasher.ComputeHash(TotalString);

            return(Hash);
        }
예제 #2
0
        /// <summary>
        /// Parses the output of an application to try and determine a failure cause (if one exists). Returns
        /// 0 for graceful shutdown
        /// </summary>
        /// <param name="Prefix"></param>
        /// <param name="App"></param>
        /// <returns></returns>
        protected virtual int GetRoleSummary(UnrealRoleArtifacts InArtifacts, out string Summary)
        {
            const int MaxLogLines       = 10;
            const int MaxCallstackLines = 20;

            UnrealLogParser.LogSummary LogSummary = InArtifacts.LogSummary;

            string ExitReason = "Unknown";
            int    ExitCode   = GetExitCodeAndReason(InArtifacts, out ExitReason);

            MarkdownBuilder MB = new MarkdownBuilder();

            MB.H3(string.Format("Role: {0} ({1} {2})", InArtifacts.SessionRole.RoleType, InArtifacts.SessionRole.Platform, InArtifacts.SessionRole.Configuration));

            if (ExitCode != 0)
            {
                MB.H4(string.Format("Result: Abnormal Exit: {0}", ExitReason));
            }
            else
            {
                MB.H4(string.Format("Result: {0}", ExitReason));
            }

            int FatalErrors = LogSummary.FatalError != null ? 1 : 0;

            if (LogSummary.FatalError != null)
            {
                MB.H4(string.Format("Fatal Error: {0}", LogSummary.FatalError.Message));
                MB.UnorderedList(InArtifacts.LogSummary.FatalError.Callstack.Take(MaxCallstackLines));

                if (InArtifacts.LogSummary.FatalError.Callstack.Count() > MaxCallstackLines)
                {
                    MB.Paragraph("See log for full callstack");
                }
            }

            if (LogSummary.Ensures.Count() > 0)
            {
                foreach (var Ensure in LogSummary.Ensures)
                {
                    MB.H4(string.Format("Ensure: {0}", Ensure.Message));
                    MB.UnorderedList(Ensure.Callstack.Take(MaxCallstackLines));

                    if (Ensure.Callstack.Count() > MaxCallstackLines)
                    {
                        MB.Paragraph("See log for full callstack");
                    }
                }
            }

            MB.Paragraph(string.Format("FatalErrors: {0}, Ensures: {1}, Errors: {2}, Warnings: {3}",
                                       FatalErrors, LogSummary.Ensures.Count(), LogSummary.Errors.Count(), LogSummary.Warnings.Count()));

            if (GetConfiguration().ShowErrorsInSummary&& InArtifacts.LogSummary.Errors.Count() > 0)
            {
                MB.H4("Errors");
                MB.UnorderedList(LogSummary.Errors.Take(MaxLogLines));

                if (LogSummary.Errors.Count() > MaxLogLines)
                {
                    MB.Paragraph(string.Format("(First {0} of {1} errors)", MaxLogLines, LogSummary.Errors.Count()));
                }
            }

            if (GetConfiguration().ShowWarningsInSummary&& InArtifacts.LogSummary.Warnings.Count() > 0)
            {
                MB.H4("Warnings");
                MB.UnorderedList(LogSummary.Warnings.Take(MaxLogLines));

                if (LogSummary.Warnings.Count() > MaxLogLines)
                {
                    MB.Paragraph(string.Format("(First {0} of {1} warnings)", MaxLogLines, LogSummary.Warnings.Count()));
                }
            }

            MB.H4("Artifacts");
            MB.Paragraph(string.Format("Log: {0}", InArtifacts.LogPath));
            MB.Paragraph(string.Format("Commandline: {0}", InArtifacts.AppInstance.CommandLine));
            MB.Paragraph(InArtifacts.ArtifactPath);

            Summary = MB.ToString();
            return(ExitCode);
        }
예제 #3
0
        /// <summary>
        /// Parses the provided artifacts to determine the cause of an exit and whether it was abnormal
        /// </summary>
        /// <param name="InArtifacts"></param>
        /// <param name="Reason"></param>
        /// <param name="WasAbnormal"></param>
        /// <returns></returns>
        protected virtual int GetExitCodeAndReason(UnrealRoleArtifacts InArtifacts, out string ExitReason)
        {
            UnrealLogParser.LogSummary LogSummary = InArtifacts.LogSummary;

            // Assume failure!
            int ExitCode = -1;

            ExitReason = "Unknown";

            if (LogSummary.FatalError != null)
            {
                ExitReason = "Process encountered fatal error";
            }
            else if (LogSummary.Ensures.Count() > 0 && CachedConfig.FailOnEnsures)
            {
                ExitReason = string.Format("Process encountered {0} Ensures", LogSummary.Ensures.Count());
            }
            else if (InArtifacts.AppInstance.WasKilled)
            {
                ExitReason = "Process was killed";
            }
            else if (LogSummary.HasTestExitCode)
            {
                if (LogSummary.TestExitCode == 0)
                {
                    ExitReason = "Process exited with code 0";
                }
                else
                {
                    ExitReason = string.Format("Process exited with error code {0}", LogSummary.TestExitCode);
                }

                ExitCode = LogSummary.TestExitCode;
            }
            else if (LogSummary.RequestedExit)
            {
                ExitReason = string.Format("Process requested exit with no fatal errors");
                ExitCode   = 0;
            }
            else
            {
                // ok, process appears to have exited for no good reason so try to divine a result...
                if (LogSummary.HasTestExitCode == false &&
                    InArtifacts.SessionRole.CommandLine.ToLower().Contains("-gauntlet"))
                {
                    Log.Verbose("Role {0} had 0 exit code but used Gauntlet and no TestExitCode was found. Assuming failure", InArtifacts.SessionRole.RoleType);
                    ExitCode   = -1;
                    ExitReason = "No test result from Gauntlet controller";
                }
            }

            // Normal exits from server are not ok if we had clients running!
            if (ExitCode == 0 && InArtifacts.SessionRole.RoleType.IsServer())
            {
                bool ClientsKilled = SessionArtifacts.Any(A => A.AppInstance.WasKilled && A.SessionRole.RoleType.IsClient());

                if (ClientsKilled)
                {
                    ExitCode   = -1;
                    ExitReason = "Server exited while clients were running";
                }
            }

            if (ExitCode == -1 && string.IsNullOrEmpty(ExitReason))
            {
                ExitReason = "Process exited with no indication of success";
            }

            return(ExitCode);
        }