-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathParallelTestMethodAttribute.cs
106 lines (85 loc) · 3.91 KB
/
ParallelTestMethodAttribute.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using Meadow.Core.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Text;
namespace Meadow.UnitTestTemplate
{
public class ParallelTestMethodAttribute : TestMethodAttribute
{
#region Fields
private readonly TestMethodAttribute _testMethodAttribute;
#endregion
#region Constructors
public ParallelTestMethodAttribute()
{
}
public ParallelTestMethodAttribute(TestMethodAttribute testMethodAttribute)
{
_testMethodAttribute = testMethodAttribute;
}
#endregion
#region Functions
public override TestResult[] Execute(ITestMethod testMethod)
{
// Get our test context
TestContext testContext = testMethod.GetTestContext();
// Create a new internal test state.
InternalTestState internalTestState = testContext.ResetInternalTestState();
// Convert test argument types
object[] args = null;
if (testMethod.Arguments != null)
{
args = new object[testMethod.Arguments.Length];
for (var i = 0; i < args.Length; i++)
{
args[i] = TypeConversion.ConvertValue(testMethod.ParameterTypes[i].ParameterType, testMethod.Arguments[i]);
}
}
// Execute our test method on our main node.
TestResult mainResult = testMethod.Invoke(args);
// Set a more accurate time elapse duration (end of init to start of cleanup)
mainResult.Duration = internalTestState.EndTime - internalTestState.StartTime;
// Obtain the display name for our test.
string testDisplayName = mainResult.DisplayName ?? testMethod.TestMethodName;
// Reset the internal test state for this test context
internalTestState = testContext.ResetInternalTestState();
// If we have a parallel node to run tests against..
if (Global.ExternalNodeTestServices != null)
{
// If we are only running against the external node
if (Global.OnlyUseExternalNode.GetValueOrDefault())
{
// Only using the external node means the above method invocation already ran on
// the external node, so we quit with the singular result.
return new[] { mainResult };
}
// Begin using the external node.
internalTestState.InExternalNodeContext = true;
// Execute our test method on our parallel node
TestResult parallelResult = testMethod.Invoke(args);
// Set a more accurate time elapse duration (end of init to start of cleanup)
parallelResult.Duration = internalTestState.EndTime - internalTestState.StartTime;
// Stop using the external node.
internalTestState.InExternalNodeContext = false;
// Set our test names
mainResult.DisplayName = $"{testDisplayName} (built-in)";
parallelResult.DisplayName = $"{testDisplayName} (external)";
return new[] { mainResult, parallelResult };
}
else
{
var parallelResult = new TestResult
{
Outcome = UnitTestOutcome.Error,
TestFailureException = new Exception("Failed to run parallel test because parallel test node services failed to initialize properly."),
};
// Set our test names
mainResult.DisplayName = $"{testDisplayName} (built-in)";
parallelResult.DisplayName = $"{testDisplayName} (external)";
return new[] { mainResult, parallelResult };
}
}
#endregion
}
}