TestJobRunner.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using UnityEditor.TestTools.TestRunner.Api;
  6. using UnityEditor.TestTools.TestRunner.TestRun.Tasks;
  7. using UnityEngine;
  8. using UnityEngine.TestTools;
  9. namespace UnityEditor.TestTools.TestRunner.TestRun
  10. {
  11. internal class TestJobRunner
  12. {
  13. private static IEnumerable<TestTaskBase> GetTaskList(ExecutionSettings settings)
  14. {
  15. if (settings == null)
  16. {
  17. yield break;
  18. }
  19. if (settings.EditModeIncluded() || (PlayerSettings.runPlayModeTestAsEditModeTest && settings.PlayModeInEditorIncluded()))
  20. {
  21. yield return new SaveModiedSceneTask();
  22. yield return new RegisterFilesForCleanupVerificationTask();
  23. yield return new SaveUndoIndexTask();
  24. yield return new BuildTestTreeTask(TestPlatform.EditMode);
  25. yield return new PrebuildSetupTask();
  26. yield return new LegacyEditModeRunTask();
  27. yield return new PerformUndoTask();
  28. yield return new CleanupVerificationTask();
  29. yield break;
  30. }
  31. if (settings.PlayModeInEditorIncluded() && !PlayerSettings.runPlayModeTestAsEditModeTest)
  32. {
  33. yield return new SaveModiedSceneTask();
  34. yield return new LegacyPlayModeRunTask();
  35. yield break;
  36. }
  37. if (settings.PlayerIncluded())
  38. {
  39. yield return new LegacyPlayerRunTask();
  40. yield break;
  41. }
  42. }
  43. internal List<TestJobData> SavedTestJobData = TestJobDataHolder.instance.TestRuns;
  44. internal Action<EditorApplication.CallbackFunction> SubscribeCallback = (callback) => EditorApplication.update += callback;
  45. // ReSharper disable once DelegateSubtraction
  46. internal Action<EditorApplication.CallbackFunction> UnsubscribeCallback = (callback) => EditorApplication.update -= callback;
  47. internal TestCommandPcHelper PcHelper = new EditModePcHelper();
  48. internal Func<ExecutionSettings, IEnumerable<TestTaskBase>> GetTasks = GetTaskList;
  49. internal Action<Exception> LogException = Debug.LogException;
  50. internal Action<string> LogError = Debug.LogError;
  51. internal Action<string> ReportRunFailed = CallbacksDelegator.instance.RunFailed;
  52. private TestJobData m_JobData;
  53. private TestTaskBase[] Tasks;
  54. private IEnumerator m_Enumerator = null;
  55. public string RunJob(TestJobData data)
  56. {
  57. if (data == null)
  58. {
  59. throw new ArgumentException(null, nameof(data));
  60. }
  61. if (m_JobData != null && m_JobData.isRunning)
  62. {
  63. throw new Exception("TestJobRunner is already running a job.");
  64. }
  65. if (data.isHandledByRunner)
  66. {
  67. throw new Exception("Test job is already being handled.");
  68. }
  69. m_JobData = data;
  70. m_JobData.isHandledByRunner = true;
  71. if (!m_JobData.isRunning)
  72. {
  73. m_JobData.isRunning = true;
  74. SavedTestJobData.Add(m_JobData);
  75. }
  76. Tasks = GetTasks(data.executionSettings).ToArray();
  77. if (!data.executionSettings.runSynchronously)
  78. {
  79. SubscribeCallback(ExecuteStep);
  80. }
  81. else
  82. {
  83. while (data.isRunning)
  84. {
  85. ExecuteStep();
  86. }
  87. }
  88. return data.guid;
  89. }
  90. private void ExecuteStep()
  91. {
  92. try
  93. {
  94. if (m_JobData.taskIndex >= Tasks.Length)
  95. {
  96. StopRun();
  97. return;
  98. }
  99. if (m_Enumerator == null)
  100. {
  101. var task = Tasks[m_JobData.taskIndex];
  102. m_Enumerator = task.Execute(m_JobData);
  103. if (task.SupportsResumingEnumerator)
  104. {
  105. PcHelper.SetEnumeratorPC(m_Enumerator, m_JobData.taskPC);
  106. }
  107. }
  108. if (!m_Enumerator.MoveNext())
  109. {
  110. m_JobData.taskIndex++;
  111. m_JobData.taskPC = 0;
  112. m_Enumerator = null;
  113. return;
  114. }
  115. if (Tasks[m_JobData.taskIndex].SupportsResumingEnumerator)
  116. {
  117. m_JobData.taskPC = PcHelper.GetEnumeratorPC(m_Enumerator);
  118. }
  119. }
  120. catch (TestRunCanceledException)
  121. {
  122. StopRun();
  123. }
  124. catch (AggregateException ex)
  125. {
  126. StopRun();
  127. LogError(ex.Message);
  128. foreach (var innerException in ex.InnerExceptions)
  129. {
  130. LogException(innerException);
  131. }
  132. ReportRunFailed("Multiple unexpected errors happened while running tests.");
  133. }
  134. catch (Exception ex)
  135. {
  136. StopRun();
  137. LogException(ex);
  138. ReportRunFailed("An unexpected error happened while running tests.");
  139. }
  140. }
  141. private void StopRun()
  142. {
  143. m_JobData.isRunning = false;
  144. UnsubscribeCallback(ExecuteStep);
  145. SavedTestJobData.Remove(m_JobData);
  146. }
  147. }
  148. }