Skip to content

Commit 1efd5e1

Browse files
Handle assemblies loaded via a stream (#1443)
1 parent d076048 commit 1efd5e1

File tree

2 files changed

+74
-3
lines changed

2 files changed

+74
-3
lines changed

src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,13 @@ public CsProjGenerator(string targetFrameworkMoniker, string cliPath, string pac
3535

3636
protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programName)
3737
{
38-
string directoryName = Path.GetDirectoryName(buildPartition.AssemblyLocation)
39-
?? throw new DirectoryNotFoundException(buildPartition.AssemblyLocation);
38+
string assemblyLocation = buildPartition.AssemblyLocation;
39+
40+
//Assembles loaded from a stream will have an empty location (https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.location).
41+
string directoryName = assemblyLocation.IsEmpty() ?
42+
Path.Combine(Directory.GetCurrentDirectory(), "BenchmarkDotNet.Bin") :
43+
Path.GetDirectoryName(buildPartition.AssemblyLocation);
44+
4045
return Path.Combine(directoryName, programName);
4146
}
4247

tests/BenchmarkDotNet.Tests/CsProjGeneratorTests.cs

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
using System.IO;
2+
using System.Linq;
3+
using System.Reflection;
4+
using BenchmarkDotNet.Characteristics;
5+
using BenchmarkDotNet.Configs;
6+
using BenchmarkDotNet.Jobs;
7+
using BenchmarkDotNet.Running;
8+
using BenchmarkDotNet.Tests.Mocks;
29
using BenchmarkDotNet.Toolchains.CsProj;
310
using JetBrains.Annotations;
411
using Xunit;
12+
using BenchmarkDotNet.Extensions;
513

614
namespace BenchmarkDotNet.Tests
715
{
@@ -140,5 +148,63 @@ public void SettingsFromPropsFileImportedUsingRelativePathGetCopies()
140148

141149
File.Delete(propsFilePath);
142150
}
151+
152+
[Fact]
153+
public void TheDefaultFilePathShouldBeUsedWhenAnAssemblyLocationIsEmpty()
154+
{
155+
const string programName = "testProgram";
156+
var config = ManualConfig.CreateEmpty().CreateImmutableConfig();
157+
var benchmarkMethod =
158+
typeof(MockFactory.MockBenchmarkClass)
159+
.GetTypeInfo()
160+
.GetMethods()
161+
.Single(method => method.Name == nameof(MockFactory.MockBenchmarkClass.Foo));
162+
163+
164+
//Simulate loading an assembly from a stream
165+
var benchmarkDotNetAssembly = typeof(MockFactory.MockBenchmarkClass).GetTypeInfo().Assembly;
166+
var streamLoadedAssembly = Assembly.Load(File.ReadAllBytes(benchmarkDotNetAssembly.Location));
167+
var assemblyType = streamLoadedAssembly.GetRunnableBenchmarks().Select(type => type).FirstOrDefault();
168+
169+
var target = new Descriptor(assemblyType, benchmarkMethod);
170+
var benchmarkCase = BenchmarkCase.Create(target, Job.Default, null, config);
171+
172+
var benchmarks = new[] { new BenchmarkBuildInfo(benchmarkCase, config.CreateImmutableConfig(), 999) };
173+
var projectGenerator = new SteamLoadedBuildPartition("netcoreapp3.0", null, null, null);
174+
string binariesPath = projectGenerator.ResolvePathForBinaries(new BuildPartition(benchmarks, new Resolver()), programName);
175+
176+
string expectedPath = Path.Combine(Path.Combine(Directory.GetCurrentDirectory(), "BenchmarkDotNet.Bin"), programName);
177+
Assert.Equal(expectedPath, binariesPath);
178+
}
179+
180+
[Fact]
181+
public void TestAssemblyFilePathIsUsedWhenTheAssemblyLocationIsNotEmpty()
182+
{
183+
const string programName = "testProgram";
184+
var benchmarkMethod =
185+
typeof(MockFactory.MockBenchmarkClass)
186+
.GetTypeInfo()
187+
.GetMethods()
188+
.Single(method => method.Name == nameof(MockFactory.MockBenchmarkClass.Foo));
189+
var target = new Descriptor(typeof(MockFactory.MockBenchmarkClass), benchmarkMethod);
190+
var benchmarkCase = BenchmarkCase.Create(target, Job.Default, null, ManualConfig.CreateEmpty().CreateImmutableConfig());
191+
var benchmarks = new[] { new BenchmarkBuildInfo(benchmarkCase, ManualConfig.CreateEmpty().CreateImmutableConfig(), 0) };
192+
var projectGenerator = new SteamLoadedBuildPartition("netcoreapp3.0", null, null, null);
193+
var buildPartition = new BuildPartition(benchmarks, new Resolver());
194+
string binariesPath = projectGenerator.ResolvePathForBinaries(buildPartition, programName);
195+
196+
string expectedPath = Path.Combine(Path.GetDirectoryName(buildPartition.AssemblyLocation), programName);
197+
Assert.Equal(expectedPath, binariesPath);
198+
}
199+
200+
private class SteamLoadedBuildPartition : CsProjGenerator
201+
{
202+
internal string ResolvePathForBinaries(BuildPartition buildPartition, string programName)
203+
{
204+
return base.GetBuildArtifactsDirectoryPath(buildPartition, programName);
205+
}
206+
207+
public SteamLoadedBuildPartition(string targetFrameworkMoniker, string cliPath, string packagesPath, string runtimeFrameworkVersion) : base(targetFrameworkMoniker, cliPath, packagesPath, runtimeFrameworkVersion) { }
208+
}
143209
}
144-
}
210+
}

0 commit comments

Comments
 (0)