-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Test Optimization] Support for MSTest v3.8.x #6686
[Test Optimization] Support for MSTest v3.8.x #6686
Conversation
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing the following branches/commits: Execution-time benchmarks measure the whole time it takes to execute a program. And are intended to measure the one-off costs. Cases where the execution time results for the PR are worse than latest master results are shown in red. The following thresholds were used for comparing the execution times:
Note that these results are based on a single point-in-time result for each branch. For full results, see the dashboard. Graphs show the p99 interval based on the mean and StdDev of the test run, as well as the mean value of the run (shown as a diamond below the graph). gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.6.2)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6686) - mean (69ms) : 66, 72
. : milestone, 69,
master - mean (73ms) : 70, 77
. : milestone, 73,
section CallTarget+Inlining+NGEN
This PR (6686) - mean (998ms) : 975, 1020
. : milestone, 998,
master - mean (1,034ms) : 1004, 1063
. : milestone, 1034,
gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6686) - mean (102ms) : 100, 104
. : milestone, 102,
master - mean (108ms) : 105, 111
. : milestone, 108,
section CallTarget+Inlining+NGEN
This PR (6686) - mean (674ms) : 653, 694
. : milestone, 674,
master - mean (698ms) : 680, 717
. : milestone, 698,
gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6686) - mean (89ms) : 86, 91
. : milestone, 89,
master - mean (95ms) : 92, 97
. : milestone, 95,
section CallTarget+Inlining+NGEN
This PR (6686) - mean (627ms) : 608, 646
. : milestone, 627,
master - mean (656ms) : 639, 672
. : milestone, 656,
gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.6.2)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6686) - mean (191ms) : 186, 196
. : milestone, 191,
master - mean (191ms) : 186, 197
. : milestone, 191,
section CallTarget+Inlining+NGEN
This PR (6686) - mean (1,108ms) : 1071, 1146
. : milestone, 1108,
master - mean (1,109ms) : 1073, 1146
. : milestone, 1109,
gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6686) - mean (271ms) : 267, 275
. : milestone, 271,
master - mean (273ms) : 266, 280
. : milestone, 273,
section CallTarget+Inlining+NGEN
This PR (6686) - mean (868ms) : 831, 904
. : milestone, 868,
master - mean (867ms) : 834, 900
. : milestone, 867,
gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6686) - mean (263ms) : 258, 267
. : milestone, 263,
master - mean (262ms) : 258, 267
. : milestone, 262,
section CallTarget+Inlining+NGEN
This PR (6686) - mean (837ms) : 806, 868
. : milestone, 837,
master - mean (849ms) : 822, 877
. : milestone, 849,
|
Benchmarks Report for tracer 🐌Benchmarks for #6686 compared to master:
The following thresholds were used for comparing the benchmark speeds:
Allocation changes below 0.5% are ignored. Benchmark detailsBenchmarks.Trace.ActivityBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.AgentWriterBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.AspNetCoreBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark - Same speed ✔️ Fewer allocations 🎉
|
Benchmark | Base Allocated | Diff Allocated | Change | Change % |
---|---|---|---|---|
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net6.0 | 41.87 KB | 41.55 KB | -317 B | -0.76% |
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | WriteAndFlushEnrichedTraces |
net6.0 | 608μs | 3.32μs | 18.8μs | 0.604 | 0 | 0 | 41.87 KB |
master | WriteAndFlushEnrichedTraces |
netcoreapp3.1 | 670μs | 3.78μs | 27.5μs | 0.338 | 0 | 0 | 41.69 KB |
master | WriteAndFlushEnrichedTraces |
net472 | 840μs | 2.83μs | 10.6μs | 8.22 | 2.47 | 0.411 | 53.34 KB |
#6686 | WriteAndFlushEnrichedTraces |
net6.0 | 573μs | 3.09μs | 18.3μs | 0.579 | 0 | 0 | 41.55 KB |
#6686 | WriteAndFlushEnrichedTraces |
netcoreapp3.1 | 643μs | 2.24μs | 8.39μs | 0.324 | 0 | 0 | 41.76 KB |
#6686 | WriteAndFlushEnrichedTraces |
net472 | 885μs | 4.17μs | 17.2μs | 8.62 | 2.59 | 0.431 | 53.3 KB |
Benchmarks.Trace.DbCommandBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | ExecuteNonQuery |
net6.0 | 1.44μs | 2.09ns | 8.1ns | 0.0138 | 0 | 0 | 1.02 KB |
master | ExecuteNonQuery |
netcoreapp3.1 | 1.75μs | 2.38ns | 9.22ns | 0.0139 | 0 | 0 | 1.02 KB |
master | ExecuteNonQuery |
net472 | 2.07μs | 4.15ns | 16.1ns | 0.156 | 0.00103 | 0 | 987 B |
#6686 | ExecuteNonQuery |
net6.0 | 1.32μs | 1.26ns | 4.88ns | 0.0144 | 0 | 0 | 1.02 KB |
#6686 | ExecuteNonQuery |
netcoreapp3.1 | 1.84μs | 1.58ns | 6.11ns | 0.0138 | 0 | 0 | 1.02 KB |
#6686 | ExecuteNonQuery |
net472 | 2.1μs | 2.1ns | 8.13ns | 0.156 | 0.00106 | 0 | 987 B |
Benchmarks.Trace.ElasticsearchBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | CallElasticsearch |
net6.0 | 1.21μs | 0.404ns | 1.51ns | 0.0139 | 0 | 0 | 976 B |
master | CallElasticsearch |
netcoreapp3.1 | 1.5μs | 0.958ns | 3.59ns | 0.0128 | 0 | 0 | 976 B |
master | CallElasticsearch |
net472 | 2.46μs | 2.36ns | 9.14ns | 0.158 | 0 | 0 | 995 B |
master | CallElasticsearchAsync |
net6.0 | 1.37μs | 1.01ns | 3.76ns | 0.013 | 0 | 0 | 952 B |
master | CallElasticsearchAsync |
netcoreapp3.1 | 1.71μs | 0.965ns | 3.61ns | 0.0139 | 0 | 0 | 1.02 KB |
master | CallElasticsearchAsync |
net472 | 2.67μs | 1.97ns | 7.63ns | 0.166 | 0 | 0 | 1.05 KB |
#6686 | CallElasticsearch |
net6.0 | 1.12μs | 2.02ns | 7.81ns | 0.0133 | 0 | 0 | 976 B |
#6686 | CallElasticsearch |
netcoreapp3.1 | 1.57μs | 1.32ns | 4.96ns | 0.0134 | 0 | 0 | 976 B |
#6686 | CallElasticsearch |
net472 | 2.48μs | 1.8ns | 6.98ns | 0.157 | 0 | 0 | 995 B |
#6686 | CallElasticsearchAsync |
net6.0 | 1.31μs | 0.64ns | 2.48ns | 0.0131 | 0 | 0 | 952 B |
#6686 | CallElasticsearchAsync |
netcoreapp3.1 | 1.71μs | 1.21ns | 4.7ns | 0.0137 | 0 | 0 | 1.02 KB |
#6686 | CallElasticsearchAsync |
net472 | 2.63μs | 1.96ns | 7.6ns | 0.166 | 0 | 0 | 1.05 KB |
Benchmarks.Trace.GraphQLBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | ExecuteAsync |
net6.0 | 1.44μs | 1.02ns | 3.96ns | 0.013 | 0 | 0 | 952 B |
master | ExecuteAsync |
netcoreapp3.1 | 1.71μs | 0.954ns | 3.7ns | 0.012 | 0 | 0 | 952 B |
master | ExecuteAsync |
net472 | 1.86μs | 0.559ns | 2.09ns | 0.145 | 0 | 0 | 915 B |
#6686 | ExecuteAsync |
net6.0 | 1.39μs | 0.473ns | 1.77ns | 0.0131 | 0 | 0 | 952 B |
#6686 | ExecuteAsync |
netcoreapp3.1 | 1.68μs | 0.328ns | 1.14ns | 0.0126 | 0 | 0 | 952 B |
#6686 | ExecuteAsync |
net472 | 1.9μs | 0.989ns | 3.83ns | 0.145 | 0 | 0 | 915 B |
Benchmarks.Trace.HttpClientBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | SendAsync |
net6.0 | 4.41μs | 1.19ns | 4.47ns | 0.0331 | 0 | 0 | 2.31 KB |
master | SendAsync |
netcoreapp3.1 | 5.35μs | 3.47ns | 13ns | 0.0374 | 0 | 0 | 2.85 KB |
master | SendAsync |
net472 | 7.37μs | 2.03ns | 7.85ns | 0.495 | 0 | 0 | 3.12 KB |
#6686 | SendAsync |
net6.0 | 4.63μs | 1.85ns | 6.92ns | 0.0324 | 0 | 0 | 2.31 KB |
#6686 | SendAsync |
netcoreapp3.1 | 5.37μs | 4.82ns | 17.4ns | 0.0374 | 0 | 0 | 2.85 KB |
#6686 | SendAsync |
net472 | 7.41μs | 2.95ns | 11ns | 0.495 | 0 | 0 | 3.12 KB |
Benchmarks.Trace.ILoggerBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | EnrichedLog |
net6.0 | 1.58μs | 0.493ns | 1.78ns | 0.023 | 0 | 0 | 1.64 KB |
master | EnrichedLog |
netcoreapp3.1 | 2.19μs | 1.07ns | 3.99ns | 0.0228 | 0 | 0 | 1.64 KB |
master | EnrichedLog |
net472 | 2.67μs | 4.35ns | 16.9ns | 0.25 | 0 | 0 | 1.57 KB |
#6686 | EnrichedLog |
net6.0 | 1.62μs | 1.07ns | 4ns | 0.0229 | 0 | 0 | 1.64 KB |
#6686 | EnrichedLog |
netcoreapp3.1 | 2.18μs | 2.16ns | 8.37ns | 0.0219 | 0 | 0 | 1.64 KB |
#6686 | EnrichedLog |
net472 | 2.55μs | 1.03ns | 3.7ns | 0.25 | 0 | 0 | 1.57 KB |
Benchmarks.Trace.Log4netBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | EnrichedLog |
net6.0 | 112μs | 212ns | 822ns | 0.0558 | 0 | 0 | 4.28 KB |
master | EnrichedLog |
netcoreapp3.1 | 117μs | 148ns | 573ns | 0.0582 | 0 | 0 | 4.28 KB |
master | EnrichedLog |
net472 | 151μs | 82.1ns | 307ns | 0.681 | 0.227 | 0 | 4.46 KB |
#6686 | EnrichedLog |
net6.0 | 114μs | 123ns | 445ns | 0.0566 | 0 | 0 | 4.28 KB |
#6686 | EnrichedLog |
netcoreapp3.1 | 120μs | 337ns | 1.31μs | 0 | 0 | 0 | 4.28 KB |
#6686 | EnrichedLog |
net472 | 150μs | 228ns | 852ns | 0.672 | 0.224 | 0 | 4.46 KB |
Benchmarks.Trace.NLogBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | EnrichedLog |
net6.0 | 3.11μs | 0.496ns | 1.72ns | 0.0311 | 0 | 0 | 2.2 KB |
master | EnrichedLog |
netcoreapp3.1 | 4.2μs | 2.35ns | 8.79ns | 0.0294 | 0 | 0 | 2.2 KB |
master | EnrichedLog |
net472 | 5.03μs | 1.01ns | 3.79ns | 0.32 | 0 | 0 | 2.02 KB |
#6686 | EnrichedLog |
net6.0 | 3.03μs | 0.709ns | 2.65ns | 0.0305 | 0 | 0 | 2.2 KB |
#6686 | EnrichedLog |
netcoreapp3.1 | 4.25μs | 3.1ns | 12ns | 0.0296 | 0 | 0 | 2.2 KB |
#6686 | EnrichedLog |
net472 | 4.8μs | 1.66ns | 6.21ns | 0.32 | 0 | 0 | 2.02 KB |
Benchmarks.Trace.RedisBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | SendReceive |
net6.0 | 1.27μs | 0.38ns | 1.47ns | 0.0159 | 0 | 0 | 1.14 KB |
master | SendReceive |
netcoreapp3.1 | 1.77μs | 0.486ns | 1.68ns | 0.015 | 0 | 0 | 1.14 KB |
master | SendReceive |
net472 | 2.12μs | 2.85ns | 11.1ns | 0.183 | 0 | 0 | 1.16 KB |
#6686 | SendReceive |
net6.0 | 1.32μs | 0.983ns | 3.68ns | 0.0157 | 0 | 0 | 1.14 KB |
#6686 | SendReceive |
netcoreapp3.1 | 1.8μs | 0.937ns | 3.51ns | 0.0149 | 0 | 0 | 1.14 KB |
#6686 | SendReceive |
net472 | 1.95μs | 0.946ns | 3.54ns | 0.183 | 0 | 0 | 1.16 KB |
Benchmarks.Trace.SerilogBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | EnrichedLog |
net6.0 | 2.77μs | 1.19ns | 4.44ns | 0.022 | 0 | 0 | 1.6 KB |
master | EnrichedLog |
netcoreapp3.1 | 3.97μs | 5.6ns | 20.9ns | 0.0217 | 0 | 0 | 1.65 KB |
master | EnrichedLog |
net472 | 4.3μs | 3.26ns | 12.6ns | 0.323 | 0 | 0 | 2.04 KB |
#6686 | EnrichedLog |
net6.0 | 2.72μs | 0.964ns | 3.74ns | 0.0218 | 0 | 0 | 1.6 KB |
#6686 | EnrichedLog |
netcoreapp3.1 | 3.95μs | 1.68ns | 6.3ns | 0.0216 | 0 | 0 | 1.65 KB |
#6686 | EnrichedLog |
net472 | 4.2μs | 2.83ns | 10.6ns | 0.323 | 0 | 0 | 2.04 KB |
Benchmarks.Trace.SpanBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | StartFinishSpan |
net6.0 | 391ns | 0.461ns | 1.79ns | 0.00817 | 0 | 0 | 576 B |
master | StartFinishSpan |
netcoreapp3.1 | 557ns | 0.82ns | 3.18ns | 0.00784 | 0 | 0 | 576 B |
master | StartFinishSpan |
net472 | 584ns | 1.27ns | 4.91ns | 0.0915 | 0 | 0 | 578 B |
master | StartFinishScope |
net6.0 | 515ns | 0.487ns | 1.89ns | 0.00983 | 0 | 0 | 696 B |
master | StartFinishScope |
netcoreapp3.1 | 742ns | 1.68ns | 6.07ns | 0.00932 | 0 | 0 | 696 B |
master | StartFinishScope |
net472 | 839ns | 2.27ns | 8.78ns | 0.105 | 0 | 0 | 658 B |
#6686 | StartFinishSpan |
net6.0 | 387ns | 0.591ns | 2.29ns | 0.00813 | 0 | 0 | 576 B |
#6686 | StartFinishSpan |
netcoreapp3.1 | 575ns | 1.86ns | 6.97ns | 0.00766 | 0 | 0 | 576 B |
#6686 | StartFinishSpan |
net472 | 634ns | 1.43ns | 5.55ns | 0.0915 | 0 | 0 | 578 B |
#6686 | StartFinishScope |
net6.0 | 479ns | 0.723ns | 2.8ns | 0.00983 | 0 | 0 | 696 B |
#6686 | StartFinishScope |
netcoreapp3.1 | 816ns | 1.82ns | 7.06ns | 0.00953 | 0 | 0 | 696 B |
#6686 | StartFinishScope |
net472 | 806ns | 1.91ns | 7.42ns | 0.104 | 0 | 0 | 658 B |
Benchmarks.Trace.TraceAnnotationsBenchmark - Faster 🎉 Same allocations ✔️
Faster 🎉 in #6686
Benchmark
base/diff
Base Median (ns)
Diff Median (ns)
Modality
Benchmarks.Trace.TraceAnnotationsBenchmark.RunOnMethodBegin‑net6.0
1.136
731.18
643.60
Benchmark | base/diff | Base Median (ns) | Diff Median (ns) | Modality |
---|---|---|---|---|
Benchmarks.Trace.TraceAnnotationsBenchmark.RunOnMethodBegin‑net6.0 | 1.136 | 731.18 | 643.60 |
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | RunOnMethodBegin |
net6.0 | 733ns | 1.3ns | 5.05ns | 0.00951 | 0 | 0 | 696 B |
master | RunOnMethodBegin |
netcoreapp3.1 | 907ns | 1.48ns | 5.73ns | 0.00936 | 0 | 0 | 696 B |
master | RunOnMethodBegin |
net472 | 1.16μs | 1.52ns | 5.88ns | 0.105 | 0 | 0 | 658 B |
#6686 | RunOnMethodBegin |
net6.0 | 643ns | 0.83ns | 3.21ns | 0.00989 | 0 | 0 | 696 B |
#6686 | RunOnMethodBegin |
netcoreapp3.1 | 850ns | 1.2ns | 4.34ns | 0.0091 | 0 | 0 | 696 B |
#6686 | RunOnMethodBegin |
net472 | 1.07μs | 3.54ns | 13.7ns | 0.104 | 0 | 0 | 658 B |
d86b72a
to
eafa170
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still in progress, will finish soon!
namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2; | ||
|
||
[DuckCopy] | ||
internal struct AssemblyInfoExceptionsStruct |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: don't need to add them in now, but I like when we include links to the github types these are duck typing, makes it easier to verify nullability annotations are correct etc + we'll need an explicit link for AOT in the (distant) future
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh man for AOT I probably will need to redo everything to split between versions, 2.x.0 is totally different to 3.[0-7] and different to 3.8.x . That means I'm 80% sure that this ducktype proxy maps with different types for different versions 😬
tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/Testing/MsTestV2/MsTestIntegration.cs
Show resolved
Hide resolved
} | ||
|
||
lock (instance.Instance!) | ||
string? assemblyName; | ||
if (testContext.TryDuckCast<TestContextStruct>(out var context) && context.TestMethod is { AssemblyName: { } contextAssemblyName }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: should the second part of the if
be inside the outer one?
i.e. is there ever a case where we can duck cast as TestContextStruct
, but assembly is null, and so we should also try to duck cast ITestAssemblyInfoWithAssembly
? Or is it either/or with the duck casting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed in a565f84
@@ -83,4 +93,11 @@ internal static CallTargetReturn OnMethodEnd<TTarget>(TTarget instance, Exceptio | |||
private static void EmptyCleanUpMethod() | |||
{ | |||
} | |||
|
|||
#pragma warning disable SA1201 | |||
internal interface ITestAssemblyInfoWithAssembly : ITestAssemblyInfo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any value in deriving from ITestAssemblyInfo
here? You're only accessing the Assembly
- doesn't that mean you're doing more work mapping other members you're never going to use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're totally right! done in a565f84
...ler/AutoInstrumentation/Testing/MsTestV2/TestAssemblyInfoRunAssemblyInitializeIntegration.cs
Show resolved
Hide resolved
...ce/ClrProfiler/AutoInstrumentation/Testing/MsTestV2/TestMethodRunnerExecuteIntegration3_8.cs
Show resolved
Hide resolved
return new CallTargetReturn<TReturn?>(returnValue); | ||
} | ||
|
||
if (returnValue is IList { Count: > 0 } lstResults) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it worth using ICollection
here if all you need is a Count and enumerate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, done in a565f84
if (state.State is StrongBox<MethodInfoCacheItem?> box) | ||
{ | ||
methodInfoCacheItem = box.Value ?? MsTestIntegration.IsTestMethodRunnableThreadLocal.Value; | ||
} | ||
else | ||
{ | ||
methodInfoCacheItem = MsTestIntegration.IsTestMethodRunnableThreadLocal.Value; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this is a little neater? Undecided
if (state.State is StrongBox<MethodInfoCacheItem?> box) | |
{ | |
methodInfoCacheItem = box.Value ?? MsTestIntegration.IsTestMethodRunnableThreadLocal.Value; | |
} | |
else | |
{ | |
methodInfoCacheItem = MsTestIntegration.IsTestMethodRunnableThreadLocal.Value; | |
} | |
if (state.State is StrongBox<MethodInfoCacheItem?> box && box.Value is { } value) | |
{ | |
methodInfoCacheItem = value; | |
} | |
else | |
{ | |
methodInfoCacheItem = MsTestIntegration.IsTestMethodRunnableThreadLocal.Value; | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that, changed in a565f84
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! 💪
// We need to check if the test is failing because a Class initialization error | ||
if (testMethodInfo.Parent?.Instance.TryDuckCast<ClassInfoInitializationExceptionStruct>(out var classInfoInitializationExceptionStruct) == true) | ||
{ | ||
if (classInfoInitializationExceptionStruct.ClassInitializationException is { } classInitializationException && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it expected that duck typing to ClassInfoInitializationExceptionStruct
could succeed, but Exception
is null? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes because here ClassInfoInitializationExceptionStruct
is extracted from a TestClassInfo
so it can have an exception or not. TestClassInfo
has a lot of properties regarding the class of the test method. So here we are just checking if the ClassInitializationException
property inside TestClassInfo
has a value, and use that value as an error in the test.
Summary of changes
This PR adds support for MSTest v3.8.x
Reason for change
These new version changed a lot of internal method signatures that break our instrumentation.
Implementation details
Added the missing classes or code to make it work.
Test coverage
Other details
Ticket: SDTEST-1650