Commit af571a61 authored by BlackAngle233's avatar BlackAngle233
Browse files

212

parent 1d9b5391
using System;
using System.Collections;
namespace UnityEngine.TestTools
{
internal class TestCommandPcHelper
{
public virtual void SetEnumeratorPC(IEnumerator enumerator, int pc)
{
// Noop implementation used in playmode.
}
public virtual int GetEnumeratorPC(IEnumerator enumerator)
{
return 0;
}
}
}
using System;
using System.Collections;
namespace UnityEngine.TestTools
{
internal class TestCommandPcHelper
{
public virtual void SetEnumeratorPC(IEnumerator enumerator, int pc)
{
// Noop implementation used in playmode.
}
public virtual int GetEnumeratorPC(IEnumerator enumerator)
{
return 0;
}
}
}
fileFormatVersion: 2
guid: 33e6b78c96bb0694e96383e3c56b7b54
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 33e6b78c96bb0694e96383e3c56b7b54
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Linq;
using NUnit.Framework.Internal;
using UnityEngine.TestRunner.NUnitExtensions.Runner;
using UnityEngine.TestTools.Logging;
using UnityEngine.TestTools.TestRunner;
namespace UnityEngine.TestTools.NUnitExtensions
{
/// <summary>
/// Specialization of BaseDelegator that makes sure objects are created on the MainThread.
/// It also deals with ScriptableObjects so that tests can survive assembly reload.
/// </summary>
internal class ConstructDelegator
{
private Type m_RequestedType;
private object[] m_Arguments;
private ScriptableObject m_CurrentRunningTest;
private readonly IStateSerializer m_StateSerializer;
protected Exception m_Exception;
protected object m_Result;
protected ITestExecutionContext m_Context;
public ConstructDelegator(IStateSerializer stateSerializer)
{
m_StateSerializer = stateSerializer;
}
protected object HandleResult()
{
SetCurrentTestContext();
if (m_Exception != null)
{
var temp = m_Exception;
m_Exception = null;
throw temp;
}
var tempResult = m_Result;
m_Result = null;
return tempResult;
}
protected void SetCurrentTestContext()
{
var prop = typeof(UnityTestExecutionContext).GetProperty("CurrentContext");
if (prop != null)
{
prop.SetValue(null, m_Context, null);
}
}
public object Delegate(Type type, object[] arguments)
{
AssertState();
m_Context = UnityTestExecutionContext.CurrentContext;
m_RequestedType = type;
m_Arguments = arguments;
using (var logScope = new LogScope())
{
Execute(logScope);
}
return HandleResult();
}
private void AssertState()
{
if (m_RequestedType != null)
{
throw new Exception("Constructor not executed yet");
}
}
public bool HasAction()
{
return m_RequestedType != null;
}
public void Execute(LogScope logScope)
{
try
{
if (typeof(ScriptableObject).IsAssignableFrom(m_RequestedType))
{
if (m_CurrentRunningTest != null && m_RequestedType != m_CurrentRunningTest.GetType())
{
DestroyCurrentTestObjectIfExists();
}
if (m_CurrentRunningTest == null)
{
if (m_StateSerializer.CanRestoreFromScriptableObject(m_RequestedType))
{
m_CurrentRunningTest = m_StateSerializer.RestoreScriptableObjectInstance();
}
else
{
m_CurrentRunningTest = ScriptableObject.CreateInstance(m_RequestedType);
}
}
m_Result = m_CurrentRunningTest;
}
else
{
DestroyCurrentTestObjectIfExists();
m_Result = Activator.CreateInstance(m_RequestedType, m_Arguments);
if (m_StateSerializer.CanRestoreFromJson(m_RequestedType))
{
m_StateSerializer.RestoreClassFromJson(ref m_Result);
}
}
if (logScope.AnyFailingLogs())
{
var failingLog = logScope.FailingLogs.First();
throw new UnhandledLogMessageException(failingLog);
}
if (logScope.ExpectedLogs.Any())
throw new UnexpectedLogMessageException(LogScope.Current.ExpectedLogs.Peek());
}
catch (Exception e)
{
m_Exception = e;
}
finally
{
m_RequestedType = null;
m_Arguments = null;
}
}
public void DestroyCurrentTestObjectIfExists()
{
if (m_CurrentRunningTest == null)
return;
Object.DestroyImmediate(m_CurrentRunningTest);
}
}
}
using System;
using System.Linq;
using NUnit.Framework.Internal;
using UnityEngine.TestRunner.NUnitExtensions.Runner;
using UnityEngine.TestTools.Logging;
using UnityEngine.TestTools.TestRunner;
namespace UnityEngine.TestTools.NUnitExtensions
{
/// <summary>
/// Specialization of BaseDelegator that makes sure objects are created on the MainThread.
/// It also deals with ScriptableObjects so that tests can survive assembly reload.
/// </summary>
internal class ConstructDelegator
{
private Type m_RequestedType;
private object[] m_Arguments;
private ScriptableObject m_CurrentRunningTest;
private readonly IStateSerializer m_StateSerializer;
protected Exception m_Exception;
protected object m_Result;
protected ITestExecutionContext m_Context;
public ConstructDelegator(IStateSerializer stateSerializer)
{
m_StateSerializer = stateSerializer;
}
protected object HandleResult()
{
SetCurrentTestContext();
if (m_Exception != null)
{
var temp = m_Exception;
m_Exception = null;
throw temp;
}
var tempResult = m_Result;
m_Result = null;
return tempResult;
}
protected void SetCurrentTestContext()
{
var prop = typeof(UnityTestExecutionContext).GetProperty("CurrentContext");
if (prop != null)
{
prop.SetValue(null, m_Context, null);
}
}
public object Delegate(Type type, object[] arguments)
{
AssertState();
m_Context = UnityTestExecutionContext.CurrentContext;
m_RequestedType = type;
m_Arguments = arguments;
using (var logScope = new LogScope())
{
Execute(logScope);
}
return HandleResult();
}
private void AssertState()
{
if (m_RequestedType != null)
{
throw new Exception("Constructor not executed yet");
}
}
public bool HasAction()
{
return m_RequestedType != null;
}
public void Execute(LogScope logScope)
{
try
{
if (typeof(ScriptableObject).IsAssignableFrom(m_RequestedType))
{
if (m_CurrentRunningTest != null && m_RequestedType != m_CurrentRunningTest.GetType())
{
DestroyCurrentTestObjectIfExists();
}
if (m_CurrentRunningTest == null)
{
if (m_StateSerializer.CanRestoreFromScriptableObject(m_RequestedType))
{
m_CurrentRunningTest = m_StateSerializer.RestoreScriptableObjectInstance();
}
else
{
m_CurrentRunningTest = ScriptableObject.CreateInstance(m_RequestedType);
}
}
m_Result = m_CurrentRunningTest;
}
else
{
DestroyCurrentTestObjectIfExists();
m_Result = Activator.CreateInstance(m_RequestedType, m_Arguments);
if (m_StateSerializer.CanRestoreFromJson(m_RequestedType))
{
m_StateSerializer.RestoreClassFromJson(ref m_Result);
}
}
if (logScope.AnyFailingLogs())
{
var failingLog = logScope.FailingLogs.First();
throw new UnhandledLogMessageException(failingLog);
}
if (logScope.ExpectedLogs.Any())
throw new UnexpectedLogMessageException(LogScope.Current.ExpectedLogs.Peek());
}
catch (Exception e)
{
m_Exception = e;
}
finally
{
m_RequestedType = null;
m_Arguments = null;
}
}
public void DestroyCurrentTestObjectIfExists()
{
if (m_CurrentRunningTest == null)
return;
Object.DestroyImmediate(m_CurrentRunningTest);
}
}
}
fileFormatVersion: 2
guid: b42e1db66fe9c634798674cb9e1df2ca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: b42e1db66fe9c634798674cb9e1df2ca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: c3de99f9efc582a48995bc8e8c2df418
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: c3de99f9efc582a48995bc8e8c2df418
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal.Filters;
namespace UnityEngine.TestRunner.NUnitExtensions.Filters
{
internal class AssemblyNameFilter : ValueMatchFilter
{
public AssemblyNameFilter(string assemblyName) : base(assemblyName) {}
public override bool Match(ITest test)
{
string assemblyName = string.Empty;
//Assembly fullname is in the format "Assembly-name, meta data ...", so extract the name by looking for the comma
if (test.TypeInfo != null && test.TypeInfo.Assembly != null && test.TypeInfo.FullName != null)
assemblyName = test.TypeInfo.Assembly.FullName.Substring(0, test.TypeInfo.Assembly.FullName.IndexOf(',')).TrimEnd(',');
return ExpectedValue.Equals(assemblyName, StringComparison.OrdinalIgnoreCase);
}
protected override string ElementName
{
get { return "id"; }
}
}
}
using System;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal.Filters;
namespace UnityEngine.TestRunner.NUnitExtensions.Filters
{
internal class AssemblyNameFilter : ValueMatchFilter
{
public AssemblyNameFilter(string assemblyName) : base(assemblyName) {}
public override bool Match(ITest test)
{
string assemblyName = string.Empty;
//Assembly fullname is in the format "Assembly-name, meta data ...", so extract the name by looking for the comma
if (test.TypeInfo != null && test.TypeInfo.Assembly != null && test.TypeInfo.FullName != null)
assemblyName = test.TypeInfo.Assembly.FullName.Substring(0, test.TypeInfo.Assembly.FullName.IndexOf(',')).TrimEnd(',');
return ExpectedValue.Equals(assemblyName, StringComparison.OrdinalIgnoreCase);
}
protected override string ElementName
{
get { return "id"; }
}
}
}
fileFormatVersion: 2
guid: 91319408591cec1478efd3c62f9f418a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 91319408591cec1478efd3c62f9f418a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Linq;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Filters;
namespace UnityEngine.TestRunner.NUnitExtensions.Filters
{
internal class CategoryFilterExtended : CategoryFilter
{
public static string k_DefaultCategory = "Uncategorized";
public CategoryFilterExtended(string name) : base(name)
{
}
public override bool Match(ITest test)
{
IList testCategories = test.Properties[PropertyNames.Category].Cast<string>().ToList();
if (test is TestMethod)
{
// Do not count tests with no attribute as Uncategorized if test fixture class has at least one attribute
// The test inherits the attribute from the test fixture
IList fixtureCategories = test.Parent.Properties[PropertyNames.Category].Cast<string>().ToList();
if (fixtureCategories.Count > 0)
return false;
}
if (testCategories.Count == 0 && ExpectedValue == k_DefaultCategory && test is TestMethod)
return true;
return base.Match(test);
}
}
}
using System.Collections;
using System.Linq;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Filters;
namespace UnityEngine.TestRunner.NUnitExtensions.Filters
{
internal class CategoryFilterExtended : CategoryFilter
{
public static string k_DefaultCategory = "Uncategorized";
public CategoryFilterExtended(string name) : base(name)
{
}
public override bool Match(ITest test)
{
IList testCategories = test.Properties[PropertyNames.Category].Cast<string>().ToList();
if (test is TestMethod)
{
// Do not count tests with no attribute as Uncategorized if test fixture class has at least one attribute
// The test inherits the attribute from the test fixture
IList fixtureCategories = test.Parent.Properties[PropertyNames.Category].Cast<string>().ToList();
if (fixtureCategories.Count > 0)
return false;
}
if (testCategories.Count == 0 && ExpectedValue == k_DefaultCategory && test is TestMethod)
return true;
return base.Match(test);
}
}
}
fileFormatVersion: 2
guid: ebeedaa04bb53e24ba2e7fb6745e3fd3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: ebeedaa04bb53e24ba2e7fb6745e3fd3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections.Generic;
using System.Reflection;
using NUnit.Framework.Api;
using NUnit.Framework.Interfaces;
namespace UnityEngine.TestTools.NUnitExtensions
{
internal interface IAsyncTestAssemblyBuilder : ITestAssemblyBuilder
{
IEnumerator<ITest> BuildAsync(Assembly[] assemblies, TestPlatform[] testPlatforms, IDictionary<string, object> options);
}
using System.Collections.Generic;
using System.Reflection;
using NUnit.Framework.Api;
using NUnit.Framework.Interfaces;
namespace UnityEngine.TestTools.NUnitExtensions
{
internal interface IAsyncTestAssemblyBuilder : ITestAssemblyBuilder
{
IEnumerator<ITest> BuildAsync(Assembly[] assemblies, TestPlatform[] testPlatforms, IDictionary<string, object> options);
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: c3aa5c3d59b94854e843f10b75b3ad63
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: c3aa5c3d59b94854e843f10b75b3ad63
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
namespace UnityEngine.TestTools.NUnitExtensions
{
internal interface IStateSerializer
{
ScriptableObject RestoreScriptableObjectInstance();
void RestoreClassFromJson(ref object instance);
bool CanRestoreFromJson(Type requestedType);
bool CanRestoreFromScriptableObject(Type requestedType);
}
}
using System;
namespace UnityEngine.TestTools.NUnitExtensions
{
internal interface IStateSerializer
{
ScriptableObject RestoreScriptableObjectInstance();
void RestoreClassFromJson(ref object instance);
bool CanRestoreFromJson(Type requestedType);
bool CanRestoreFromScriptableObject(Type requestedType);
}
}
fileFormatVersion: 2
guid: 5f875a14565308a40a5262d2504da705
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 5f875a14565308a40a5262d2504da705
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 37888acc09d9ee848bf9559f06645c45
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 37888acc09d9ee848bf9559f06645c45
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NUnit.Framework;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Commands;
using NUnit.Framework.Internal.Execution;
using UnityEngine.TestTools.Logging;
using UnityEngine.TestTools.TestRunner;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{
internal class CompositeWorkItem : UnityWorkItem
{
private readonly TestSuite _suite;
private readonly TestSuiteResult _suiteResult;
private readonly ITestFilter _childFilter;
private TestCommand _setupCommand;
private TestCommand _teardownCommand;
public List<UnityWorkItem> Children { get; private set; }
private int _countOrder;
private CountdownEvent _childTestCountdown;
public CompositeWorkItem(TestSuite suite, ITestFilter childFilter, WorkItemFactory factory)
: base(suite, factory)
{
_suite = suite;
_suiteResult = Result as TestSuiteResult;
_childFilter = childFilter;
_countOrder = 0;
}
protected override IEnumerable PerformWork()
{
InitializeSetUpAndTearDownCommands();
if (UnityTestExecutionContext.CurrentContext != null && m_DontRunRestoringResult && EditModeTestCallbacks.RestoringTestContext != null)
{
EditModeTestCallbacks.RestoringTestContext();
}
if (!CheckForCancellation())
if (Test.RunState == RunState.Explicit && !_childFilter.IsExplicitMatch(Test))
SkipFixture(ResultState.Explicit, GetSkipReason(), null);
else
switch (Test.RunState)
{
default:
case RunState.Runnable:
case RunState.Explicit:
Result.SetResult(ResultState.Success);
CreateChildWorkItems();
if (Children.Count > 0)
{
if (!m_DontRunRestoringResult)
{
//This is needed to give the editor a chance to go out of playmode if needed before creating objects.
//If we do not, the objects could be automatically destroyed when exiting playmode and could result in errors later on
yield return null;
PerformOneTimeSetUp();
}
if (!CheckForCancellation())
{
switch (Result.ResultState.Status)
{
case TestStatus.Passed:
foreach (var child in RunChildren())
{
if (CheckForCancellation())
{
yield break;
}
yield return child;
}
break;
case TestStatus.Skipped:
case TestStatus.Inconclusive:
case TestStatus.Failed:
SkipChildren(_suite, Result.ResultState.WithSite(FailureSite.Parent), "OneTimeSetUp: " + Result.Message);
break;
}
}
if (Context.ExecutionStatus != TestExecutionStatus.AbortRequested && !m_DontRunRestoringResult)
{
PerformOneTimeTearDown();
}
}
break;
case RunState.Skipped:
SkipFixture(ResultState.Skipped, GetSkipReason(), null);
break;
case RunState.Ignored:
SkipFixture(ResultState.Ignored, GetSkipReason(), null);
break;
case RunState.NotRunnable:
SkipFixture(ResultState.NotRunnable, GetSkipReason(), GetProviderStackTrace());
break;
}
if (!ResultedInDomainReload)
{
WorkItemComplete();
}
}
private bool CheckForCancellation()
{
if (Context.ExecutionStatus != TestExecutionStatus.Running)
{
Result.SetResult(ResultState.Cancelled, "Test cancelled by user");
return true;
}
return false;
}
private void InitializeSetUpAndTearDownCommands()
{
List<SetUpTearDownItem> setUpTearDownItems = _suite.TypeInfo != null
? CommandBuilder.BuildSetUpTearDownList(_suite.TypeInfo.Type, typeof(OneTimeSetUpAttribute), typeof(OneTimeTearDownAttribute))
: new List<SetUpTearDownItem>();
var actionItems = new List<TestActionItem>();
foreach (ITestAction action in Actions)
{
bool applyToSuite = (action.Targets & ActionTargets.Suite) == ActionTargets.Suite
|| action.Targets == ActionTargets.Default && !(Test is ParameterizedMethodSuite);
bool applyToTest = (action.Targets & ActionTargets.Test) == ActionTargets.Test
&& !(Test is ParameterizedMethodSuite);
if (applyToSuite)
actionItems.Add(new TestActionItem(action));
if (applyToTest)
Context.UpstreamActions.Add(action);
}
_setupCommand = CommandBuilder.MakeOneTimeSetUpCommand(_suite, setUpTearDownItems, actionItems);
_teardownCommand = CommandBuilder.MakeOneTimeTearDownCommand(_suite, setUpTearDownItems, actionItems);
}
private void PerformOneTimeSetUp()
{
var logScope = new LogScope();
try
{
_setupCommand.Execute(Context);
}
catch (Exception ex)
{
if (ex is NUnitException || ex is TargetInvocationException)
ex = ex.InnerException;
Result.RecordException(ex, FailureSite.SetUp);
}
if (logScope.AnyFailingLogs())
{
Result.RecordException(new UnhandledLogMessageException(logScope.FailingLogs.First()));
}
logScope.Dispose();
}
private IEnumerable RunChildren()
{
int childCount = Children.Count;
if (childCount == 0)
throw new InvalidOperationException("RunChildren called but item has no children");
_childTestCountdown = new CountdownEvent(childCount);
foreach (UnityWorkItem child in Children)
{
if (CheckForCancellation())
{
yield break;
}
var unityTestExecutionContext = new UnityTestExecutionContext(Context);
child.InitializeContext(unityTestExecutionContext);
var enumerable = child.Execute().GetEnumerator();
while (true)
{
if (!enumerable.MoveNext())
{
break;
}
ResultedInDomainReload |= child.ResultedInDomainReload;
yield return enumerable.Current;
}
_suiteResult.AddResult(child.Result);
childCount--;
}
if (childCount > 0)
{
while (childCount-- > 0)
CountDownChildTest();
}
}
private void CreateChildWorkItems()
{
Children = new List<UnityWorkItem>();
var testSuite = _suite;
foreach (ITest test in testSuite.Tests)
{
if (_childFilter.Pass(test))
{
var child = m_Factory.Create(test, _childFilter);
if (test.Properties.ContainsKey(PropertyNames.Order))
{
Children.Insert(0, child);
_countOrder++;
}
else
{
Children.Add(child);
}
}
}
if (_countOrder != 0) SortChildren();
}
private class UnityWorkItemOrderComparer : IComparer<UnityWorkItem>
{
public int Compare(UnityWorkItem x, UnityWorkItem y)
{
var xKey = int.MaxValue;
var yKey = int.MaxValue;
if (x.Test.Properties.ContainsKey(PropertyNames.Order))
xKey = (int)x.Test.Properties[PropertyNames.Order][0];
if (y.Test.Properties.ContainsKey(PropertyNames.Order))
yKey = (int)y.Test.Properties[PropertyNames.Order][0];
return xKey.CompareTo(yKey);
}
}
private void SortChildren()
{
Children.Sort(0, _countOrder, new UnityWorkItemOrderComparer());
}
private void SkipFixture(ResultState resultState, string message, string stackTrace)
{
Result.SetResult(resultState.WithSite(FailureSite.SetUp), message, StackFilter.Filter(stackTrace));
SkipChildren(_suite, resultState.WithSite(FailureSite.Parent), "OneTimeSetUp: " + message);
}
private void SkipChildren(TestSuite suite, ResultState resultState, string message)
{
foreach (Test child in suite.Tests)
{
if (_childFilter.Pass(child))
{
Context.Listener.TestStarted(child);
TestResult childResult = child.MakeTestResult();
childResult.SetResult(resultState, message);
_suiteResult.AddResult(childResult);
if (child.IsSuite)
SkipChildren((TestSuite)child, resultState, message);
Context.Listener.TestFinished(childResult);
}
}
}
private void PerformOneTimeTearDown()
{
_teardownCommand.Execute(Context);
}
private string GetSkipReason()
{
return (string)Test.Properties.Get(PropertyNames.SkipReason);
}
private string GetProviderStackTrace()
{
return (string)Test.Properties.Get(PropertyNames.ProviderStackTrace);
}
private void CountDownChildTest()
{
_childTestCountdown.Signal();
if (_childTestCountdown.CurrentCount == 0)
{
if (Context.ExecutionStatus != TestExecutionStatus.AbortRequested)
PerformOneTimeTearDown();
foreach (var childResult in _suiteResult.Children)
if (childResult.ResultState == ResultState.Cancelled)
{
this.Result.SetResult(ResultState.Cancelled, "Cancelled by user");
break;
}
WorkItemComplete();
}
}
public override void Cancel(bool force)
{
if (Children == null)
return;
foreach (var child in Children)
{
var ctx = child.Context;
if (ctx != null)
ctx.ExecutionStatus = force ? TestExecutionStatus.AbortRequested : TestExecutionStatus.StopRequested;
if (child.State == WorkItemState.Running)
child.Cancel(force);
}
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NUnit.Framework;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Commands;
using NUnit.Framework.Internal.Execution;
using UnityEngine.TestTools.Logging;
using UnityEngine.TestTools.TestRunner;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{
internal class CompositeWorkItem : UnityWorkItem
{
private readonly TestSuite _suite;
private readonly TestSuiteResult _suiteResult;
private readonly ITestFilter _childFilter;
private TestCommand _setupCommand;
private TestCommand _teardownCommand;
public List<UnityWorkItem> Children { get; private set; }
private int _countOrder;
private CountdownEvent _childTestCountdown;
public CompositeWorkItem(TestSuite suite, ITestFilter childFilter, WorkItemFactory factory)
: base(suite, factory)
{
_suite = suite;
_suiteResult = Result as TestSuiteResult;
_childFilter = childFilter;
_countOrder = 0;
}
protected override IEnumerable PerformWork()
{
InitializeSetUpAndTearDownCommands();
if (UnityTestExecutionContext.CurrentContext != null && m_DontRunRestoringResult && EditModeTestCallbacks.RestoringTestContext != null)
{
EditModeTestCallbacks.RestoringTestContext();
}
if (!CheckForCancellation())
if (Test.RunState == RunState.Explicit && !_childFilter.IsExplicitMatch(Test))
SkipFixture(ResultState.Explicit, GetSkipReason(), null);
else
switch (Test.RunState)
{
default:
case RunState.Runnable:
case RunState.Explicit:
Result.SetResult(ResultState.Success);
CreateChildWorkItems();
if (Children.Count > 0)
{
if (!m_DontRunRestoringResult)
{
//This is needed to give the editor a chance to go out of playmode if needed before creating objects.
//If we do not, the objects could be automatically destroyed when exiting playmode and could result in errors later on
yield return null;
PerformOneTimeSetUp();
}
if (!CheckForCancellation())
{
switch (Result.ResultState.Status)
{
case TestStatus.Passed:
foreach (var child in RunChildren())
{
if (CheckForCancellation())
{
yield break;
}
yield return child;
}
break;
case TestStatus.Skipped:
case TestStatus.Inconclusive:
case TestStatus.Failed:
SkipChildren(_suite, Result.ResultState.WithSite(FailureSite.Parent), "OneTimeSetUp: " + Result.Message);
break;
}
}
if (Context.ExecutionStatus != TestExecutionStatus.AbortRequested && !m_DontRunRestoringResult)
{
PerformOneTimeTearDown();
}
}
break;
case RunState.Skipped:
SkipFixture(ResultState.Skipped, GetSkipReason(), null);
break;
case RunState.Ignored:
SkipFixture(ResultState.Ignored, GetSkipReason(), null);
break;
case RunState.NotRunnable:
SkipFixture(ResultState.NotRunnable, GetSkipReason(), GetProviderStackTrace());
break;
}
if (!ResultedInDomainReload)
{
WorkItemComplete();
}
}
private bool CheckForCancellation()
{
if (Context.ExecutionStatus != TestExecutionStatus.Running)
{
Result.SetResult(ResultState.Cancelled, "Test cancelled by user");
return true;
}
return false;
}
private void InitializeSetUpAndTearDownCommands()
{
List<SetUpTearDownItem> setUpTearDownItems = _suite.TypeInfo != null
? CommandBuilder.BuildSetUpTearDownList(_suite.TypeInfo.Type, typeof(OneTimeSetUpAttribute), typeof(OneTimeTearDownAttribute))
: new List<SetUpTearDownItem>();
var actionItems = new List<TestActionItem>();
foreach (ITestAction action in Actions)
{
bool applyToSuite = (action.Targets & ActionTargets.Suite) == ActionTargets.Suite
|| action.Targets == ActionTargets.Default && !(Test is ParameterizedMethodSuite);
bool applyToTest = (action.Targets & ActionTargets.Test) == ActionTargets.Test
&& !(Test is ParameterizedMethodSuite);
if (applyToSuite)
actionItems.Add(new TestActionItem(action));
if (applyToTest)
Context.UpstreamActions.Add(action);
}
_setupCommand = CommandBuilder.MakeOneTimeSetUpCommand(_suite, setUpTearDownItems, actionItems);
_teardownCommand = CommandBuilder.MakeOneTimeTearDownCommand(_suite, setUpTearDownItems, actionItems);
}
private void PerformOneTimeSetUp()
{
var logScope = new LogScope();
try
{
_setupCommand.Execute(Context);
}
catch (Exception ex)
{
if (ex is NUnitException || ex is TargetInvocationException)
ex = ex.InnerException;
Result.RecordException(ex, FailureSite.SetUp);
}
if (logScope.AnyFailingLogs())
{
Result.RecordException(new UnhandledLogMessageException(logScope.FailingLogs.First()));
}
logScope.Dispose();
}
private IEnumerable RunChildren()
{
int childCount = Children.Count;
if (childCount == 0)
throw new InvalidOperationException("RunChildren called but item has no children");
_childTestCountdown = new CountdownEvent(childCount);
foreach (UnityWorkItem child in Children)
{
if (CheckForCancellation())
{
yield break;
}
var unityTestExecutionContext = new UnityTestExecutionContext(Context);
child.InitializeContext(unityTestExecutionContext);
var enumerable = child.Execute().GetEnumerator();
while (true)
{
if (!enumerable.MoveNext())
{
break;
}
ResultedInDomainReload |= child.ResultedInDomainReload;
yield return enumerable.Current;
}
_suiteResult.AddResult(child.Result);
childCount--;
}
if (childCount > 0)
{
while (childCount-- > 0)
CountDownChildTest();
}
}
private void CreateChildWorkItems()
{
Children = new List<UnityWorkItem>();
var testSuite = _suite;
foreach (ITest test in testSuite.Tests)
{
if (_childFilter.Pass(test))
{
var child = m_Factory.Create(test, _childFilter);
if (test.Properties.ContainsKey(PropertyNames.Order))
{
Children.Insert(0, child);
_countOrder++;
}
else
{
Children.Add(child);
}
}
}
if (_countOrder != 0) SortChildren();
}
private class UnityWorkItemOrderComparer : IComparer<UnityWorkItem>
{
public int Compare(UnityWorkItem x, UnityWorkItem y)
{
var xKey = int.MaxValue;
var yKey = int.MaxValue;
if (x.Test.Properties.ContainsKey(PropertyNames.Order))
xKey = (int)x.Test.Properties[PropertyNames.Order][0];
if (y.Test.Properties.ContainsKey(PropertyNames.Order))
yKey = (int)y.Test.Properties[PropertyNames.Order][0];
return xKey.CompareTo(yKey);
}
}
private void SortChildren()
{
Children.Sort(0, _countOrder, new UnityWorkItemOrderComparer());
}
private void SkipFixture(ResultState resultState, string message, string stackTrace)
{
Result.SetResult(resultState.WithSite(FailureSite.SetUp), message, StackFilter.Filter(stackTrace));
SkipChildren(_suite, resultState.WithSite(FailureSite.Parent), "OneTimeSetUp: " + message);
}
private void SkipChildren(TestSuite suite, ResultState resultState, string message)
{
foreach (Test child in suite.Tests)
{
if (_childFilter.Pass(child))
{
Context.Listener.TestStarted(child);
TestResult childResult = child.MakeTestResult();
childResult.SetResult(resultState, message);
_suiteResult.AddResult(childResult);
if (child.IsSuite)
SkipChildren((TestSuite)child, resultState, message);
Context.Listener.TestFinished(childResult);
}
}
}
private void PerformOneTimeTearDown()
{
_teardownCommand.Execute(Context);
}
private string GetSkipReason()
{
return (string)Test.Properties.Get(PropertyNames.SkipReason);
}
private string GetProviderStackTrace()
{
return (string)Test.Properties.Get(PropertyNames.ProviderStackTrace);
}
private void CountDownChildTest()
{
_childTestCountdown.Signal();
if (_childTestCountdown.CurrentCount == 0)
{
if (Context.ExecutionStatus != TestExecutionStatus.AbortRequested)
PerformOneTimeTearDown();
foreach (var childResult in _suiteResult.Children)
if (childResult.ResultState == ResultState.Cancelled)
{
this.Result.SetResult(ResultState.Cancelled, "Cancelled by user");
break;
}
WorkItemComplete();
}
}
public override void Cancel(bool force)
{
if (Children == null)
return;
foreach (var child in Children)
{
var ctx = child.Context;
if (ctx != null)
ctx.ExecutionStatus = force ? TestExecutionStatus.AbortRequested : TestExecutionStatus.StopRequested;
if (child.State == WorkItemState.Running)
child.Cancel(force);
}
}
}
}
fileFormatVersion: 2
guid: 110d5035a36a6a34580fb65bb40cd78f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 110d5035a36a6a34580fb65bb40cd78f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Collections;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Commands;
using NUnit.Framework.Internal.Execution;
using UnityEngine.TestTools.Utils;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{
internal class CoroutineTestWorkItem : UnityWorkItem
{
private static MonoBehaviour m_MonoBehaviourCoroutineRunner;
private TestCommand m_Command;
public static MonoBehaviour monoBehaviourCoroutineRunner
{
get
{
if (m_MonoBehaviourCoroutineRunner == null)
{
throw new NullReferenceException("MonoBehaviour coroutine runner not set");
}
return m_MonoBehaviourCoroutineRunner;
}
set { m_MonoBehaviourCoroutineRunner = value; }
}
public CoroutineTestWorkItem(TestMethod test, ITestFilter filter)
: base(test, null)
{
m_Command = m_Command = TestCommandBuilder.BuildTestCommand(test, filter);
}
protected override IEnumerable PerformWork()
{
if (m_Command is SkipCommand)
{
m_Command.Execute(Context);
Result = Context.CurrentResult;
WorkItemComplete();
yield break;
}
if (m_Command is ApplyChangesToContextCommand)
{
var applyChangesToContextCommand = (ApplyChangesToContextCommand)m_Command;
applyChangesToContextCommand.ApplyChanges(Context);
m_Command = applyChangesToContextCommand.GetInnerCommand();
}
var enumerableTestMethodCommand = (IEnumerableTestMethodCommand)m_Command;
try
{
var executeEnumerable = enumerableTestMethodCommand.ExecuteEnumerable(Context).GetEnumerator();
var coroutineRunner = new CoroutineRunner(monoBehaviourCoroutineRunner, Context);
yield return coroutineRunner.HandleEnumerableTest(executeEnumerable);
if (coroutineRunner.HasFailedWithTimeout())
{
Context.CurrentResult.SetResult(ResultState.Failure, string.Format("Test exceeded Timeout value of {0}ms", Context.TestCaseTimeout));
}
while (executeEnumerable.MoveNext()) {}
Result = Context.CurrentResult;
}
finally
{
WorkItemComplete();
}
}
}
}
using System;
using System.Collections;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Commands;
using NUnit.Framework.Internal.Execution;
using UnityEngine.TestTools.Utils;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{
internal class CoroutineTestWorkItem : UnityWorkItem
{
private static MonoBehaviour m_MonoBehaviourCoroutineRunner;
private TestCommand m_Command;
public static MonoBehaviour monoBehaviourCoroutineRunner
{
get
{
if (m_MonoBehaviourCoroutineRunner == null)
{
throw new NullReferenceException("MonoBehaviour coroutine runner not set");
}
return m_MonoBehaviourCoroutineRunner;
}
set { m_MonoBehaviourCoroutineRunner = value; }
}
public CoroutineTestWorkItem(TestMethod test, ITestFilter filter)
: base(test, null)
{
m_Command = m_Command = TestCommandBuilder.BuildTestCommand(test, filter);
}
protected override IEnumerable PerformWork()
{
if (m_Command is SkipCommand)
{
m_Command.Execute(Context);
Result = Context.CurrentResult;
WorkItemComplete();
yield break;
}
if (m_Command is ApplyChangesToContextCommand)
{
var applyChangesToContextCommand = (ApplyChangesToContextCommand)m_Command;
applyChangesToContextCommand.ApplyChanges(Context);
m_Command = applyChangesToContextCommand.GetInnerCommand();
}
var enumerableTestMethodCommand = (IEnumerableTestMethodCommand)m_Command;
try
{
var executeEnumerable = enumerableTestMethodCommand.ExecuteEnumerable(Context).GetEnumerator();
var coroutineRunner = new CoroutineRunner(monoBehaviourCoroutineRunner, Context);
yield return coroutineRunner.HandleEnumerableTest(executeEnumerable);
if (coroutineRunner.HasFailedWithTimeout())
{
Context.CurrentResult.SetResult(ResultState.Failure, string.Format("Test exceeded Timeout value of {0}ms", Context.TestCaseTimeout));
}
while (executeEnumerable.MoveNext()) {}
Result = Context.CurrentResult;
}
finally
{
WorkItemComplete();
}
}
}
}
fileFormatVersion: 2
guid: b557515fff172984e8c4400b43f1c631
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: b557515fff172984e8c4400b43f1c631
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Collections;
using System.Linq;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Commands;
using NUnit.Framework.Internal.Execution;
using UnityEngine.TestTools;
using SetUpTearDownCommand = NUnit.Framework.Internal.Commands.SetUpTearDownCommand;
using TestActionCommand = NUnit.Framework.Internal.Commands.TestActionCommand;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{
internal class EditModeTestCallbacks
{
public static Action RestoringTestContext { get; set; }
}
internal class DefaultTestWorkItem : UnityWorkItem
{
private TestCommand _command;
public DefaultTestWorkItem(TestMethod test, ITestFilter filter)
: base(test, null)
{
_command = TestCommandBuilder.BuildTestCommand(test, filter);
}
protected override IEnumerable PerformWork()
{
if (m_DontRunRestoringResult && EditModeTestCallbacks.RestoringTestContext != null)
{
EditModeTestCallbacks.RestoringTestContext();
Result = Context.CurrentResult;
yield break;
}
try
{
if (_command is SkipCommand || _command is FailCommand)
{
Result = _command.Execute(Context);
yield break;
}
if (!(_command is IEnumerableTestMethodCommand))
{
Debug.LogError("Cannot perform work on " + _command.GetType().Name);
yield break;
}
foreach (var workItemStep in ((IEnumerableTestMethodCommand)_command).ExecuteEnumerable(Context))
{
ResultedInDomainReload = false;
if (workItemStep is IEditModeTestYieldInstruction)
{
var editModeTestYieldInstruction = (IEditModeTestYieldInstruction)workItemStep;
yield return editModeTestYieldInstruction;
var enumerator = editModeTestYieldInstruction.Perform();
while (true)
{
bool moveNext;
try
{
moveNext = enumerator.MoveNext();
}
catch (Exception e)
{
Context.CurrentResult.RecordException(e);
break;
}
if (!moveNext)
{
break;
}
yield return null;
}
}
else
{
yield return workItemStep;
}
}
Result = Context.CurrentResult;
}
finally
{
WorkItemComplete();
}
}
}
}
using System;
using System.Collections;
using System.Linq;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Commands;
using NUnit.Framework.Internal.Execution;
using UnityEngine.TestTools;
using SetUpTearDownCommand = NUnit.Framework.Internal.Commands.SetUpTearDownCommand;
using TestActionCommand = NUnit.Framework.Internal.Commands.TestActionCommand;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{
internal class EditModeTestCallbacks
{
public static Action RestoringTestContext { get; set; }
}
internal class DefaultTestWorkItem : UnityWorkItem
{
private TestCommand _command;
public DefaultTestWorkItem(TestMethod test, ITestFilter filter)
: base(test, null)
{
_command = TestCommandBuilder.BuildTestCommand(test, filter);
}
protected override IEnumerable PerformWork()
{
if (m_DontRunRestoringResult && EditModeTestCallbacks.RestoringTestContext != null)
{
EditModeTestCallbacks.RestoringTestContext();
Result = Context.CurrentResult;
yield break;
}
try
{
if (_command is SkipCommand || _command is FailCommand)
{
Result = _command.Execute(Context);
yield break;
}
if (!(_command is IEnumerableTestMethodCommand))
{
Debug.LogError("Cannot perform work on " + _command.GetType().Name);
yield break;
}
foreach (var workItemStep in ((IEnumerableTestMethodCommand)_command).ExecuteEnumerable(Context))
{
ResultedInDomainReload = false;
if (workItemStep is IEditModeTestYieldInstruction)
{
var editModeTestYieldInstruction = (IEditModeTestYieldInstruction)workItemStep;
yield return editModeTestYieldInstruction;
var enumerator = editModeTestYieldInstruction.Perform();
while (true)
{
bool moveNext;
try
{
moveNext = enumerator.MoveNext();
}
catch (Exception e)
{
Context.CurrentResult.RecordException(e);
break;
}
if (!moveNext)
{
break;
}
yield return null;
}
}
else
{
yield return workItemStep;
}
}
Result = Context.CurrentResult;
}
finally
{
WorkItemComplete();
}
}
}
}
fileFormatVersion: 2
guid: c7cfda246e604b945b12b7afedb094ce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: c7cfda246e604b945b12b7afedb094ce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment