示例#1
0
 public void MarkTestRailsTestCase(bool isSuccess, params int[] testCaseIds)
 {
     if (!IsFailing)
     {
         AutomationReport.MarkTestRailsTestCase(isSuccess ? "Passed" : "Failed", testCaseIds);
     }
 }
示例#2
0
		/// <summary>
		/// Return list of most recent logs. Stores a maximum of 25 most recent logs.
		/// </summary>
		/// <returns>The latest logs.</returns>
		/// <param name="numberOfMostRecentLogsToReturn">Number of most recent logs to return.</param>
		public static string ReturnLatestLogs(int numberOfMostRecentLogsToReturn) {
			
			List<Log> returnList = new List<Log>();
			if(Logs.Count <= numberOfMostRecentLogsToReturn) {
				
				returnList = Logs;

			} else {
				
				for(int i = 1; i <= numberOfMostRecentLogsToReturn; i++) {
					
					if(i < 0) {
						
						break;

					}

					Log thisLog = Logs[Logs.Count - i];
					if(!string.IsNullOrEmpty(thisLog.message)) {
						
						returnList.Add(thisLog);

					} else {
						
						Logs.RemoveAt(Logs.Count - i);
						i--;

					}

				}

			}
			StringBuilder logString = new StringBuilder();
			for(int i = 0; i < returnList.Count; i++) {
				
				logString.AppendLine(string.Format("(LOG ENTRY) MESSAGE: {0} ** STACKTRACE: {1} ** TYPE: {2}", returnList[i].message, returnList[i].stackTrace, returnList[i].type.ToString()));

			}
			if(logString.Length > MAX_LOG_RETURN_LENGTH) {
				
				return AutomationReport.EncodeCharactersForJson(logString.ToString().Substring(0, MAX_LOG_RETURN_LENGTH)).Replace(AutomationMaster.DELIMITER.ToString(), "%7C"); //Encode AutomationMaster.DELIMITER character or errors will occur in data parsing in server.

			} else {
				
				return AutomationReport.EncodeCharactersForJson(logString.ToString()).Replace(AutomationMaster.DELIMITER.ToString(), "%7C"); //Encode AutomationMaster.DELIMITER character or errors will occur in data parsing in server.

			}

		}
示例#3
0
            public void Add(AutoConsole.Log error)
            {
                GameException ex = new GameException();

                ex.ScreenshotName = string.Format("EXCEPTION_{0}", Reported.Count);
                AutomationMaster.StaticSelfComponent.TakeScreenshotAsync(false, ex.ScreenshotName);
                ex.TimeStamp          = System.DateTime.UtcNow.ToLongDateString();
                ex.TestExecutionTime  = System.DateTime.UtcNow.Subtract(AutomationMaster.CurrentTestContext.StartTime).TotalSeconds.ToString();
                ex.CurrentRunningTest = AutomationMaster.CurrentTestContext.TestName;
                ex.Error        = AutomationReport.EncodeCharactersForJson(error.message);
                ex.ErrorDetails = AutomationReport.EncodeCharactersForJson(error.stackTrace);
                ex.Occurrences  = 1;
                for (int r = 0; r < Reported.Count; r++)
                {
                    if (Reported[r].Error == ex.Error && Reported[r].ErrorDetails == ex.ErrorDetails)
                    {
                        Reported[r].Occurrences++;
                        return;
                    }
                }
                _reported.Add(ex);
            }
示例#4
0
            public void Add(AutoConsole.Log error)
            {
                GameException ex = new GameException();

                ex.ScreenshotName     = string.Format("EXCEPTION_{0}", Reported.Count);
                ex.TimeStamp          = System.DateTime.UtcNow.ToLongDateString();
                ex.TestExecutionTime  = System.DateTime.UtcNow.Subtract(AutomationMaster.CurrentTestContext.StartTime).TotalSeconds.ToString();
                ex.CurrentRunningTest = AutomationMaster.CurrentTestContext.TestName;
                ex.Error        = AutomationReport.EncodeCharactersForJson(error.message).Replace(AutomationMaster.DELIMITER.ToString(), "%7C");          //Encode AutomationMaster.DELIMITER character or errors will occur in data parsing in server.
                ex.ErrorDetails = AutomationReport.EncodeCharactersForJson(error.stackTrace).Replace(AutomationMaster.DELIMITER.ToString(), "%7C");       //Encode AutomationMaster.DELIMITER character or errors will occur in data parsing in server.
                ex.Occurrences  = 1;
                for (int r = 0; r < Reported.Count; r++)
                {
                    if (Reported[r].Error == ex.Error && Reported[r].ErrorDetails == ex.ErrorDetails)
                    {
                        Reported[r].Occurrences++;
                        return;
                    }
                }
                AutomationMaster.StaticSelfComponent.TakeScreenshotAsync(false, ex.ScreenshotName);                 //Only take a screenshot if it is not a duplicate. Spammed errors would lead to spammed screenshots.
                _reported.Add(ex);
            }
