Skip to content

Commit 0d23385

Browse files
Add Android/Robolectric visibility to Test Optimization spans (#11852)
feat: tag Robolectric test spans with emulated Android SDK metadata feat: add is_android_emulated telemetry test: add Robolectric Gradle smoke-test scenario nit: comments Co-authored-by: daniel.mohedano <daniel.mohedano@datadoghq.com>
1 parent dfc9070 commit 0d23385

18 files changed

Lines changed: 1026 additions & 2 deletions

File tree

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
/dd-java-agent/instrumentation/jacoco-0.8.9/ @DataDog/ci-app-libraries
112112
/dd-java-agent/instrumentation/junit @DataDog/ci-app-libraries
113113
/dd-java-agent/instrumentation/karate-1.0/ @DataDog/ci-app-libraries
114+
/dd-java-agent/instrumentation/robolectric-4.13/ @DataDog/ci-app-libraries
114115
/dd-java-agent/instrumentation/scalatest-3.0.8/ @DataDog/ci-app-libraries
115116
/dd-java-agent/instrumentation/selenium-3.13/ @DataDog/ci-app-libraries
116117
/dd-java-agent/instrumentation/testng/ @DataDog/ci-app-libraries

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/TestImpl.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import datadog.trace.api.civisibility.telemetry.tag.EventType;
2323
import datadog.trace.api.civisibility.telemetry.tag.FailedTestReplayEnabled;
2424
import datadog.trace.api.civisibility.telemetry.tag.HasFailedAllRetries;
25+
import datadog.trace.api.civisibility.telemetry.tag.IsAndroidEmulated;
2526
import datadog.trace.api.civisibility.telemetry.tag.IsAttemptToFix;
2627
import datadog.trace.api.civisibility.telemetry.tag.IsDisabled;
2728
import datadog.trace.api.civisibility.telemetry.tag.IsModified;
@@ -323,7 +324,8 @@ public void end(@Nullable Long endTime) {
323324
span.getTag(Tags.TEST_IS_RUM_ACTIVE) != null ? IsRum.TRUE : null,
324325
CIConstants.SELENIUM_BROWSER_DRIVER.equals(span.getTag(Tags.TEST_BROWSER_DRIVER))
325326
? BrowserDriver.SELENIUM
326-
: null);
327+
: null,
328+
span.getTag(Tags.TEST_ANDROID_API_LEVEL) != null ? IsAndroidEmulated.TRUE : null);
327329
}
328330

