diff --git a/src/BenchmarkDotNet/Running/BuildPartition.cs b/src/BenchmarkDotNet/Running/BuildPartition.cs index d7fb9bc8a8..8fd058df63 100644 --- a/src/BenchmarkDotNet/Running/BuildPartition.cs +++ b/src/BenchmarkDotNet/Running/BuildPartition.cs @@ -4,6 +4,7 @@ using System.Threading; using BenchmarkDotNet.Characteristics; using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Detectors; using BenchmarkDotNet.Environments; using BenchmarkDotNet.Helpers; using BenchmarkDotNet.Jobs; @@ -28,11 +29,7 @@ public BuildPartition(BenchmarkBuildInfo[] benchmarks, IResolver resolver) Resolver = resolver; RepresentativeBenchmarkCase = benchmarks[0].BenchmarkCase; Benchmarks = benchmarks; - // Combine the benchmark's assembly name, folder info, and build partition id. - string benchmarkAssemblyName = RepresentativeBenchmarkCase.Descriptor.Type.Assembly.GetName().Name; - string folderInfo = RepresentativeBenchmarkCase.Job.FolderInfo; - int id = Interlocked.Increment(ref s_partitionCounter); - ProgramName = $"{benchmarkAssemblyName}-{folderInfo}-{id}"; + ProgramName = GetProgramName(RepresentativeBenchmarkCase, Interlocked.Increment(ref s_partitionCounter)); LogBuildOutput = benchmarks[0].Config.Options.IsSet(ConfigOptions.LogBuildOutput); GenerateMSBuildBinLog = benchmarks[0].Config.Options.IsSet(ConfigOptions.GenerateMSBuildBinLog); } @@ -85,6 +82,32 @@ private static string GetResolvedAssemblyLocation(Assembly assembly) => // manually construct the path. assembly.Location.Length == 0 ? Path.Combine(AppContext.BaseDirectory, assembly.GetName().Name) : assembly.Location; + internal static string GetProgramName(BenchmarkCase representativeBenchmarkCase, int id) + { + // Combine the benchmark's assembly name, folder info, and build partition id. + string benchmarkAssemblyName = representativeBenchmarkCase.Descriptor.Type.Assembly.GetName().Name; + string folderInfo = representativeBenchmarkCase.Job.FolderInfo; + var programName = $"{benchmarkAssemblyName}-{folderInfo}-{id}"; + // Very long program name can cause the path to exceed Windows' 260 character limit, + // for example BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks. + // 36 is an arbitrary limit, but it's the length of Guid strings which is what was used previously. + if (!OsDetector.IsWindows() || programName.Length <= 36) + { + return programName; + } + programName = $"{benchmarkAssemblyName}-{id}"; + if (programName.Length <= 36) + { + return programName; + } + programName = $"{folderInfo}-{id}"; + if (programName.Length <= 36) + { + return programName; + } + return id.ToString(); + } + internal bool ForcedNoDependenciesForIntegrationTests { get diff --git a/tests/BenchmarkDotNet.IntegrationTests/InProcessEmitTest.cs b/tests/BenchmarkDotNet.IntegrationTests/InProcessEmitTest.cs index 76a665d4de..aa8b12fa03 100644 --- a/tests/BenchmarkDotNet.IntegrationTests/InProcessEmitTest.cs +++ b/tests/BenchmarkDotNet.IntegrationTests/InProcessEmitTest.cs @@ -70,12 +70,11 @@ private void DiffEmit(Summary summary) return; var benchmarkCase = summary.BenchmarksCases.First(); - var caseName = $"{benchmarkCase.Descriptor.Type.Assembly.GetName().Name}-{benchmarkCase.Job.FolderInfo}"; // The benchmark config built jobs with 2 toolchains, 1 InProcessEmit and 1 Roslyn, // so we need to subtract 1 from the partition counter to obtain the emit output. NaiveRunnableEmitDiff.RunDiff( - $@"{caseName}-{BuildPartition.s_partitionCounter}.exe", - $@"{caseName}-{BuildPartition.s_partitionCounter - 1}Emitted.dll", + $@"{BuildPartition.GetProgramName(benchmarkCase, BuildPartition.s_partitionCounter)}.exe", + $@"{BuildPartition.GetProgramName(benchmarkCase, BuildPartition.s_partitionCounter - 1)}Emitted.dll", ConsoleLogger.Default); }