示例#5
0
        public override void Render()
        {
            _newBuddyName = AutomationReport.GetMostRecentBuddy();             //Display last-used Buddy by default.

            //Tell test runner to not/ignore BuddySystem tests in the current test run.
            if (Application.isPlaying)
            {
                if (_ignoreBuddyTests != AutomationMaster.IgnoreAllBuddyTests)
                {
                    if (!AutomationMaster.LockIgnoreBuddyTestsFlag)
                    {
                        AutomationMaster.IgnoreAllBuddyTests = _ignoreBuddyTests;
                    }
                }
            }


            GUIStyle buddyWindowLabel = new GUIStyle(GUI.skin.label);

            buddyWindowLabel.fontStyle = FontStyle.Bold;
            buddyWindowLabel.padding   = Nexus.BaseRectOffset;
            GUIStyle sl = new GUIStyle(GUI.skin.label);

            sl.padding = new RectOffset(15, 0, 0, 0);

            EditorGUILayout.Space();
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("- Set Buddy Info -", buddyWindowLabel);
            EditorGUILayout.Space();
            EditorGUILayout.Space();

            sl.normal.textColor = Swat.WindowDefaultTextColor;

            if (_isBuddySet && !string.IsNullOrEmpty(BuddyHandler.BuddyName))
            {
                EditorGUILayout.LabelField(string.Format("Current Buddy is {0}", BuddyHandler.BuddyName), sl);
                EditorGUILayout.Space();
            }

            sl.fixedWidth = 125;

            if (!_buddyHistory.Any() && DateTime.Now.Subtract(_lastBuddyRetrieval).TotalSeconds > _redrawRateSeconds)
            {
                _buddyHistory       = AutomationReport.GetBuddyHistory();
                _lastBuddyRetrieval = DateTime.Now;
            }

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Ignore Buddy Tests? ", sl);
            _ignoreBuddyTests = EditorGUILayout.Toggle(_ignoreBuddyTests);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();

            if (_buddyHistory.Any())
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Use Known Buddy? ", sl);
                _chooseBuddyFromHistory = EditorGUILayout.Toggle(_chooseBuddyFromHistory);
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Space();
            }

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Is Primary? ", sl);
            _isPrimaryBuddy = EditorGUILayout.Toggle(_isPrimaryBuddy);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();

            if (!_chooseBuddyFromHistory || !_buddyHistory.Any())
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Buddy Name: ", sl);
                _newBuddyName = EditorGUILayout.TextField(_newBuddyName);
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Space();
            }

            GUIStyle buddies = new GUIStyle(EditorStyles.popup);

            buddies.margin = new RectOffset(15, 0, 0, 0);

            if (_chooseBuddyFromHistory)
            {
                if (_buddyHistory.Any())
                {
                    buddies.fixedHeight = 15;
                    _buddySelection     = EditorGUILayout.Popup(_buddySelection, _buddyHistory.ToArray(), buddies, new GUILayoutOption[] { GUILayout.Height(50), GUILayout.MaxWidth(250) });
                }
            }

            buddies             = new GUIStyle(GUI.skin.button);
            buddies.margin      = new RectOffset(15, 0, 0, 0);
            buddies.fixedHeight = 25;

            if (GUILayout.Button("Set Buddy", buddies, new GUILayoutOption[] { GUILayout.Width(75), GUILayout.Height(25) }))
            {
                _isBuddySet = true;
                AutomationMaster.Arbiter.SendCommunication(string.Format("{{\"manual_set_buddy_{0}\":\"{1}\"}}", _isPrimaryBuddy ? "primary" : "secondary", _chooseBuddyFromHistory && _buddyHistory.Any() ? _buddyHistory[_buddySelection] : _newBuddyName));
            }

            EditorGUILayout.Space();
        }
示例#6
0
 public void AddTestCaseAssertionOnFailure(string newAssertion)
 {
     //Add test case assertion before the last failed assertion.
     Assertions.AddAt(Assertions.Count - 2, AutomationReport.EncodeCharactersForJson(newAssertion));
 }
示例#7
0
 public void AddAssertion(string newAssertion)
 {
     Assertions.Add(AutomationReport.EncodeCharactersForJson(newAssertion));
 }
