169 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Linq;
 | |
| using UnityEditor.TestRunner.TestLaunchers;
 | |
| using UnityEditor.TestTools.TestRunner.Api;
 | |
| using UnityEngine;
 | |
| 
 | |
| namespace UnityEditor.TestTools.TestRunner.CommandLineTest
 | |
| {
 | |
|     internal class Executer : IExecuter
 | |
|     {
 | |
|         internal IRunData runData = RunData.instance;
 | |
| 
 | |
|         private ITestRunnerApi m_TestRunnerApi;
 | |
|         private ISettingsBuilder m_SettingsBuilder;
 | |
|         private Action<string, object[]> m_LogErrorFormat;
 | |
|         private Action<Exception> m_LogException;
 | |
|         private Action<string> m_LogMessage;
 | |
|         private Action<int> m_ExitEditorApplication;
 | |
|         private Func<bool> m_ScriptCompilationFailedCheck;
 | |
|         private Func<bool> m_IsRunActive;
 | |
| 
 | |
|         public Executer(ITestRunnerApi testRunnerApi, ISettingsBuilder settingsBuilder, Action<string, object[]> logErrorFormat, Action<Exception> logException, Action<string> logMessage, Action<int> exitEditorApplication, Func<bool> scriptCompilationFailedCheck, Func<bool> isRunActive)
 | |
|         {
 | |
|             m_TestRunnerApi = testRunnerApi;
 | |
|             m_SettingsBuilder = settingsBuilder;
 | |
|             m_LogErrorFormat = logErrorFormat;
 | |
|             m_LogException = logException;
 | |
|             m_LogMessage = logMessage;
 | |
|             m_ExitEditorApplication = exitEditorApplication;
 | |
|             m_ScriptCompilationFailedCheck = scriptCompilationFailedCheck;
 | |
|             m_IsRunActive = isRunActive;
 | |
|         }
 | |
| 
 | |
|         public string InitializeAndExecuteRun(string[] commandLineArgs)
 | |
|         {
 | |
|             Api.ExecutionSettings executionSettings;
 | |
|             try
 | |
|             {
 | |
|                 executionSettings = m_SettingsBuilder.BuildApiExecutionSettings(commandLineArgs);
 | |
|                 if (executionSettings.targetPlatform.HasValue)
 | |
|                     RemotePlayerLogController.instance.SetBuildTarget(executionSettings.targetPlatform.Value);
 | |
|             }
 | |
|             catch (SetupException exception)
 | |
|             {
 | |
|                 HandleSetupException(exception);
 | |
|                 return string.Empty;
 | |
|             }
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 // It is important that the message starts with "Running tests for ", otherwise TestCleanConsole will fail.
 | |
|                 m_LogMessage($"Running tests for {executionSettings}");
 | |
|                 return m_TestRunnerApi.Execute(executionSettings);
 | |
|             }
 | |
|             catch (Exception exception)
 | |
|             {
 | |
|                 m_LogException(exception);
 | |
|                 ExitApplication(ReturnCodes.RunError, "Exception when starting test run.");
 | |
|                 return string.Empty;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public void ExitIfRunIsCompleted()
 | |
|         {
 | |
|             if (m_IsRunActive())
 | |
|             {
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             var runState = runData.RunState;
 | |
|             var returnCode = s_StateReturnCodes[runState];
 | |
|             var reason = s_StateMessages[runState] ?? runData.RunErrorMessage;
 | |
|             ExitApplication(returnCode, reason);
 | |
|         }
 | |
| 
 | |
|         private void ExitApplication(ReturnCodes returnCode, string reason)
 | |
|         {
 | |
|             var returnCodeInt = (int)returnCode;
 | |
| 
 | |
|             m_LogMessage($"Test run completed. Exiting with code {returnCodeInt} ({returnCode}). {reason}");
 | |
| 
 | |
|             m_ExitEditorApplication(returnCodeInt);
 | |
|         }
 | |
| 
 | |
|         public ExecutionSettings BuildExecutionSettings(string[] commandLineArgs)
 | |
|         {
 | |
|             return m_SettingsBuilder.BuildExecutionSettings(commandLineArgs);
 | |
|         }
 | |
| 
 | |
|         internal enum ReturnCodes
 | |
|         {
 | |
|             Ok = 0,
 | |
|             Failed = 2,
 | |
|             RunError = 3,
 | |
|             PlatformNotFoundReturnCode = 4
 | |
|         }
 | |
| 
 | |
|         public void SetUpCallbacks(ExecutionSettings executionSettings)
 | |
|         {
 | |
|             RemotePlayerLogController.instance.SetLogsDirectory(executionSettings.DeviceLogsDirectory);
 | |
| 
 | |
|             var resultSavingCallback = ScriptableObject.CreateInstance<ResultsSavingCallbacks>();
 | |
|             resultSavingCallback.m_ResultFilePath = executionSettings.TestResultsFile;
 | |
| 
 | |
|             var logSavingCallback = ScriptableObject.CreateInstance<LogSavingCallbacks>();
 | |
| 
 | |
|             TestRunnerApi.RegisterTestCallback(resultSavingCallback);
 | |
|             TestRunnerApi.RegisterTestCallback(logSavingCallback);
 | |
|             TestRunnerApi.RegisterTestCallback(new RunStateCallbacks());
 | |
|         }
 | |
| 
 | |
|         public void ExitOnCompileErrors()
 | |
|         {
 | |
|             if (m_ScriptCompilationFailedCheck())
 | |
|             {
 | |
|                 var handling = s_ExceptionHandlingMapping.First(h => h.m_ExceptionType == SetupException.ExceptionType.ScriptCompilationFailed);
 | |
|                 m_LogErrorFormat(handling.m_Message, new object[0]);
 | |
|                 ExitApplication(handling.m_ReturnCode, handling.m_Message);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void HandleSetupException(SetupException exception)
 | |
|         {
 | |
|             ExceptionHandling handling = s_ExceptionHandlingMapping.FirstOrDefault(h => h.m_ExceptionType == exception.Type) ?? new ExceptionHandling(exception.Type, "Unknown command line test run error. " + exception.Type, ReturnCodes.RunError);
 | |
|             m_LogErrorFormat(handling.m_Message, exception.Details);
 | |
|             ExitApplication(handling.m_ReturnCode, handling.m_Message);
 | |
|         }
 | |
| 
 | |
|         private class ExceptionHandling
 | |
|         {
 | |
|             internal SetupException.ExceptionType m_ExceptionType;
 | |
|             internal string m_Message;
 | |
|             internal ReturnCodes m_ReturnCode;
 | |
|             public ExceptionHandling(SetupException.ExceptionType exceptionType, string message, ReturnCodes returnCode)
 | |
|             {
 | |
|                 m_ExceptionType = exceptionType;
 | |
|                 m_Message = message;
 | |
|                 m_ReturnCode = returnCode;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private static ExceptionHandling[] s_ExceptionHandlingMapping = {
 | |
|             new ExceptionHandling(SetupException.ExceptionType.ScriptCompilationFailed, "Scripts had compilation errors.", ReturnCodes.RunError),
 | |
|             new ExceptionHandling(SetupException.ExceptionType.PlatformNotFound, "Test platform not found ({0}).", ReturnCodes.PlatformNotFoundReturnCode),
 | |
|             new ExceptionHandling(SetupException.ExceptionType.TestSettingsFileNotFound, "Test settings file not found at {0}.", ReturnCodes.RunError),
 | |
|             new ExceptionHandling(SetupException.ExceptionType.OrderedTestListFileNotFound, "Ordered test list file not found at {0}.", ReturnCodes.RunError)
 | |
|         };
 | |
| 
 | |
|         private static IDictionary<TestRunState, string> s_StateMessages = new Dictionary<TestRunState, string>()
 | |
|         {
 | |
|             {TestRunState.NoCallbacksReceived, "No callbacks received."},
 | |
|             {TestRunState.OneOrMoreTestsExecutedWithNoFailures, "Run completed."},
 | |
|             {TestRunState.OneOrMoreTestsExecutedWithOneOrMoreFailed, "One or more tests failed."},
 | |
|             {TestRunState.CompletedJobWithoutAnyTestsExecuted, "No tests were executed."},
 | |
|             {TestRunState.RunError, null}
 | |
|         };
 | |
| 
 | |
|         private static IDictionary<TestRunState, ReturnCodes> s_StateReturnCodes = new Dictionary<TestRunState, ReturnCodes>()
 | |
|         {
 | |
|             {TestRunState.NoCallbacksReceived, ReturnCodes.RunError},
 | |
|             {TestRunState.OneOrMoreTestsExecutedWithNoFailures, ReturnCodes.Ok},
 | |
|             {TestRunState.OneOrMoreTestsExecutedWithOneOrMoreFailed, ReturnCodes.Failed},
 | |
|             {TestRunState.CompletedJobWithoutAnyTestsExecuted, ReturnCodes.Ok},
 | |
|             {TestRunState.RunError, ReturnCodes.RunError}
 | |
|         };
 | |
|     }
 | |
| }
 |