329331
/**
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
muzzle {
2+
extraRepository('google', 'https://maven.google.com')
3+
pass {
4+
group = 'org.robolectric'
5+
module = 'robolectric'
6+
versions = '[4.13,)'
7+
// androidx.test:monitor is an Android archive (.aar) that a JVM configuration cannot consume;
8+
// it is not referenced by the advice/helper. Mirror the compileOnly exclusion below.
9+
excludeDependency 'androidx.test:monitor'
10+
}
11+
}
12+
13+
apply from: "$rootDir/gradle/java.gradle"
14+
15+
repositories {
16+
// Robolectric drags in androidx.test.* transitive dependencies that are published only to
17+
// Google's Maven. Declared after java.gradle so Maven Central is tried first
18+
maven {
19+
url = 'https://maven.google.com'
20+
content {
21+
includeGroupAndSubgroups 'androidx'
22+
}
23+
}
24+
}
25+
26+
dependencies {
27+
// Instrumentation is validated through a scenario in `GradleDaemonSmokeTest`.
28+
// Exclude androidx.test:monitor: it is an Android archive (.aar) published only to Google's Maven
29+
// repository, is not referenced by the advice/helper.
30+
compileOnly(group: 'org.robolectric', name: 'robolectric', version: '4.16.1') {
31+
exclude group: 'androidx.test', module: 'monitor'
32+
}
33+
// RobolectricTestRunner extends JUnit's BlockJUnit4ClassRunner; JUnit must be on the compile
34+
// classpath so its supertypes resolve (both javac and forbiddenApis walk the class hierarchy).
35+
compileOnly group: 'junit', name: 'junit', version: '4.13.2'
36+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# This is a Gradle generated file for dependency locking.
2+
# Manual edits can break the build and are not advised.
3+
# This file is expected to be part of source control.
4+
# To regenerate this file, run: ./gradlew :dd-java-agent:instrumentation:robolectric-4.13:dependencies --write-locks
5+
cafe.cryptography:curve25519-elisabeth:0.1.0=testRuntimeClasspath
6+
cafe.cryptography:ed25519-elisabeth:0.1.0=testRuntimeClasspath
7+
ch.qos.logback:logback-classic:1.2.13=testCompileClasspath,testRuntimeClasspath
8+
ch.qos.logback:logback-core:1.2.13=testCompileClasspath,testRuntimeClasspath
9+
com.almworks.sqlite4java:sqlite4java:1.0.392=compileClasspath
10+
com.blogspot.mydailyjava:weak-lock-free:0.17=buildTimeInstrumentationPlugin,compileClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
11+
com.datadoghq.okhttp3:okhttp:3.12.15=testCompileClasspath,testRuntimeClasspath
12+
com.datadoghq.okio:okio:1.17.6=testCompileClasspath,testRuntimeClasspath
13+
com.datadoghq:dd-instrument-java:0.0.4=buildTimeInstrumentationPlugin,compileClasspath,muzzleBootstrap,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
14+
com.datadoghq:dd-javac-plugin-client:0.2.2=buildTimeInstrumentationPlugin,compileClasspath,muzzleBootstrap,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
15+
com.datadoghq:java-dogstatsd-client:4.4.5=testRuntimeClasspath
16+
com.datadoghq:sketches-java:0.8.3=testRuntimeClasspath
17+
com.github.javaparser:javaparser-core:3.25.6=codenarc
18+
com.github.jnr:jffi:1.3.15=testRuntimeClasspath
19+
com.github.jnr:jnr-a64asm:1.0.0=testRuntimeClasspath
20+
com.github.jnr:jnr-constants:0.10.4=testRuntimeClasspath
21+
com.github.jnr:jnr-enxio:0.32.20=testRuntimeClasspath
22+
com.github.jnr:jnr-ffi:2.2.19=testRuntimeClasspath
23+
com.github.jnr:jnr-posix:3.1.22=testRuntimeClasspath
24+
com.github.jnr:jnr-unixsocket:0.38.25=testRuntimeClasspath
25+
com.github.jnr:jnr-x86asm:1.0.2=testRuntimeClasspath
26+
com.github.spotbugs:spotbugs-annotations:4.9.8=compileClasspath,spotbugs
27+
com.github.spotbugs:spotbugs:4.9.8=spotbugs
28+
com.github.stephenc.jcip:jcip-annotations:1.0-1=spotbugs
29+
com.google.auto.service:auto-service-annotations:1.1.1=annotationProcessor,compileClasspath,testAnnotationProcessor,testCompileClasspath
30+
com.google.auto.service:auto-service:1.1.1=annotationProcessor,testAnnotationProcessor
31+
com.google.auto.value:auto-value-annotations:1.11.0=compileClasspath
32+
com.google.auto:auto-common:1.2.1=annotationProcessor,testAnnotationProcessor
33+
com.google.code.findbugs:jsr305:3.0.2=annotationProcessor,compileClasspath,spotbugs,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
34+
com.google.code.gson:gson:2.13.2=spotbugs
35+
com.google.errorprone:error_prone_annotations:2.18.0=annotationProcessor,testAnnotationProcessor
36+
com.google.errorprone:error_prone_annotations:2.36.0=compileClasspath
37+
com.google.errorprone:error_prone_annotations:2.41.0=spotbugs
38+
com.google.errorprone:error_prone_annotations:2.47.0=testCompileClasspath,testRuntimeClasspath
39+
com.google.guava:failureaccess:1.0.1=annotationProcessor,testAnnotationProcessor
40+
com.google.guava:failureaccess:1.0.3=compileClasspath,testCompileClasspath,testRuntimeClasspath
41+
com.google.guava:guava:32.0.1-jre=annotationProcessor,testAnnotationProcessor
42+
com.google.guava:guava:33.4.8-jre=compileClasspath
43+
com.google.guava:guava:33.6.0-jre=testCompileClasspath,testRuntimeClasspath
44+
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=annotationProcessor,compileClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
45+
com.google.j2objc:j2objc-annotations:2.8=annotationProcessor,testAnnotationProcessor
46+
com.google.j2objc:j2objc-annotations:3.0.0=compileClasspath
47+
com.google.j2objc:j2objc-annotations:3.1=testCompileClasspath,testRuntimeClasspath
48+
com.google.re2j:re2j:1.8=testRuntimeClasspath
49+
com.ibm.icu:icu4j:77.1=compileClasspath
50+
com.squareup.moshi:moshi:1.11.0=testCompileClasspath,testRuntimeClasspath
51+
com.squareup.okhttp3:logging-interceptor:3.12.12=testCompileClasspath,testRuntimeClasspath
52+
com.squareup.okhttp3:okhttp:3.12.12=testCompileClasspath,testRuntimeClasspath
53+
com.squareup.okio:okio:1.17.5=testCompileClasspath,testRuntimeClasspath
54+
com.thoughtworks.qdox:qdox:1.12.1=codenarc
55+
commons-fileupload:commons-fileupload:1.5=testCompileClasspath,testRuntimeClasspath
56+
commons-io:commons-io:2.11.0=testCompileClasspath,testRuntimeClasspath
57+
commons-io:commons-io:2.20.0=spotbugs
58+
de.thetaphi:forbiddenapis:3.10=compileClasspath,testCompileClasspath,testRuntimeClasspath
59+
io.leangen.geantyref:geantyref:1.3.16=testRuntimeClasspath
60+
io.sqreen:libsqreen:17.3.0=testRuntimeClasspath
61+
javax.annotation:javax.annotation-api:1.3.2=compileClasspath
62+
javax.inject:javax.inject:1=compileClasspath
63+
javax.servlet:javax.servlet-api:3.1.0=testCompileClasspath,testRuntimeClasspath
64+
jaxen:jaxen:2.0.0=spotbugs
65+
junit:junit:4.13.2=compileClasspath,testRuntimeClasspath
66+
net.bytebuddy:byte-buddy-agent:1.18.10=buildTimeInstrumentationPlugin,compileClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
67+
net.bytebuddy:byte-buddy:1.18.10=buildTimeInstrumentationPlugin,compileClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
68+
net.java.dev.jna:jna-platform:5.8.0=testRuntimeClasspath
69+
net.java.dev.jna:jna:5.8.0=testRuntimeClasspath
70+
net.sf.saxon:Saxon-HE:12.9=spotbugs
71+
org.apache.ant:ant-antlr:1.10.14=codenarc
72+
org.apache.ant:ant-junit:1.10.14=codenarc
73+
org.apache.bcel:bcel:6.11.0=spotbugs
74+
org.apache.commons:commons-lang3:3.19.0=spotbugs
75+
org.apache.commons:commons-text:1.14.0=spotbugs
76+
org.apache.logging.log4j:log4j-api:2.25.2=spotbugs
77+
org.apache.logging.log4j:log4j-core:2.25.2=spotbugs
78+
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testRuntimeClasspath
79+
org.bouncycastle:bcprov-jdk18on:1.81=compileClasspath
80+
org.checkerframework:checker-qual:3.33.0=annotationProcessor,testAnnotationProcessor
81+
org.codehaus.groovy:groovy-ant:3.0.23=codenarc
82+
org.codehaus.groovy:groovy-docgenerator:3.0.23=codenarc
83+
org.codehaus.groovy:groovy-groovydoc:3.0.23=codenarc
84+
org.codehaus.groovy:groovy-json:3.0.23=codenarc
85+
org.codehaus.groovy:groovy-json:3.0.25=testCompileClasspath,testRuntimeClasspath
86+
org.codehaus.groovy:groovy-templates:3.0.23=codenarc
87+
org.codehaus.groovy:groovy-xml:3.0.23=codenarc
88+
org.codehaus.groovy:groovy:3.0.23=codenarc
89+
org.codehaus.groovy:groovy:3.0.25=testCompileClasspath,testRuntimeClasspath
90+
org.codenarc:CodeNarc:3.7.0=codenarc
91+
org.dom4j:dom4j:2.2.0=spotbugs
92+
org.gmetrics:GMetrics:2.1.0=codenarc
93+
org.hamcrest:hamcrest-core:1.3=compileClasspath,testRuntimeClasspath
94+
org.hamcrest:hamcrest:3.0=testCompileClasspath,testRuntimeClasspath
95+
org.jctools:jctools-core-jdk11:4.0.6=testRuntimeClasspath
96+
org.jctools:jctools-core:4.0.6=testRuntimeClasspath
97+
org.jspecify:jspecify:1.0.0=compileClasspath,testCompileClasspath,testRuntimeClasspath
98+
org.junit.jupiter:junit-jupiter-api:5.14.1=testCompileClasspath,testRuntimeClasspath
99+
org.junit.jupiter:junit-jupiter-engine:5.14.1=testRuntimeClasspath
100+
org.junit.jupiter:junit-jupiter-params:5.14.1=testCompileClasspath,testRuntimeClasspath
101+
org.junit.jupiter:junit-jupiter:5.14.1=testCompileClasspath,testRuntimeClasspath
102+
org.junit.platform:junit-platform-commons:1.14.1=testCompileClasspath,testRuntimeClasspath
103+
org.junit.platform:junit-platform-engine:1.14.1=testCompileClasspath,testRuntimeClasspath
104+
org.junit.platform:junit-platform-launcher:1.14.1=testRuntimeClasspath
105+
org.junit.platform:junit-platform-runner:1.14.1=testRuntimeClasspath
106+
org.junit.platform:junit-platform-suite-api:1.14.1=testRuntimeClasspath
107+
org.junit.platform:junit-platform-suite-commons:1.14.1=testRuntimeClasspath
108+
org.junit:junit-bom:5.14.0=spotbugs
109+
org.junit:junit-bom:5.14.1=testCompileClasspath,testRuntimeClasspath
110+
org.mockito:mockito-core:4.4.0=testRuntimeClasspath
111+
org.objenesis:objenesis:3.3=testCompileClasspath,testRuntimeClasspath
112+
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath
113+
org.ow2.asm:asm-analysis:9.7.1=testRuntimeClasspath
114+
org.ow2.asm:asm-analysis:9.9=spotbugs
115+
org.ow2.asm:asm-commons:9.8=compileClasspath
116+
org.ow2.asm:asm-commons:9.9=spotbugs
117+
org.ow2.asm:asm-commons:9.9.1=testRuntimeClasspath
118+
org.ow2.asm:asm-tree:9.8=compileClasspath
119+
org.ow2.asm:asm-tree:9.9=spotbugs
120+
org.ow2.asm:asm-tree:9.9.1=testRuntimeClasspath
121+
org.ow2.asm:asm-util:9.7.1=testRuntimeClasspath
122+
org.ow2.asm:asm-util:9.9=spotbugs
123+
org.ow2.asm:asm:9.9=spotbugs
124+
org.ow2.asm:asm:9.9.1=buildTimeInstrumentationPlugin,compileClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
125+
org.robolectric:annotations:4.16.1=compileClasspath
126+
org.robolectric:junit:4.16.1=compileClasspath
127+
org.robolectric:nativeruntime:4.16.1=compileClasspath
128+
org.robolectric:pluginapi:4.16.1=compileClasspath
129+
org.robolectric:plugins-maven-dependency-resolver:4.16.1=compileClasspath
130+
org.robolectric:resources:4.16.1=compileClasspath
131+
org.robolectric:robolectric:4.16.1=compileClasspath
132+
org.robolectric:sandbox:4.16.1=compileClasspath
133+
org.robolectric:shadowapi:4.16.1=compileClasspath
134+
org.robolectric:shadows-framework:4.16.1=compileClasspath
135+
org.robolectric:utils-reflector:4.16.1=compileClasspath
136+
org.robolectric:utils:4.16.1=compileClasspath
137+
org.slf4j:jcl-over-slf4j:1.7.30=testCompileClasspath,testRuntimeClasspath
138+
org.slf4j:jul-to-slf4j:1.7.30=testCompileClasspath,testRuntimeClasspath
139+
org.slf4j:log4j-over-slf4j:1.7.30=testCompileClasspath,testRuntimeClasspath
140+
org.slf4j:slf4j-api:1.7.30=buildTimeInstrumentationPlugin,compileClasspath,muzzleBootstrap,muzzleTooling,runtimeClasspath
141+
org.slf4j:slf4j-api:1.7.32=testCompileClasspath,testRuntimeClasspath
142+
org.slf4j:slf4j-api:2.0.17=spotbugs,spotbugsSlf4j
143+
org.slf4j:slf4j-simple:2.0.17=spotbugsSlf4j
144+
org.snakeyaml:snakeyaml-engine:2.9=buildTimeInstrumentationPlugin,muzzleTooling,runtimeClasspath,testRuntimeClasspath
145+
org.spockframework:spock-bom:2.4-groovy-3.0=testCompileClasspath,testRuntimeClasspath
146+
org.spockframework:spock-core:2.4-groovy-3.0=testCompileClasspath,testRuntimeClasspath
147+
org.tabletest:tabletest-junit:1.2.1=testCompileClasspath,testRuntimeClasspath
148+
org.tabletest:tabletest-parser:1.2.0=testCompileClasspath,testRuntimeClasspath
149+
org.xmlresolver:xmlresolver:5.3.3=spotbugs
150+
empty=spotbugsPlugins
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package datadog.trace.instrumentation.robolectric;
2+
3+
import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface;
4+
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
5+
6+
import com.google.auto.service.AutoService;
7+
import datadog.trace.agent.tooling.Instrumenter;
8+
import datadog.trace.agent.tooling.InstrumenterModule;
9+
import net.bytebuddy.asm.Advice;
10+
import net.bytebuddy.description.type.TypeDescription;
11+
import net.bytebuddy.matcher.ElementMatcher;
12+
13+
/**
14+
* Captures the emulated Android SDK for tests running under Robolectric.
15+
*
16+
* <p>Robolectric establishes the emulated SDK in {@code TestEnvironment#setUpApplicationState},
17+
* which runs on the per-SDK sandbox "main" thread right before the test body (the SDK is not yet
18+
* set when the JUnit test-start event fires, and is torn down before the finish event).
19+
*/
20+
@AutoService(InstrumenterModule.class)
21+
public class RobolectricInstrumentation extends InstrumenterModule.CiVisibility
22+
implements Instrumenter.ForTypeHierarchy, Instrumenter.HasMethodAdvice {
23+
24+
public RobolectricInstrumentation() {
25+
super("ci-visibility", "robolectric");
26+
}
27+
28+
@Override
29+
public String hierarchyMarkerType() {
30+
return "org.robolectric.internal.TestEnvironment";
31+
}
32+
33+
@Override
34+
public ElementMatcher<TypeDescription> hierarchyMatcher() {
35+
return implementsInterface(named(hierarchyMarkerType()));
36+
}
37+
38+
@Override
39+
public String[] helperClassNames() {
40+
return new String[] {packageName + ".RobolectricTestAnnotator"};
41+
}
42+
43+
@Override
44+
public void methodAdvice(MethodTransformer transformer) {
45+
transformer.applyAdvice(
46+
named("setUpApplicationState"), getClass().getName() + "$SetUpApplicationStateAdvice");
47+
}
48+
49+
public static class SetUpApplicationStateAdvice {
50+
// onThrowable so the tags are still captured when setUpApplicationState fails (e.g. during
51+
// manifest/resource initialization): the emulated SDK is set early in the method, and the test
52+
// span still exists, so the failing test should carry the Android metadata too.
53+
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
54+
public static void onExit() {
55+
RobolectricTestAnnotator.annotate();
56+
}
57+
}
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package datadog.trace.instrumentation.robolectric;
2+
3+
import datadog.trace.api.gateway.RequestContext;
4+
import datadog.trace.api.gateway.RequestContextSlot;
5+
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
6+
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
7+
import datadog.trace.bootstrap.instrumentation.api.Tags;
8+
import java.io.File;
9+
import java.net.URL;
10+
import java.security.CodeSource;
11+
import java.security.ProtectionDomain;
12+
import java.util.regex.Matcher;
13+
import java.util.regex.Pattern;
14+
import org.robolectric.RobolectricTestRunner;
15+
import org.robolectric.RuntimeEnvironment;
16+
import org.robolectric.versioning.AndroidVersions;
17+
18+
public final class RobolectricTestAnnotator {
19+
20+
/** Matches the version in a {@code robolectric-<version>.jar} file name. */
21+
private static final Pattern ROBOLECTRIC_JAR = Pattern.compile("^robolectric-(.+)\\.jar$");
22+
23+
private RobolectricTestAnnotator() {}
24+
25+
public static void annotate() {
26+
int apiLevel = RuntimeEnvironment.getApiLevel();
27+
if (apiLevel <= 0) {
28+
return;
29+
}
30+
31+
AgentSpan span = AgentTracer.activeSpan();
32+
if (span == null) {
33+
return;
34+
}
35+
RequestContext requestContext = span.getRequestContext();
36+
if (requestContext == null
37+
|| requestContext.getData(RequestContextSlot.CI_VISIBILITY) == null) {
38+
// The active span is not a CI Visibility test span; nothing to enrich.
39+
return;
40+
}
41+
42+
span.setTag(Tags.TEST_ANDROID_API_LEVEL, apiLevel);
43+
AndroidVersions.AndroidRelease release = AndroidVersions.getReleaseForSdkInt(apiLevel);
44+
if (release != null) {
45+
span.setTag(Tags.TEST_ANDROID_RELEASE, release.getVersion());
46+
span.setTag(Tags.TEST_ANDROID_CODENAME, release.getShortCode());
47+
}
48+
String robolectricVersion = robolectricVersion();
49+
if (robolectricVersion != null) {
50+
span.setTag(Tags.TEST_ANDROID_ROBOLECTRIC_VERSION, robolectricVersion);
51+
}
52+
}
53+
54+
private static String robolectricVersion() {
55+
try {
56+
// RuntimeEnvironment is re-loaded by the sandbox classloader with no CodeSource, but the
57+
// runner runs outside the sandbox (it creates it), so it is delegated to the application
58+
// classloader and its CodeSource points at the real robolectric-<version>.jar.
59+
ProtectionDomain protectionDomain = RobolectricTestRunner.class.getProtectionDomain();
60+
CodeSource codeSource = protectionDomain != null ? protectionDomain.getCodeSource() : null;
61+
URL location = codeSource != null ? codeSource.getLocation() : null;
62+
if (location == null) {
63+
return null;
64+
}
65+
Matcher matcher = ROBOLECTRIC_JAR.matcher(new File(location.getPath()).getName());
66+
return matcher.matches() ? matcher.group(1) : null;
67+
} catch (Throwable t) {
68+
return null;
69+
}
70+
}
71+
}

dd-smoke-tests/gradle/src/test/java/datadog/smoketest/GradleDaemonSmokeTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,34 @@ void testNew(
129129
expectedCoverages);
130130
}
131131

