Skip to content

Commit 2bea759

Browse files
committed
Bug fixes
1 parent 8d12353 commit 2bea759

File tree

10 files changed

+112
-20
lines changed

10 files changed

+112
-20
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
2+
using Xunit.Abstractions;
3+
4+
namespace KS.RustAnalyzer.TestAdapter.UnitTests;
5+
6+
public sealed class MessageLogger : IMessageLogger
7+
{
8+
private readonly ITestOutputHelper _output;
9+
10+
public MessageLogger(ITestOutputHelper output)
11+
{
12+
_output = output;
13+
}
14+
15+
public void SendMessage(TestMessageLevel testMessageLevel, string message)
16+
{
17+
_output.WriteLine("{0}: {1}", testMessageLevel, message);
18+
}
19+
}

src/RustAnalyzer.TestAdapter.UnitTests/RustAnalyzer.TestAdapter.UnitTests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,14 @@
5252
<Compile Include="Cargo\ToolChainServiceTests.cs" />
5353
<Compile Include="Cargo\WorkspaceExtensionsTests.cs" />
5454
<Compile Include="Common\EnvironmentExtensionsTests.cs" />
55+
<Compile Include="MessageLogger.cs" />
5556
<Compile Include="SpyFrameworkHandle.cs" />
5657
<Compile Include="SpyTestCaseDiscoverySink.cs" />
5758
<Compile Include="TestExecutorTests.cs" />
5859
<Compile Include="TestDiscovererTests.cs" />
5960
<Compile Include="Common\PathExTests.cs" />
6061
<Compile Include="Properties\AssemblyInfo.cs" />
62+
<Compile Include="TestsWithLogger.cs" />
6163
</ItemGroup>
6264
<ItemGroup>
6365
<None Include="Cargo\TestData\**\*.*">

src/RustAnalyzer.TestAdapter.UnitTests/SpyFrameworkHandle.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
using System;
2+
using System.Collections.Concurrent;
23
using System.Collections.Generic;
34
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
45
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
56
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
7+
using Xunit.Abstractions;
68

79
namespace KS.RustAnalyzer.TestAdapter.UnitTests;
810

