Skip to content

Commit 63b528a

Browse files
authored
chore: Discover dotNet version dynamically in the SDK image (#10569)
chore: Discover dotNet version dynamically in the SDK image Also, relax the constraint of 'linux/amd64' platform. Allowing to run on macOs. Indeed both ubuntu: 22.04 and mcr.microsoft.com/dotnet/sdk:8.0 have a linux/arm64 variant. * https://hub.docker.com/_/ubuntu/tags?name=22.04 * https://mcr.microsoft.com/artifact/mar/dotnet/sdk/tags Co-authored-by: brice.dutheil <brice.dutheil@datadoghq.com>
1 parent 20f91ec commit 63b528a

File tree

1 file changed

+46
-17
lines changed

1 file changed

+46
-17
lines changed

dd-java-agent/agent-crashtracking/src/test/java/datadog/crashtracking/buildid/BuildIdExtractorIntegrationTest.java

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import java.nio.file.Path;
1010
import java.nio.file.Paths;
1111
import java.time.Duration;
12+
import java.util.regex.Matcher;
13+
import java.util.regex.Pattern;
1214
import java.util.stream.Stream;
1315
import org.junit.jupiter.api.AfterAll;
1416
import org.junit.jupiter.api.BeforeAll;
@@ -18,6 +20,7 @@
1820
import org.junit.jupiter.params.provider.MethodSource;
1921
import org.slf4j.Logger;
2022
import org.slf4j.LoggerFactory;
23+
import org.testcontainers.containers.Container.ExecResult;
2124
import org.testcontainers.containers.GenericContainer;
2225
import org.testcontainers.utility.DockerImageName;
2326

@@ -26,11 +29,13 @@
2629
* build ID extraction from real ELF (Unix/Linux) and PE (Windows) binaries.
2730
*/
2831
public 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

Comments
 (0)