99import java .nio .file .Path ;
1010import java .nio .file .Paths ;
1111import java .time .Duration ;
12+ import java .util .regex .Matcher ;
13+ import java .util .regex .Pattern ;
1214import java .util .stream .Stream ;
1315import org .junit .jupiter .api .AfterAll ;
1416import org .junit .jupiter .api .BeforeAll ;
1820import org .junit .jupiter .params .provider .MethodSource ;
1921import org .slf4j .Logger ;
2022import org .slf4j .LoggerFactory ;
23+ import org .testcontainers .containers .Container .ExecResult ;
2124import org .testcontainers .containers .GenericContainer ;
2225import org .testcontainers .utility .DockerImageName ;
2326
2629 * build ID extraction from real ELF (Unix/Linux) and PE (Windows) binaries.
2730 */
2831public class BuildIdExtractorIntegrationTest {
32+ private static final String DOTNET_SDK_MAJOR_VERSION = "8.0" ;
2933 private static GenericContainer <?> linuxContainer ;
3034 private static GenericContainer <?> dotnetContainer ;
3135 @ TempDir private static Path tempDir ;
3236 private static final Logger logger =
3337 LoggerFactory .getLogger (BuildIdExtractorIntegrationTest .class );
38+ private static String dotnetVersion ;
3439
3540 @ BeforeAll
3641 static void startContainers () throws IOException {
@@ -40,20 +45,51 @@ static void startContainers() throws IOException {
4045 new GenericContainer <>(
4146 DockerImageName .parse ("ubuntu:22.04" ).asCompatibleSubstituteFor ("ubuntu" ))
4247 .withCommand ("sleep" , "infinity" )
43- .withStartupTimeout (Duration .ofMinutes (2 ))
44- .withCreateContainerCmdModifier (cmd -> cmd .withPlatform ("linux/amd64" ));
48+ .withStartupTimeout (Duration .ofMinutes (2 ));
4549 linuxContainer .start ();
4650
4751 // Start dotnet SDK container for PE testing
4852 // Use linux/amd64 platform to ensure consistent binary format
4953 dotnetContainer =
5054 new GenericContainer <>(
51- DockerImageName .parse ("mcr.microsoft.com/dotnet/sdk:8.0" )
55+ DockerImageName .parse ("mcr.microsoft.com/dotnet/sdk:" + DOTNET_SDK_MAJOR_VERSION )
5256 .asCompatibleSubstituteFor ("dotnet" ))
5357 .withCommand ("sleep" , "infinity" )
54- .withStartupTimeout (Duration .ofMinutes (2 ))
55- .withCreateContainerCmdModifier (cmd -> cmd .withPlatform ("linux/amd64" ));
58+ .withStartupTimeout (Duration .ofMinutes (2 ));
5659 dotnetContainer .start ();
60+
61+ dotnetVersion = discoverExactDotnetVersionFrom (dotnetContainer );
62+ }
63+
64+ /**
65+ * Discovers the .NET Core runtime version installed in the container by listing available
66+ * versions.
67+ *
68+ * @param dotnetContainer the dotNet SDK container
69+ * @return the discovered .NET version string
70+ */
71+ private static String discoverExactDotnetVersionFrom (GenericContainer <?> dotnetContainer )
72+ throws IOException {
73+ try {
74+ ExecResult execResult =
75+ dotnetContainer .execInContainer ("ls" , "/usr/share/dotnet/shared/Microsoft.NETCore.App" );
76+ if (execResult .getExitCode () == 0 ) {
77+ Pattern pattern =
78+ Pattern .compile (
79+ "^" + Pattern .quote (DOTNET_SDK_MAJOR_VERSION ) + "\\ .\\ d+$" , Pattern .MULTILINE );
80+ Matcher matcher = pattern .matcher (execResult .getStdout ());
81+ if (matcher .find ()) {
82+ return matcher .group ();
83+ }
84+ throw new IOException (
85+ "No .NET " + DOTNET_SDK_MAJOR_VERSION + " version found in container" );
86+ }
87+ } catch (InterruptedException e ) {
88+ Thread .currentThread ().interrupt ();
89+ throw new IOException ("Interrupted while discovering .NET version" , e );
90+ }
91+
92+ throw new IOException ("Failed to list .NET versions in container" );
5793 }
5894
5995 @ AfterAll
@@ -113,19 +149,12 @@ void testElfBuildIdExtraction(String containerPath, String description) throws E
113149 }
114150
115151 private static Stream <Arguments > peBinaries () {
152+ String basePath = "/usr/share/dotnet/shared/Microsoft.NETCore.App/" + dotnetVersion ;
116153 return Stream .of (
117- Arguments .of (
118- "/usr/share/dotnet/shared/Microsoft.NETCore.App/8.0.24/System.Private.CoreLib.dll" ,
119- "Core .NET Library" ),
120- Arguments .of (
121- "/usr/share/dotnet/shared/Microsoft.NETCore.App/8.0.24/System.Runtime.dll" ,
122- ".NET Runtime" ),
123- Arguments .of (
124- "/usr/share/dotnet/shared/Microsoft.NETCore.App/8.0.24/System.Console.dll" ,
125- "Console Library" ),
126- Arguments .of (
127- "/usr/share/dotnet/shared/Microsoft.NETCore.App/8.0.24/Microsoft.CSharp.dll" ,
128- "C# Compiler Library" ));
154+ Arguments .of (basePath + "/System.Private.CoreLib.dll" , "Core .NET Library" ),
155+ Arguments .of (basePath + "/System.Runtime.dll" , ".NET Runtime" ),
156+ Arguments .of (basePath + "/System.Console.dll" , "Console Library" ),
157+ Arguments .of (basePath + "/Microsoft.CSharp.dll" , "C# Compiler Library" ));
129158 }
130159
131160 @ ParameterizedTest (name = "PE: {1}" )
0 commit comments