911
public class SpyFrameworkHandle : IFrameworkHandle
1012
{
11-
private readonly List<TestResult> _results = new ();
13+
private readonly ConcurrentBag<TestResult> _results = new ();
14+
private readonly ITestOutputHelper _output;
1215

13-
public IReadOnlyList<TestResult> Results => _results;
16+
public SpyFrameworkHandle(ITestOutputHelper output)
17+
{
18+
_output = output;
19+
}
20+
21+
public IReadOnlyCollection<TestResult> Results => _results;
1422

1523
public bool EnableShutdownAfterTestRun { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
1624

@@ -41,5 +49,6 @@ public void RecordStart(TestCase testCase)
4149

4250
public void SendMessage(TestMessageLevel testMessageLevel, string message)
4351
{
52+
_output.WriteLine("{0}: {1}", testMessageLevel, message);
4453
}
4554
}

src/RustAnalyzer.TestAdapter.UnitTests/TestDiscovererTests.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,19 @@
1010
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
1111
using Moq;
1212
using Xunit;
13+
using Xunit.Abstractions;
1314

1415
namespace KS.RustAnalyzer.TestAdapter.UnitTests;
1516

16-
public class TestDiscovererTests
17+
public class TestDiscovererTests : TestsWithLogger
1718
{
1819
private readonly IToolChainService _tcs = new ToolChainService(TestHelpers.TL.T, TestHelpers.TL.L);
1920

21+
public TestDiscovererTests(ITestOutputHelper output)
22+
: base(output)
23+
{
24+
}
25+
2026
[Theory]
2127
[InlineData(@"hello_world", "hello_world_hello_world.rusttests", "dev")] // No tests.
2228
[InlineData(@"hello_library", "hello_lib_libhello_lib.rusttests", "dev")] // Has tests.
@@ -29,7 +35,7 @@ public async Task DiscoverTestsTestsAsync(string workspaceRelRoot, string contai
2935

3036
await _tcs.DoBuildAsync(tps.WorkspacePath, tps.ManifestPath, profile);
3137
var sink = new SpyTestCaseDiscoverySink();
32-
new TestDiscoverer().DiscoverTests(tcPath, Mock.Of<IDiscoveryContext>(), Mock.Of<IMessageLogger>(), sink);
38+
new TestDiscoverer().DiscoverTests(tcPath, Mock.Of<IDiscoveryContext>(), MessageLogger, sink);
3339

3440
var normalizedStr = sink.TestCases
3541
.OrderBy(x => x.FullyQualifiedName).ThenBy(x => x.LineNumber)
@@ -48,7 +54,7 @@ public async Task AdditionalBuildArgsTestsAsync(string workspaceRelRoot, string
4854

4955
await _tcs.DoBuildAsync(tps.WorkspacePath, tps.ManifestPath, profile, additionalBuildArgs: @"--config ""build.rustflags = '--cfg foo'""", additionalTestDiscoveryArguments: "--config\0build.rustflags = '--cfg foo'\0\0");
5056
var sink = new SpyTestCaseDiscoverySink();
51-
new TestDiscoverer().DiscoverTests(tcPath, Mock.Of<IDiscoveryContext>(), Mock.Of<IMessageLogger>(), sink);
57+
new TestDiscoverer().DiscoverTests(tcPath, Mock.Of<IDiscoveryContext>(), MessageLogger, sink);
5258

5359
var normalizedStr = sink.TestCases
5460
.OrderBy(x => x.FullyQualifiedName).ThenBy(x => x.LineNumber)

src/RustAnalyzer.TestAdapter.UnitTests/TestExecutorTests.cs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,19 @@
1212
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
1313
using Moq;
1414
using Xunit;
15+
using Xunit.Abstractions;
1516

1617
namespace KS.RustAnalyzer.TestAdapter.UnitTests;
1718

18-
public class TestExecutorTests
19+
public class TestExecutorTests : TestsWithLogger
1920
{
2021
private readonly IToolChainService _tcs = new ToolChainService(TestHelpers.TL.T, TestHelpers.TL.L);
2122

23+
public TestExecutorTests(ITestOutputHelper output)
24+
: base(output)
25+
{
26+
}
27+
2228
[Theory]
2329
[InlineData(@"hello_world", "hello_world_hello_world.rusttests", "bench")] // No tests.
2430
[InlineData(@"hello_library", "hello_lib_libhello_lib.rusttests", "bench")] // Has tests.
@@ -29,12 +35,11 @@ public async Task RunTestsTestsAsync(string workspaceRelRoot, string containerNa
2935
var tps = workspaceRelRoot.GetTestPaths(profile);
3036
var tcPath = tps.TargetPath + (PathEx)containerName;
3137
await _tcs.DoBuildAsync(tps.WorkspacePath, tps.ManifestPath, profile, additionalTestExecutionArguments: "--exclude-should-panic", testExecutionEnvironment: "ENV_VAR_1=ENV_VAR_1_VALUE\0\0");
32-
new TestDiscoverer().DiscoverTests(tcPath, Mock.Of<IDiscoveryContext>(), Mock.Of<IMessageLogger>(), Mock.Of<ITestCaseDiscoverySink>());
38+
new TestDiscoverer().DiscoverTests(tcPath, Mock.Of<IDiscoveryContext>(), MessageLogger, Mock.Of<ITestCaseDiscoverySink>());
3339

34-
var fh = new SpyFrameworkHandle();
35-
new TestExecutor().RunTests(tcPath, Mock.Of<IRunContext>(), fh);
40+
new TestExecutor().RunTests(tcPath, Mock.Of<IRunContext>(), FrameworkHandle);
3641

37-
var normalizedStr = fh.Results
42+
var normalizedStr = FrameworkHandle.Results
3843
.OrderBy(x => x.TestCase.FullyQualifiedName).ThenBy(x => x.TestCase.LineNumber)
3944
.SerializeAndNormalizeObject();
4045
Approvals.Verify(normalizedStr);
@@ -50,11 +55,10 @@ public async Task RunSelectedTestsFromMultiplePackagesMultipleFilesTestsAsync(st
5055
var testCases = tests.Select(t => t.Split('|')).Select(x => new TestCase { Source = $"{tps.TargetPath + x[0]}{Constants.TestsContainerExtension}", FullyQualifiedName = x[1], });
5156

5257
await _tcs.DoBuildAsync(tps.WorkspacePath, tps.ManifestPath, profile);
53-
new TestDiscoverer().DiscoverTests(testCases.Select(tc => tc.Source), Mock.Of<IDiscoveryContext>(), Mock.Of<IMessageLogger>(), Mock.Of<ITestCaseDiscoverySink>());
58+
new TestDiscoverer().DiscoverTests(testCases.Select(tc => tc.Source), Mock.Of<IDiscoveryContext>(), MessageLogger, Mock.Of<ITestCaseDiscoverySink>());
5459

55-
var fh = new SpyFrameworkHandle();
56-
new TestExecutor().RunTests(testCases, Mock.Of<IRunContext>(), fh);
60+
new TestExecutor().RunTests(testCases, Mock.Of<IRunContext>(), FrameworkHandle);
5761

58-
fh.Results.Select(r => $"{((PathEx)r.TestCase.Source).GetFileNameWithoutExtension()}|{r.DisplayName}").Should().BeEquivalentTo(tests);
62+
FrameworkHandle.Results.Select(r => $"{((PathEx)r.TestCase.Source).GetFileNameWithoutExtension()}|{r.DisplayName}").Should().BeEquivalentTo(tests);
5963
}
6064
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
2+
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
3+
using Xunit.Abstractions;
4+
5+
namespace KS.RustAnalyzer.TestAdapter.UnitTests;
6+
7+
public abstract class TestsWithLogger
8+
{
9+
private readonly ITestOutputHelper _output;
10+
11+
protected TestsWithLogger(ITestOutputHelper output)
12+
{
13+
_output = output;
14+
FrameworkHandle = new SpyFrameworkHandle(_output);
15+
}
16+
17+
protected SpyFrameworkHandle FrameworkHandle { get; private set; }
18+
19+
protected IMessageLogger MessageLogger => new MessageLogger(_output);
20+
}

src/RustAnalyzer.TestAdapter/BaseTestDiscoverer.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
using System;
12
using System.Collections.Generic;
23
using System.Linq;
4+
using System.Reflection;
35
using KS.RustAnalyzer.TestAdapter.Common;
46
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
57
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
@@ -22,4 +24,31 @@ public void DiscoverTests(PathEx source, IDiscoveryContext discoveryContext, IMe
2224
}
2325

2426
public abstract void DiscoverTests(IEnumerable<PathEx> sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink);
27+
28+
protected void SignupForAssemblyResolution(ILogger logger)
29+
{
30+
AppDomain.CurrentDomain.AssemblyResolve +=
31+
new ResolveEventHandler(CurrentDomain_AssemblyResolve(logger));
32+
}
33+
34+
protected Func<object, ResolveEventArgs, Assembly> CurrentDomain_AssemblyResolve(ILogger logger)
35+
{
36+
return (object sender, ResolveEventArgs args) =>
37+
{
38+
logger.WriteLine(@"This is a sign of impending doom. Have been asked by '{0}' to resolve '{1}'.", args.RequestingAssembly.FullName, args.Name);
39+
40+
var name = new AssemblyName(args.Name);
41+
if (name.Name == "System.Diagnostics.DiagnosticSource")
42+
{
43+
return typeof(System.Diagnostics.DiagnosticSource).Assembly;
44+
}
45+
else if (name.Name == "System.Runtime.CompilerServices.Unsafe")
46+
{
47+
return typeof(System.Runtime.CompilerServices.Unsafe).Assembly;
48+
}
49+
50+
logger.WriteError(@"Unable to resolve resolve assembly '{0}'. Behavior unknow from this point on. Please file a bug at https://github.com/kitamstudios/rust-analyzer.vs.", args.Name);
51+
return null;
52+
};
53+
}
2554
}

src/RustAnalyzer.TestAdapter/TestDiscoverer.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public class TestDiscoverer : BaseTestDiscoverer, ITestDiscoverer
2323
public override void DiscoverTests(IEnumerable<PathEx> sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink)
2424
{
2525
var tl = logger.CreateTL();
26+
SignupForAssemblyResolution(tl.L);
27+
2628
var tasks = sources
2729
.GroupBy(s => s)
2830
.Select(async g => await DiscoverAndReportTestsFromOneSource(await g.Key.ReadTestContainerAsync(default), discoverySink, tl, default));

src/RustAnalyzer.TestAdapter/TestExecutor.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,6 @@ private static async Task<IEnumerable<TestResult>> RunTestsFromOneExe(PathEx exe
116116
}
117117

118118
using var testExeProc = await ProcessRunner.RunWithLogging(exe, args, exe.GetDirectoryName(), envDict, ct, tl.L, @throw: false);
119-
var ec = testExeProc.ExitCode ?? 0;
120-
if (ec != 0)
121-
{
122-
tl.L.WriteError("RunTestsFromOneSourceAsync test executable exited with code {0}.", ec);
123-
}
124119

125120
var testCasesMap = testCases.ToImmutableDictionary(x => x.FullyQualifiedNameRustFormat());
126121
var tris = testExeProc.StandardOutputLines
@@ -130,6 +125,12 @@ private static async Task<IEnumerable<TestResult>> RunTestsFromOneExe(PathEx exe
130125
.Where(x => x.Event != TestRunInfo.EventType.Started)
131126
.OrderBy(x => x.FQN)
132127
.Select(x => ToTestResult(exe, x, testCasesMap));
128+
var ec = testExeProc.ExitCode ?? 0;
129+
if (ec != 0 && !tris.Any())
130+
{
131+
tl.L.WriteError("RunTestsFromOneSourceAsync test executable exited with code {0}.", ec);
132+
throw new ApplicationException($"Test executable returned {ec}. Check above for the arguments passed to test executable by running it on the command line.");
133+
}
133134

134135
tl.T.TrackEvent("RunTestsFromOneSourceAsync", ("Results", $"{tris.Count()}"));
135136

src/RustAnalyzer/Infrastructure/Options.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public class Options : BaseOptionModel<Options>, ISettingsServiceDefaults
7777
[Category(SettingsInfo.KindTest)]
7878
[DisplayName("Execution arguments")]
7979
[Description($"Additional arguments passed test executable test in addition to --format json --report-time. Check 'cargo help test' for more information.")]
80-
public string AdditionalTestExecutionArguments { get; set; } = "--exact --show-output --test-threads 1";
80+
public string AdditionalTestExecutionArguments { get; set; } = "--show-output --test-threads 1";
8181

8282
[Browsable(true)]
8383
[Category(SettingsInfo.KindTest)]

0 commit comments

Comments
 (0)