示例#8
0
        protected IEnumerator Unifier(bool b, bool inverse, string message, FailureContext newFailureContext, params int[] testRailsId)
        {
            //If test was already marked as a failure, and test has flag indicating that it should continue despite failure, ignore.
            if (!AutomationMaster.CurrentTestContext.IsSuccess || ((AutomationMaster.TryContinueOnFailure || MideExecution_MarkTestToTryContinueAfterFail) && IsFailing))
            {
                UnitTestStepFailure = isSoft = isTry = quiet = false;                 //Reset the UnitTestStepFailure, Soft, Try, and Quiet flags.
                yield break;
            }

            //Automatically label this assertion as quiet if the previous assertion is identical to this one.
            quiet = quiet ? true : AutomationMaster.CurrentTestContext.Assertions.Last() == message;

            _failureContext = newFailureContext;
            if ((!b && inverse) || (b && !inverse))
            {
                if (isTry && !quiet)
                {
                    AutomationMaster.CurrentTestContext.AddAssertion(string.Format("**TRY_SUCCESS**{0}", message));
                    UnitTestStepFailure = isSoft = isTry = quiet = false;                     //Reset the UnitTestStepFailure, Soft, Try, and Quiet flags.
                    yield break;
                }

                ConcurrentFailures = 0;
                AutomationMaster.CurrentTestContext.IsSuccess = true;
                if (!string.IsNullOrEmpty(message) && !isTry && !quiet)
                {
                    AutomationMaster.CurrentTestContext.AddAssertion(message);
                }
            }
            else
            {
                //TODO: UnitTestStepFailure - Determine if an assertion has failed within the context of a TestObject "steps" method. If so, set this to true. Used to disabled certain TestRunner reactive logic, such as screenshots.

                if (isTry)
                {
                    if (!quiet)
                    {
                        AutomationMaster.CurrentTestContext.AddAssertion(string.Format("**TRY_FAIL**{0}", message));
                    }
                    UnitTestStepFailure = isSoft = isTry = quiet = false;                     //Reset the UnitTestStepFailure, Soft, Try, and Quiet flags.
                    yield break;
                }

                IsFailing = true;
                bool recordLogDetails = newFailureContext != FailureContext.Skipped;

                SetReflectedTestData();
                string recentLogs = AutomationReport.EncodeCharactersForJson(AutoConsole.ReturnLatestLogs(5));

                if (newFailureContext == FailureContext.Skipped)
                {
                    AutomationMaster.TestRunContext.Skipped.Add(AutomationMaster.CurrentTestContext.TestName);
                }
                else
                {
                    AutomationMaster.TestRunContext.Failed.Add(AutomationMaster.CurrentTestContext.TestName, new string[] {
                        message,
                        recentLogs.ToString(),
                        lineNumber
                    });
                }

                AutomationMaster.CurrentTestContext.IsSuccess = false;
                AutomationMaster.CurrentTestContext.AddAssertion(message);
                AutomationMaster.CurrentTestContext.ErrorDetails += string.Format("Error Message [{0}] : Test Line [{1}] : Debug Logs [{2}] ", message, string.Format("Line [{0}] Call [{1}]", lineNumber, lineCall), (recordLogDetails ? recentLogs : string.Format("#SKIPPED#{0}", message)));
                AutomationMaster.CurrentTestContext.ErrorDetails += string.Format(" FULL STACK: [{0}]", Environment.StackTrace.Replace(" at", string.Format(" {0} at", AutomationMaster.NEW_LINE_INDICATOR)));
                if (failureContext != FailureContext.Skipped)
                {
                    //Take screenshot if a failure is not a "Skip" failure (In which case a test does not run at all, and there is no value in taking a screenshot as the current screen has no relevance to the reason it failed).
                    yield return(StartCoroutine(AutomationMaster.StaticSelfComponent.TakeScreenshot()));

                    screenshotRequestTime = DateTime.UtcNow;
                }

                //Handle errors occurring outside of the context of the current test's execution. Only certain contexts require additional handling over what is offered by default.
                switch (AutomationMaster.ExecutionContext)
                {
                case AutomationMaster.CurrentExecutionContext.SetUpClass:
                    AutomationMaster.AutoSkips.Add(new KeyValuePair <string[], string>(new string[] { "class", AutomationMaster.CurrentTestContext.ClassName }, string.Format("FAILURE OCCURRED IN SETUPCLASS:", message)));
                    break;

                case AutomationMaster.CurrentExecutionContext.SetUp:
                    AutomationMaster.AutoSkips.Add(new KeyValuePair <string[], string>(new string[] { "test", AutomationMaster.CurrentTestContext.TestName }, string.Format("FAILURE OCCURRED IN SETUP:", message)));
                    break;

                case AutomationMaster.CurrentExecutionContext.TearDownClass:
                    yield return(StartCoroutine(Q.assert.Warn(string.Format("A failure occurred in the TearDownClass logic for  the test \"{0}.{1}\". This fails the last-run test, and may cause other undesirable behavior for downstream test execution.", AutomationMaster.CurrentTestContext.ClassName, AutomationMaster.CurrentTestContext.TestName))));

                    //Will automatically handle the failure of this test.
                    break;

                case AutomationMaster.CurrentExecutionContext.TearDown:
                //Will automatically handle the failure of this test.
                case AutomationMaster.CurrentExecutionContext.Test:
                //Will automatically handle the failure of this test.
                default:
                    break;
                }

                if ((AutomationMaster.TryContinueOnFailure || MideExecution_MarkTestToTryContinueAfterFail) && ConcurrentFailures > 5)
                {
                    AutomationMaster.OverrideContinueOnFailureAfterTooManyConcurrentFailures = true;
                }

                                #if UNITY_EDITOR
                AutomationMaster.PauseEditorOnFailure();
                                #endif

                //Any FailureContext beyond TestMethod will not have an instantiated test method.
                if (!AutomationMaster.TryContinueOnFailure)
                {
                    if ((!isSoft && AutomationMaster.OverrideContinueOnFailureAfterTooManyConcurrentFailures) || (!MideExecution_MarkTestToTryContinueAfterFail && (_failureContext == FailureContext.TestMethod || _failureContext == FailureContext.Default) && failureContext != FailureContext.Skipped))
                    {
                        try {
                            AutomationMaster.CurrentTestMethod.Stop();                //Kill current test, only if the currently queued test has been initialized.
                        } catch { }
                        yield return(new WaitForEndOfFrame());                        //Allow all Coroutines to be stopped before returning control. In reality, the coroutine calling this will be stopped, so control will never be returned anyway.
                    }
                }

                if (!isSoft && (AutomationMaster.TryContinueOnFailure || MideExecution_MarkTestToTryContinueAfterFail))
                {
                    ConcurrentFailures++;
                }
            }

            if (testRailsId.Length > 0)
            {
                AutomationReport.MarkTestRailsTestCase(AutomationMaster.CurrentTestContext.IsSuccess ? "Passed" : "Failed", testRailsId);
            }

            AutoConsole.PostMessage(string.Format("Assert [{0}] |{1}| {2}", AutomationMaster.CurrentTestContext.TestName, AutomationMaster.CurrentTestContext.IsSuccess ? "Success" : "Failure", message), MessageLevel.Verbose, ConsoleMessageType.TestRunnerUpdate);
            UnitTestStepFailure = isSoft = isTry = quiet = false;             //Reset the UnitTestStepFailure, Soft, Try, and Quiet flags.
            yield return(null);
        }
