44using System . Threading ;
55using BenchmarkDotNet . Characteristics ;
66using BenchmarkDotNet . Configs ;
7+ using BenchmarkDotNet . Detectors ;
78using BenchmarkDotNet . Environments ;
89using BenchmarkDotNet . Helpers ;
910using BenchmarkDotNet . Jobs ;
@@ -28,11 +29,7 @@ public BuildPartition(BenchmarkBuildInfo[] benchmarks, IResolver resolver)
2829 Resolver = resolver ;
2930 RepresentativeBenchmarkCase = benchmarks [ 0 ] . BenchmarkCase ;
3031 Benchmarks = benchmarks ;
31- // Combine the benchmark's assembly name, folder info, and build partition id.
32- string benchmarkAssemblyName = RepresentativeBenchmarkCase . Descriptor . Type . Assembly . GetName ( ) . Name ;
33- string folderInfo = RepresentativeBenchmarkCase . Job . FolderInfo ;
34- int id = Interlocked . Increment ( ref s_partitionCounter ) ;
35- ProgramName = $ "{ benchmarkAssemblyName } -{ folderInfo } -{ id } ";
32+ ProgramName = GetProgramName ( RepresentativeBenchmarkCase , Interlocked . Increment ( ref s_partitionCounter ) ) ;
3633 LogBuildOutput = benchmarks [ 0 ] . Config . Options . IsSet ( ConfigOptions . LogBuildOutput ) ;
3734 GenerateMSBuildBinLog = benchmarks [ 0 ] . Config . Options . IsSet ( ConfigOptions . GenerateMSBuildBinLog ) ;
3835 }
@@ -85,6 +82,33 @@ private static string GetResolvedAssemblyLocation(Assembly assembly) =>
8582 // manually construct the path.
8683 assembly . Location . Length == 0 ? Path . Combine ( AppContext . BaseDirectory , assembly . GetName ( ) . Name ) : assembly . Location ;
8784
85+ internal static string GetProgramName ( BenchmarkCase representativeBenchmarkCase , int id )
86+ {
87+ // Combine the benchmark's assembly name, folder info, and build partition id.
88+ string benchmarkAssemblyName = representativeBenchmarkCase . Descriptor . Type . Assembly . GetName ( ) . Name ;
89+ string folderInfo = representativeBenchmarkCase . Job . FolderInfo ;
90+ var programName = $ "{ benchmarkAssemblyName } -{ folderInfo } -{ id } ";
91+ // Very long program name can cause the path to exceed Windows' 260 character limit,
92+ // for example BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.
93+ // 36 is an arbitrary limit, but it's the length of Guid strings which is what was used previously.
94+ const int MaxLength = 36 ;
95+ if ( ! OsDetector . IsWindows ( ) || programName . Length <= MaxLength )
96+ {
97+ return programName ;
98+ }
99+ programName = $ "{ benchmarkAssemblyName } -{ id } ";
100+ if ( programName . Length <= MaxLength )
101+ {
102+ return programName ;
103+ }
104+ programName = $ "{ folderInfo } -{ id } ";
105+ if ( programName . Length <= MaxLength )
106+ {
107+ return programName ;
108+ }
109+ return id . ToString ( ) ;
110+ }
111+
88112 internal bool ForcedNoDependenciesForIntegrationTests
89113 {
90114 get
@@ -100,4 +124,4 @@ internal bool ForcedNoDependenciesForIntegrationTests
100124 }
101125 }
102126 }
103- }
127+ }
0 commit comments