132+
@TableTest({
133+
"scenario | gradleVersion | projectName | expectedTraces",
134+
"robolectric-latest | latest | test-succeed-robolectric | 6 "
135+
})
136+
@ParameterizedTest
137+
void testRobolectric(String gradleVersion, String projectName, int expectedTraces)
138+
throws IOException {
139+
Assumptions.assumeTrue(
140+
JavaVirtualMachine.isJavaVersionBetween(17, 22), "Robolectric 4.16 supports JDK 17-21");
141+
142+
gradleVersion = resolveVersion(gradleVersion);
143+
givenGradleVersionIsCompatibleWithCurrentJvm(gradleVersion);
144+
givenGradleVersionIsSupportedByCurrentGradleTestKit(gradleVersion);
145+
givenGradleProjectFiles(projectName);
146+
givenGradleProjectProperties();
147+
ensureDependenciesDownloaded(gradleVersion);
148+
149+
BuildResult buildResult = runGradleTests(gradleVersion, true, false);
150+
assertBuildSuccessful(buildResult);
151+
152+
verifyEventsAndCoverages(
153+
projectName,
154+
"gradle",
155+
gradleVersion,
156+
mockBackend.waitForEvents(expectedTraces),
157+
mockBackend.waitForCoverages(0));
158+
}
159+
132160
// TODO: add back LATEST_GRADLE_VERSION after fixing ordering on Gradle 9.3.0
133161
@TableTest({
134162
"scenario | gradleVersion | projectName | flakyTests | expectedOrder | eventsNumber",

0 commit comments

Comments
 (0)