示例#9
0
        /// <summary>
        /// While this client is in the Primary Buddy role, run Action tests, and await completion of Secondary Buddy's Reaction tests.
        /// </summary>
        /// <returns>The buddy test run.</returns>
        public IEnumerator PrimaryBuddyTestRun()
        {
            for (int b = 0; b < _buddies.Count; b++)
            {
                //Skip this method if it has already been handled.
                if (HandledBuddyTests.Contains(Buddies[b].Key.Key))
                {
                    continue;
                }

                SecondaryReactionsStarted = false; //Reset for next reaction.

                timeout = 180;
                time    = 0;

                //Retrieve any BuddyCommands for this Action test, and send them to Buddy for execution.
                BuddyCommand command = _buddies[b].Key.Value.GetCustomAttributes(typeof(BuddyCommand), false).ToList().First() as BuddyCommand;
                if (command != null)
                {
                    SendBuddyCommunication("buddy_primary_pretest_commands", string.Join("|", command.Commands.ToArray()));
                    BuddyProcessingCommands = true;
                    while (BuddyProcessingCommands && time <= timeout)
                    {
                        if (BuddyCommandExecutionFailure)
                        {
                            break;
                        }
                        //Every 50 seconds, report still waiting.
                        if (time % 50 == 0)
                        {
                            AutoConsole.PostMessage(string.Format("Primary waiting for Secondary to complete pretest commands ({0}) seconds", time.ToString()), MessageLevel.Abridged);
                        }

                        yield return(StartCoroutine(Q.driver.WaitRealTime(5)));

                        time += 5;
                    }
                }

                string errorMessage = string.Empty;
                HandledBuddyTests.Add(_buddies[b].Key.Key);
                if (!AutomationMaster.Methods.KeyValListContainsKey(Buddies[b].Key.Key))
                {
                    AutomationMaster.Methods.Add(new KeyValuePair <string, MethodInfo>(Buddies[b].Key.Key, Buddies[b].Key.Value));
                }

                if (!BuddyCommandExecutionFailure && time <= timeout)
                {
                    //Launch Action test.
                    yield return(StartCoroutine(Master.LaunchSingleTest(Buddies[b].Key, AutomationMaster.Methods.Count - 1)));
                }
                else
                {
                    AutomationMaster.CurrentTestContext.TestInitialize(_buddies[b].Key.Value);
                    if (BuddyCommandExecutionFailure)
                    {
                        errorMessage = string.Format("The Secondary Buddy of this client failed to successfully handle the command(s) {0} required by this Action test. Commands: {1}.", BuddyCommandFailure, string.Join("|", command.Commands.ToArray()));
                    }
                    else
                    {
                        errorMessage = "Timout occurred waiting for primary buddy to complete its pretest commands.";
                    }
                    yield return(StartCoroutine(Q.assert.Fail(errorMessage, FailureContext.TestMethod)));

                    AutomationReport.AddToReport(false, 0, true); //Save results to test run's XML file.
                    Master.ReportOnTest();
                }
                ResendAllInfoForBuddyTests();
                yield return(StartCoroutine(Q.driver.WaitRealTime(2f)));

                bool actionSuccessful = AutomationMaster.CurrentTestContext.IsSuccess;
                if (actionSuccessful)
                {
                    SendBuddyCommunication("buddy_primary_test_complete", _buddies[b].Key.Value.Name);
                }
                else
                {
                    SendBuddyCommunication("buddy_primary_test_failed", _buddies[b].Key.Value.Name);
                }

                //When the buddy has completed all reaction tests, we can then move on to the next.
                timeout = 300;
                time    = 0;
                _waitingForBuddyToCompleteReactionTests = true;
                int resendCount = 4;
                while (_waitingForBuddyToCompleteReactionTests && time <= timeout)
                {
                    //Check if buddy has declared that it is running its secondary tests. If not, resend the command once.
                    if (resendCount > 0 && time > 10 && !SecondaryReactionsStarted)
                    {
                        resendCount--;
                        if (actionSuccessful)
                        {
                            SendBuddyCommunication("buddy_primary_test_complete", _buddies[b].Key.Value.Name);
                        }
                        else
                        {
                            SendBuddyCommunication("buddy_primary_test_failed", _buddies[b].Key.Value.Name);
                        }
                    }

                    //Every 50 seconds, report still waiting.
                    if (time % 50 == 0)
                    {
                        AutoConsole.PostMessage(string.Format("Primary waiting for Secondary ({0}) seconds", time.ToString()), MessageLevel.Abridged);
                    }

                    yield return(StartCoroutine(Q.driver.WaitRealTime(5f)));

                    time += 5;
                }

                //If we time out, stop the run and break out of execution.
                _isBuddySystemFailure = time >= timeout;
                if (_isBuddySystemFailure)
                {
                    _failureReason = errorMessage;
                    AutoConsole.PostMessage(_failureReason, MessageLevel.Abridged);
                    break;
                }

                //Run all CounterReaction tests for this Action.
                List <KeyValuePair <string, MethodInfo> > counterReactions = _buddies.FindAll(x => x.Key.Value.Name == _buddies[b].Key.Value.Name).First().Value.FindAll(x => {
                    BuddySystem bs = (BuddySystem)Attribute.GetCustomAttribute(x.Value, typeof(BuddySystem));
                    return(bs.buddy == Buddy.CounterReaction);
                });

                for (int c = 0; c < counterReactions.Count; c++)
                {
                    HandledBuddyTests.Add(counterReactions[c].Key);
                    if (!AutomationMaster.Methods.KeyValListContainsKey(counterReactions[c].Key))
                    {
                        AutomationMaster.Methods.Add(new KeyValuePair <string, MethodInfo>(counterReactions[c].Key, counterReactions[c].Value));
                    }
                    yield return(StartCoroutine(Master.LaunchSingleTest(counterReactions[c], AutomationMaster.Methods.Count - 1, actionSuccessful ? TestStatus.Pass : TestStatus.Fail)));
                }
            }

            SendBuddyCommunication("buddy_primary_complete_action_tests", "0");

            yield return(null);
        }
