Skip to content

Commit 9781660

Browse files
authored
Add InitializeLifetimeService() (#97)
* Add InitializeLifetimeService() * Improve logging * Remove stopwatch * Add logging and make exeption logging consitent * ignore if we can't report the error * Add IFrameworkLogger instead * Add IFrameworkLogger
1 parent 444052d commit 9781660

File tree

8 files changed

+83
-39
lines changed

8 files changed

+83
-39
lines changed

src/Machine.Specifications.Runner.VisualStudio/Discovery/BuiltIn/TestDiscoverer.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,18 @@
88

99
namespace Machine.VSTestAdapter.Discovery.BuiltIn
1010
{
11-
1211
public class TestDiscoverer
1312
#if !NETSTANDARD
1413
: MarshalByRefObject
1514
#endif
1615
{
17-
16+
#if !NETSTANDARD
17+
[System.Security.SecurityCritical]
18+
public override object InitializeLifetimeService()
19+
{
20+
return null;
21+
}
22+
#endif
1823
private readonly PropertyInfo behaviorProperty = typeof(BehaviorSpecification).GetProperty("BehaviorFieldInfo");
1924

2025
public IEnumerable<MSpecTestCase> DiscoverTests(string assemblyPath)
@@ -48,7 +53,7 @@ private IEnumerable<MSpecTestCase> CreateTestCase(Context context, SourceCodeLoc
4853
fieldDeclaringType = spec.FieldInfo.DeclaringType.GetGenericTypeDefinition().FullName;
4954
else
5055
fieldDeclaringType = spec.FieldInfo.DeclaringType.FullName;
51-
56+
5257
SourceCodeLocationInfo locationInfo = locationFinder.GetFieldLocation(fieldDeclaringType, spec.FieldInfo.Name);
5358
if (locationInfo != null)
5459
{
@@ -89,13 +94,6 @@ private string GetContextDisplayName(Type contextType)
8994

9095
return displayName;
9196
}
92-
93-
#if !NETSTANDARD
94-
public override object InitializeLifetimeService()
95-
{
96-
return null;
97-
}
98-
#endif
9997
}
10098

10199
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
2+
3+
namespace Machine.VSTestAdapter.Execution
4+
{
5+
public interface IFrameworkLogger
6+
{
7+
void SendMessage(TestMessageLevel level, string message);
8+
}
9+
}

src/Machine.Specifications.Runner.VisualStudio/Execution/SpecificationExecutor.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
2-
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
1+
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
32
using System;
43
using System.Collections.Generic;
54
using System.IO;
6-
using System.Linq;
75
using Machine.VSTestAdapter.Helpers;
86
using Machine.VSTestAdapter.Configuration;
97

@@ -29,7 +27,7 @@ public void RunAssemblySpecifications(string assemblyPath,
2927

3028
executor.RunTestsInAssembly(assemblyPath, specifications, listener);
3129
#if !NETSTANDARD
32-
}
30+
}
3331
#endif
3432
}
3533
}

src/Machine.Specifications.Runner.VisualStudio/Execution/SpecificationFilterProvider.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ public SpecificationFilterProvider()
3434
.ToArray();
3535
}
3636