示例#10
0
        public IEnumerator RunBuddySystemTests()
        {
            //If a relationship has not yet been established, then cancel BuddySystem execution. This is not used if IgnoreAllBuddyTests flag set.
            BuddySystemHandlingStarted = true;
            _isBuddySystemFailure      = string.IsNullOrEmpty(BuddyName);

            if (!AutomationMaster.IgnoreAllBuddyTests)
            {
                //If allowed, and Buddy is not yet set, then set Buddy to last-used Buddy.
            #if UNITY_EDITOR
                if (AutomationMaster.ConfigReader.GetBool("EDITOR_DEFAULT_BUDDY_TO_LAST"))
                {
                    string mostRecentBuddy = AutomationReport.GetMostRecentBuddy();
                    if (!string.IsNullOrEmpty(mostRecentBuddy))
                    {
                        BuddyName = mostRecentBuddy;
                    }
                }
            #endif

                if (_isBuddySystemFailure)
                {
                    _failureReason = "Buddy was not set before BuddySystem test execution started.";
                }

                if (!_isBuddySystemFailure)
                {
                    AutoConsole.PostMessage("Establishing Connection With Buddy", MessageLevel.Abridged);
                    do
                    {
                        if (RoleGridLock)
                        {
                            _isBuddySystemFailure = true;
                            _failureReason        = "This client and the associated Buddy client share the same role (primary/secondary). One must be a primary Buddy, and the other a secondary Buddy.";
                            break;
                        }

                        SendBuddyCommunication("buddy_ready_for_tests", IsPrimary ? "primary" : "secondary");
                        yield return(StartCoroutine(Q.driver.WaitRealTime(5)));

                        time += 5;
                    } while((!_isBuddyReadyForBuddyTests || !HasBuddyAcknowledgedOurReadiness) && time <= timeout);
                    AutoConsole.PostMessage(time > timeout ? "Buddy Connection Failure": "Buddy Connection Established", MessageLevel.Abridged);

                    if (IsPrimary && !BuddyTestRequiredDetails.Any())
                    {
                        //If this client is the Primary, and has not yet recieved its required information from the Secondary, request it.
                        for (int limit = 30; limit >= 0; limit--)
                        {
                            if (!BuddyTestRequiredDetails.Any())
                            {
                                break;
                            }

                            SendBuddyCommunication("buddy_requesting_required_details", "0");
                            yield return(StartCoroutine(Q.driver.WaitRealTime(1)));
                        }
                    }

                    if (time >= timeout || (IsPrimary && !BuddyTestRequiredDetails.Any()))
                    {
                        _isBuddySystemFailure = true;
                        _failureReason        = "Timed out waiting for Buddy to be ready for multi-client testing.";
                    }

                    if (!_isBuddySystemFailure)
                    {
                        SendBasicBuddyDetails();

                        if (_isPrimary)
                        {
                            yield return(StartCoroutine(PrimaryBuddyTestRun()));

                            if (!_isBuddySystemFailure)
                            {
                                ResetBuddySystemValues();
                                yield return(StartCoroutine(Q.driver.WaitRealTime(5)));

                                SendBuddyCommunication("buddy_switching_roles", "0");

                                timeout = 300;
                                time    = 0;
                                while (!BuddyHasSuccessfullySwitchRoles && time <= timeout)
                                {
                                    yield return(StartCoroutine(Q.driver.WaitRealTime(5)));

                                    SendBuddyCommunication("buddy_primary_complete_action_tests", "0");
                                    time += 5;
                                }
                                if (time > timeout)
                                {
                                    _isBuddySystemFailure = true;
                                    _failureReason        = "Timed out waiting for Buddy to switch roles from Secondary to Primary.";
                                }
                                else
                                {
                                    AutoConsole.PostMessage("Switching Roles With Buddy", MessageLevel.Abridged);
                                    yield return(StartCoroutine(SecondaryBuddyTestRun()));
                                }
                            }
                        }
                        else
                        {
                            yield return(StartCoroutine(SecondaryBuddyTestRun()));

                            if (!_isBuddySystemFailure)
                            {
                                ResetBuddySystemValues();
                                yield return(StartCoroutine(Q.driver.WaitRealTime(5)));

                                SendBuddyCommunication("buddy_switching_roles", "0");

                                timeout = 300;
                                time    = 0;
                                while (!BuddyHasSuccessfullySwitchRoles && time <= timeout)
                                {
                                    yield return(StartCoroutine(Q.driver.WaitRealTime(5)));

                                    SendBuddyCommunication("buddy_secondary_tests_complete", "0");
                                    time += 5;
                                }
                                if (time > timeout)
                                {
                                    _isBuddySystemFailure = true;
                                    _failureReason        = "Timed out waiting for Buddy to switch roles from Primary to Secondary.";
                                }
                                else
                                {
                                    AutoConsole.PostMessage("Switching Roles With Buddy", MessageLevel.Abridged);
                                    yield return(StartCoroutine(PrimaryBuddyTestRun()));
                                }
                            }
                        }

                        SendBuddyCommunication("buddy_tearing_down", "0");
                        yield return(StartCoroutine(Q.driver.WaitRealTime(5)));

                        SendBuddyCommunication("buddy_tearing_down", "0");
                    }
                }
            }

            if (_isBuddySystemFailure || AutomationMaster.IgnoreAllBuddyTests)
            {
                //Fail all remaining tests.
                string errorMessage = string.Format("BuddySystem failure. Reason: {0} Skipping BuddySystem tests.", _failureReason);
                AutoConsole.PostMessage(errorMessage, MessageLevel.Abridged);
                for (int f = 0; f < _buddies.Count; f++)
                {
                    if (!HandledBuddyTests.Contains(_buddies[f].Key.Key))
                    {
                        AutomationMaster.CurrentTestContext = new TestContext();
                        if (!AutomationMaster.Methods.KeyValListContainsKey(_buddies[f].Key.Key))
                        {
                            AutomationMaster.Methods.Add(new KeyValuePair <string, MethodInfo>(_buddies[f].Key.Key, Buddies[f].Key.Value));
                        }
                    }

                    yield return(StartCoroutine(Master.LaunchSingleTest(_buddies[f].Key, AutomationMaster.Methods.Count - 1, AutomationMaster.IgnoreAllBuddyTests ? TestStatus.Ignore : TestStatus.Fail, errorMessage)));

                    for (int fr = 0; fr < _buddies[f].Value.Count; fr++)
                    {
                        if (HandledBuddyTests.Contains(Buddies[f].Value[fr].Value.Name))
                        {
                            continue;
                        }
                        AutomationMaster.CurrentTestContext = new TestContext();
                        if (!AutomationMaster.Methods.KeyValListContainsKey(_buddies[f].Value[fr].Key))
                        {
                            AutomationMaster.Methods.Add(new KeyValuePair <string, MethodInfo>(_buddies[f].Value[fr].Key, Buddies[f].Value[fr].Value));
                        }
                        yield return(StartCoroutine(Master.LaunchSingleTest(_buddies[f].Value[fr], AutomationMaster.Methods.Count - 1, AutomationMaster.IgnoreAllBuddyTests ? TestStatus.Ignore : TestStatus.Fail, errorMessage)));
                    }
                }
            }

            HandledBuddyTests = new List <string>();
            ResetBuddySystemValues();

            yield return(null);
        }