37-
3837
public IEnumerable<TestCase> FilteredTests(IEnumerable<TestCase> testCases, IRunContext runContext, IFrameworkHandle handle)
3938
{
4039
var filterExpression = runContext.GetTestCaseFilter(supportedProperties, propertyName =>
@@ -50,13 +49,13 @@ public IEnumerable<TestCase> FilteredTests(IEnumerable<TestCase> testCases, IRun
5049
return null;
5150
});
5251

52+
handle?.SendMessage(TestMessageLevel.Informational, $"Machine Specifications Visual Studio Test Adapter - Filter property set '{filterExpression?.TestCaseFilterValue}'");
53+
5354
if (filterExpression == null)
5455
{
5556
return testCases;
5657
}
5758

58-
handle?.SendMessage(TestMessageLevel.Informational, $"Machine Specifications Visual Studio Test Adapter - Filter property set '{filterExpression.TestCaseFilterValue}'");
59-
6059
var filteredTests = testCases
6160
.Where(testCase => filterExpression.MatchTestCase(testCase, propertyName =>
6261
{

src/Machine.Specifications.Runner.VisualStudio/Execution/TestExecutor.cs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
using System.Reflection;
77
using Machine.Specifications;
88
using Machine.VSTestAdapter.Helpers;
9+
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
10+
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
911

1012
namespace Machine.VSTestAdapter.Execution
1113
{
@@ -14,15 +16,15 @@ public class TestExecutor
1416
: MarshalByRefObject
1517
#endif
1618
{
17-
1819
#if !NETSTANDARD
20+
[System.Security.SecurityCritical]
1921
public override object InitializeLifetimeService()
2022
{
2123
return null;
2224
}
2325
#endif
2426

25-
private DefaultRunner CreateRunner(Assembly assembly,ISpecificationRunListener specificationRunListener)
27+
private DefaultRunner CreateRunner(Assembly assembly, ISpecificationRunListener specificationRunListener)
2628
{
2729
var listener = new AggregateRunListener(new[] {
2830
specificationRunListener,
@@ -59,8 +61,23 @@ public void RunTestsInAssembly(string pathToAssembly, IEnumerable<VisualStudioTe
5961
}
6062
finally
6163
{
62-
if (mspecRunner != null && assemblyToRun != null)
63-
mspecRunner.EndRun(assemblyToRun);
64+
try
65+
{
66+
if (mspecRunner != null && assemblyToRun != null)
67+
mspecRunner.EndRun(assemblyToRun);
68+
}
69+
catch (Exception exception)
70+
{
71+
try
72+
{
73+
var frameworkLogger = specificationRunListener as IFrameworkLogger;
74+
frameworkLogger?.SendMessage(TestMessageLevel.Error, "Machine Specifications Visual Studio Test Adapter - Error Ending Test Run." + Environment.NewLine + exception);
75+
}
76+
catch
77+
{
78+
// ignored
79+
}
80+
}
6481
}
6582
}
6683
}

src/Machine.Specifications.Runner.VisualStudio/Execution/VSProxyAssemblySpecificationRunListener.cs

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,15 @@ public class VSProxyAssemblySpecificationRunListener :
1313
#if !NETSTANDARD
1414
MarshalByRefObject,
1515
#endif
16-
ISpecificationRunListener
16+
ISpecificationRunListener, IFrameworkLogger
1717
{
18+
#if !NETSTANDARD
19+
[System.Security.SecurityCritical]
20+
public override object InitializeLifetimeService()
21+
{
22+
return null;
23+
}
24+
#endif
1825
private readonly IFrameworkHandle frameworkHandle;
1926
private readonly string assemblyPath;
2027
private readonly Uri executorUri;
@@ -23,7 +30,8 @@ public class VSProxyAssemblySpecificationRunListener :
2330
private RunStats currentRunStats;
2431
readonly Settings settings;
2532

26-
public VSProxyAssemblySpecificationRunListener(string assemblyPath, IFrameworkHandle frameworkHandle, Uri executorUri, Settings settings)
33+
public VSProxyAssemblySpecificationRunListener(string assemblyPath, IFrameworkHandle frameworkHandle,
34+
Uri executorUri, Settings settings)
2735
{
2836
if (settings == null)
2937
throw new ArgumentNullException(nameof(settings));
@@ -48,7 +56,9 @@ public void OnFatalError(ExceptionResult exception)
4856
this.currentRunStats = null;
4957
}
5058

51-
this.frameworkHandle.SendMessage(TestMessageLevel.Error, "Machine Specifications Visual Studio Test Adapter - Fatal error while executing test." + Environment.NewLine + exception.ToString());
59+
this.frameworkHandle.SendMessage(TestMessageLevel.Error,
60+
"Machine Specifications Visual Studio Test Adapter - Fatal error while executing test." +
61+
Environment.NewLine + exception);
5262
}
5363

5464
public void OnSpecificationStart(SpecificationInfo specification)
@@ -80,13 +90,17 @@ public void OnContextEnd(ContextInfo context)
8090
}
8191

8292

83-
#region Mapping
93+
#region Mapping
94+
8495
private TestCase ConvertSpecificationToTestCase(SpecificationInfo specification, Settings settings)
8596
{
8697
VisualStudioTestIdentifier vsTestId = specification.ToVisualStudioTestIdentifier(currentContext);
8798

88-
return new TestCase(vsTestId.FullyQualifiedName, this.executorUri, this.assemblyPath) {
89-
DisplayName = settings.DisableFullTestNameInOutput ? specification.Name : $"{this.currentContext?.TypeName}.{specification.FieldName}",
99+
return new TestCase(vsTestId.FullyQualifiedName, this.executorUri, this.assemblyPath)
100+
{
101+
DisplayName = settings.DisableFullTestNameInOutput
102+
? specification.Name
103+
: $"{this.currentContext?.TypeName}.{specification.FieldName}",
90104
};
91105
}
92106

@@ -109,19 +123,20 @@ private static TestOutcome MapSpecificationResultToTestOutcome(Result result)
109123

110124
private static TestResult ConverResultToTestResult(TestCase testCase, Result result, RunStats runStats)
111125
{
112-
TestResult testResult = new TestResult(testCase) {
126+
TestResult testResult = new TestResult(testCase)
127+
{
113128
ComputerName = Environment.MachineName,
114129
Outcome = MapSpecificationResultToTestOutcome(result),
115130
DisplayName = testCase.DisplayName
116131
};
117132

118-
if (result.Exception != null)
133+
if (result.Exception != null)
119134
{
120135
testResult.ErrorMessage = result.Exception.Message;
121136
testResult.ErrorStackTrace = result.Exception.ToString();
122137
}
123138

124-
if (runStats != null)
139+
if (runStats != null)
125140
{
126141
testResult.StartTime = runStats.Start;
127142
testResult.EndTime = runStats.End;
@@ -131,10 +146,11 @@ private static TestResult ConverResultToTestResult(TestCase testCase, Result res
131146
return testResult;
132147
}
133148

134-
#endregion
149+
#endregion
150+
135151

152+
#region Stubs
136153

137-
#region Stubs
138154
public void OnAssemblyEnd(AssemblyInfo assembly)
139155
{
140156
}
@@ -150,6 +166,12 @@ public void OnRunEnd()
150166
public void OnRunStart()
151167
{
152168
}
153-
#endregion
169+
170+
#endregion
171+
172+
public void SendMessage(TestMessageLevel level, string message)
173+
{
174+
frameworkHandle?.SendMessage(level, message);
175+
}
154176
}
155177
}

src/Machine.Specifications.Runner.VisualStudio/MSpecTestAdapterDiscoverer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ public void DiscoverTests(IEnumerable<string> sources, Settings settings, IMessa
6666
}
6767
catch (Exception discoverException)
6868
{
69-
logger.SendMessage(TestMessageLevel.Error, $"Machine Specifications Visual Studio Test Adapter - Error while discovering specifications in assembly {assemblyPath} - {discoverException}");
69+
logger.SendMessage(TestMessageLevel.Error, $"Machine Specifications Visual Studio Test Adapter - Error while discovering specifications in assembly {assemblyPath}." + Environment.NewLine + discoverException);
7070
}
7171
}
7272

73-
logger.SendMessage(TestMessageLevel.Informational, string.Format("Machine Specifications Visual Studio Test Adapter - Discovery Complete - {0} specifications in {2} of {1} assemblies scanned.", discoveredSpecCount, sourcesArray.Count(), sourcesWithSpecs));
73+
logger.SendMessage(TestMessageLevel.Informational, $"Machine Specifications Visual Studio Test Adapter - Discovery Complete - {discoveredSpecCount} specifications in {sourcesWithSpecs} of {sourcesArray.Length} assemblies scanned.");
7474
}
7575
}
7676
}

src/Machine.Specifications.Runner.VisualStudio/MspecTestAdapterExecutor.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,25 +45,26 @@ public void RunTests(IEnumerable<TestCase> tests, IRunContext runContext, IFrame
4545
var testCases = tests.ToArray();
4646
foreach (var grouping in testCases.GroupBy(x => x.Source))
4747
{
48+
currentAssembly = grouping.Key;
4849
totalSpecCount += grouping.Count();
4950

50-
frameworkHandle.SendMessage(TestMessageLevel.Informational, $"Machine Specifications Visual Studio Test Adapter - Executing test cases in {grouping.Key}");
51-
5251
var filteredTests = specificationFilterProvider.FilteredTests(grouping.AsEnumerable(), runContext, frameworkHandle);
5352

5453
var testsToRun = filteredTests
5554
.Select(test => test.ToVisualStudioTestIdentifier())
5655
.ToArray();
5756

57+
frameworkHandle.SendMessage(TestMessageLevel.Informational, $"Machine Specifications Visual Studio Test Adapter - Executing {testsToRun.Length} tests in '{currentAssembly}'.");
58+
5859
executor.RunAssemblySpecifications(grouping.Key, testsToRun, settings, MSpecTestAdapter.Uri, frameworkHandle);
5960
executedSpecCount += testsToRun.Length;
6061
}
6162

6263
frameworkHandle.SendMessage(TestMessageLevel.Informational, $"Machine Specifications Visual Studio Test Adapter - Execution Complete - {executedSpecCount} of {totalSpecCount} specifications in {testCases.GroupBy(x => x.Source).Count()} assemblies.");
6364
}
64-
catch (Exception ex)
65+
catch (Exception exception)
6566
{
66-
frameworkHandle.SendMessage(TestMessageLevel.Error, $"Machine Specifications Visual Studio Test Adapter - Error while executing specifications in assembly {currentAssembly} - {ex}");
67+
frameworkHandle.SendMessage(TestMessageLevel.Error, $"Machine Specifications Visual Studio Test Adapter - Error while executing specifications in assembly '{currentAssembly}'." + Environment.NewLine + exception);
6768
}
6869
}
6970

0 commit comments

Comments
 (0)