示例#11
0
        public override void Render()
        {
            GUIStyle horizontal = new GUIStyle();

            horizontal.margin = new RectOffset(10, 11, 0, 0);

            GUIStyle statusColor = new GUIStyle(GUI.skin.label);

            statusColor.margin           = new RectOffset(0, 0, 3, 0);
            statusColor.normal.textColor = AutoConsole.Paused ? Color.red : Nexus.TextGreen;
            statusColor.fixedWidth       = 125;
            statusColor.fontStyle        = FontStyle.Bold;

            GUILayout.Space(15);
            EditorGUILayout.BeginHorizontal(horizontal);             //For "Running" notification and FPS counter.

            if (Application.isPlaying && AutomationMaster.Busy)
            {
                EditorGUILayout.LabelField("Running Test(s)", statusColor);
            }
            else
            {
                AutomationMaster.Busy = false;
                EditorGUILayout.LabelField(string.Empty, statusColor);
            }

            if (Application.isPlaying)
            {
                if (renderPasses == FPS_SAMPLE_RATE && Application.isPlaying)
                {
                    fpsSample    = Math.Round(1 / Time.deltaTime, 0);
                    renderPasses = 0;
                }
                GUIStyle fps = new GUIStyle(GUI.skin.label);
                fps.fontSize         = 26;
                fps.padding          = new RectOffset(0, 0, -8, 0);
                fps.normal.textColor = GetFpsColor(fpsSample);

                GUILayout.FlexibleSpace();
                EditorGUILayout.LabelField(string.Format("FPS   {0}", fpsSample), new GUILayoutOption[] { GUILayout.Width(50) });
                EditorGUILayout.LabelField(string.Format("◈", fpsSample), fps, new GUILayoutOption[] { GUILayout.Width(35) });
                GUILayout.Space(-18);

                renderPasses++;
            }
            EditorGUILayout.EndHorizontal();             //End for "Running" notification and FPS counter.

            GUIStyle scrollStatus = new GUIStyle(GUI.skin.button);

            scrollStatus.margin            = new RectOffset(0, 0, 0, 0);
            scrollStatus.fontStyle         = _autoScroll ? FontStyle.Bold : FontStyle.Normal;
            scrollStatus.normal.background = Swat.ToggleButtonBackgroundSelectedTexture;
            scrollStatus.normal.textColor  = _pubsubMode ? Nexus.TextGreen : Swat.WindowDefaultTextColor;
            EditorGUILayout.Space();

            GUILayout.BeginHorizontal(horizontal);
            EditorGUILayout.LabelField(string.Format("{0}  -  {1}", AutoConsole.Paused ? "Paused" : "Active", AutoConsole.FilterLevel == MessageLevel.Verbose ? "Verbose" : "Abridged"), statusColor);
            EditorGUILayout.Space();
            GUILayout.Space(-100);
            Nexus.Self.Button("Pubsub", "Show received Pubsub messages.",
                              new Nexus.SwatDelegate(delegate() {
                _pubsubMode = !_pubsubMode;
            }), scrollStatus, new GUILayoutOption[] { GUILayout.Width(75), GUILayout.Height(22) });
            GUILayout.Space(0.65f);
            scrollStatus.normal.textColor = _autoScroll ? Nexus.TextGreen : Color.red;
            Nexus.Self.Button("Auto Scroll", "Remove all messages in the console.",
                              new Nexus.SwatDelegate(delegate() {
                _autoScroll = !_autoScroll;
            }), scrollStatus, new GUILayoutOption[] { GUILayout.Width(75), GUILayout.Height(22) });
            GUILayout.EndHorizontal();

            EditorGUILayout.Space();

            GUILayout.BeginHorizontal(horizontal);
            GUIStyle button = new GUIStyle(GUI.skin.button);

            button.margin            = new RectOffset(0, 0, 0, 0);
            button.normal.textColor  = Swat.ToggleButtonTextColor;
            button.normal.background = Swat.ToggleButtonBackgroundTexture;

            Nexus.Self.Button("Clear", "Remove all messages in the console.",
                              new Nexus.SwatDelegate(delegate() {
                FileBroker.SaveUnboundFile(string.Format("{0}{1}{2}/console_before_start.txt", FileBroker.BASE_NON_UNITY_PATH, ConfigReader.GetString("EDITOR_RESOURCE_CONSOLE_LOG_DIRECTORY"), GameMaster.GAME_NAME), string.Empty);
                AutoConsole.messageListDisplayed = new List <AutoConsoleMessage>();
                AutoConsole.messageListQueued    = new List <AutoConsoleMessage>();
                _selectedConsoleMessage          = null;
            }), button, new GUILayoutOption[] { GUILayout.Width(60), GUILayout.Height(22) });

            GUILayout.Space(0.5f);

            Nexus.Self.Button(AutoConsole.Paused ? "Resume" : "Pause", "Pause/Continue rendering of new messages in the console. Messages are still received and stored when paused, and will appear immediately when resuming.",
                              new Nexus.SwatDelegate(delegate() {
                AutoConsole.Paused = !AutoConsole.Paused;
            }), button, new GUILayoutOption[] { GUILayout.Width(60), GUILayout.Height(22) });

            EditorGUILayout.Space();

            Nexus.Self.Button("Verbose", "Post ALL messages from the automation framework in the console.",
                              new Nexus.SwatDelegate(delegate() {
                AutoConsole.FilterLevel = MessageLevel.Verbose;
                if (_autoScroll)
                {
                    _scroll.y = 99999;
                    _scroll.x = 0;
                }
            }), button, new GUILayoutOption[] { GUILayout.Width(75), GUILayout.Height(22) });

            GUILayout.Space(0.65f);

            GUIStyle abridged = new GUIStyle(GUI.skin.button);

            abridged.margin            = new RectOffset(0, 0, 0, 0);
            abridged.normal.textColor  = Swat.ToggleButtonTextColor;
            abridged.normal.background = Swat.ToggleButtonBackgroundTexture;
            Nexus.Self.Button("Abridged", "Post only automation messages marked as high priority in the console.",
                              new Nexus.SwatDelegate(delegate() {
                AutoConsole.FilterLevel = MessageLevel.Abridged;
                if (_autoScroll)
                {
                    _scroll.y = 99999;
                    _scroll.x = 0;
                }
            }), abridged, new GUILayoutOption[] { GUILayout.Width(75), GUILayout.Height(22) });

            GUILayout.EndHorizontal();

            float messageHeight = 15;

            GUIStyle consoleBox = new GUIStyle(GUI.skin.box);

            consoleBox.fixedHeight       = Nexus.Self.position.height - (Application.isPlaying ? 125 : 105);
            consoleBox.fixedWidth        = Nexus.Self.position.width - 20;
            consoleBox.margin            = new RectOffset(10, 0, 0, 10);
            consoleBox.normal.background = Swat.TabButtonBackgroundTexture;

            GUILayout.BeginVertical(consoleBox);             //Begin box border around console.
            _scroll = GUILayout.BeginScrollView(_scroll);

            GUIStyle messageBox = new GUIStyle(GUI.skin.box);

            messageBox.normal.background = Swat.TabButtonBackgroundSelectedTexture;
            messageBox.margin            = new RectOffset(2, 2, 1, 1);
            GUIStyle messageBoxText = new GUIStyle(GUI.skin.label);

            messageBoxText.normal.textColor = Swat.WindowDefaultTextColor;
            messageBox.fixedWidth           = consoleBox.fixedWidth - 10;
            messageBoxText.fixedWidth       = messageBox.fixedWidth - 5;

            string lastConsoleMessage = string.Empty;
            int    duplicateCount     = 0;
            List <AutoConsoleMessage> consoleMessages = AutoConsole.messageListDisplayed;

            for (int m = 0; m < consoleMessages.Count; m++)
            {
                if ((_pubsubMode && consoleMessages[m].messageType != ConsoleMessageType.Pubsub) || (!_pubsubMode && consoleMessages[m].messageType == ConsoleMessageType.Pubsub))
                {
                    continue;
                }

                //If this is a new console message, and auto scroll is on, scroll down automatically.
                if (_autoScroll && m == _lastPassConsoleMessageCount)
                {
                    _scroll.y = 99999;
                    _scroll.x = 0;
                }

                //Render only messages of the requested filter level.
                if (_pubsubMode || (AutoConsole.FilterLevel == MessageLevel.Abridged && consoleMessages[m].level == MessageLevel.Abridged) || AutoConsole.FilterLevel == MessageLevel.Verbose)
                {
                    messageBoxText.normal.textColor = AutoConsole.MessageColor(consoleMessages[m].messageType);
                    GUILayout.BeginHorizontal(messageBox, new GUILayoutOption[] {
                        GUILayout.MinWidth(225),
                        GUILayout.MaxHeight(messageHeight)
                    });

                    if (lastConsoleMessage == consoleMessages[m].message)
                    {
                        duplicateCount++;
                        consoleMessages.RemoveAt(m - 1);
                    }
                    else
                    {
                        lastConsoleMessage = consoleMessages[m].message;
                        duplicateCount     = 0;
                    }

                    if (consoleMessages.Count > m)
                    {
                        if (GUILayout.Button(string.Format("{0} {1}", duplicateCount > 0 ?(duplicateCount + 1).ToString() : string.Empty, consoleMessages[m].message), messageBoxText))
                        {
                            if (_selectedConsoleMessage == consoleMessages[m])
                            {
                                //If the message has been double-clicked, open this test failure as a single-test, temporary report.
                                if (DateTime.Now.Subtract(_lastConsoleMessageButtonClick).TotalSeconds < 0.75d && !string.IsNullOrEmpty(consoleMessages[m].testMethod))
                                {
                                    if (_consoleAbridgedReportTypes.Contains(consoleMessages[m].messageType))
                                    {
                                        _selectedConsoleMessage = null;                                         //Prevents details panel from appearing. We only want it to appear for a single click, not a double click.
                                        AutomationReport.BuildTemporaryReportForSingleConsoleFailure(consoleMessages[m].testMethod);
                                        System.Diagnostics.Process.Start(string.Format("{0}SingleTestAsReportTemp.html", FileBroker.RESOURCES_DIRECTORY));
                                        OpenedTestReport = DateTime.UtcNow;
                                    }
                                }
                                else
                                {
                                    ConsoleMessage.Pop(_selectedConsoleMessage.message, Enum.GetName(typeof(ConsoleMessageType), _selectedConsoleMessage.messageType), Enum.GetName(typeof(MessageLevel), _selectedConsoleMessage.level), _selectedConsoleMessage.timestamp.ToString());
                                    _selectedConsoleMessage = null;
                                }
                            }

                            _selectedConsoleMessage        = consoleMessages[m];
                            _lastConsoleMessageButtonClick = DateTime.Now;
                        }
                    }
                    GUILayout.EndHorizontal();
                }
            }

            _lastPassConsoleMessageCount = consoleMessages.Count;

            GUILayout.EndScrollView();
            GUILayout.EndVertical();
        }