Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ muzzle {
pass {
group = 'org.robolectric'
module = 'robolectric'
versions = '[4.13,4.17)'
versions = '[4.13,)'
// androidx.test:monitor is an Android archive (.aar) that a JVM configuration cannot consume;
// it is not referenced by the advice/helper. Mirror the compileOnly exclusion below.
excludeDependency 'androidx.test:monitor'
// Robolectric loads the selected Android SDK dynamically, so android-all is not a transitive
// dependency even though android.os.Build is available when the helper runs.
extraDependency 'org.robolectric:android-all:14-robolectric-10818077'
}
}

Expand All @@ -32,6 +35,7 @@ dependencies {
compileOnly(group: 'org.robolectric', name: 'robolectric', version: '4.16.1') {
exclude group: 'androidx.test', module: 'monitor'
}
compileOnly group: 'org.robolectric', name: 'android-all', version: '14-robolectric-10818077'
// RobolectricTestRunner extends JUnit's BlockJUnit4ClassRunner; JUnit must be on the compile
// classpath so its supertypes resolve (both javac and forbiddenApis walk the class hierarchy).
compileOnly group: 'junit', name: 'junit', version: '4.13.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ org.ow2.asm:asm-tree:9.8=compileClasspath
org.ow2.asm:asm-util:9.10.1=spotbugs
org.ow2.asm:asm-util:9.7.1=testRuntimeClasspath
org.ow2.asm:asm:9.10.1=buildTimeInstrumentationPlugin,compileClasspath,muzzleTooling,runtimeClasspath,spotbugs,testCompileClasspath,testRuntimeClasspath
org.robolectric:android-all:14-robolectric-10818077=compileClasspath
org.robolectric:annotations:4.16.1=compileClasspath
org.robolectric:junit:4.16.1=compileClasspath
org.robolectric:nativeruntime:4.16.1=compileClasspath
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package datadog.trace.instrumentation.robolectric;

public final class AndroidVersionUtils {

private static final String[] CODENAMES = {
null,
"BASE",
"BASE_1_1",
"CUPCAKE",
"DONUT",
"ECLAIR",
"ECLAIR_0_1",
"ECLAIR_MR1",
"FROYO",
"GINGERBREAD",
"GINGERBREAD_MR1",
"HONEYCOMB",
"HONEYCOMB_MR1",
"HONEYCOMB_MR2",
"ICE_CREAM_SANDWICH",
"ICE_CREAM_SANDWICH_MR1",
"JELLY_BEAN",
"JELLY_BEAN_MR1",
"JELLY_BEAN_MR2",
"KITKAT",
"KITKAT_WATCH",
"LOLLIPOP",
"LOLLIPOP_MR1",
"M",
"N",
"N_MR1",
"O",
"O_MR1",
"P",
"Q",
"R",
"S",
"S_V2",
"TIRAMISU",
"UPSIDE_DOWN_CAKE",
"VANILLA_ICE_CREAM",
"BAKLAVA",
"CINNAMON_BUN"
};

private AndroidVersionUtils() {}

public static String codename(int apiLevel) {
return apiLevel > 0 && apiLevel < CODENAMES.length ? CODENAMES[apiLevel] : null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ public ElementMatcher<TypeDescription> hierarchyMatcher() {

@Override
public String[] helperClassNames() {
return new String[] {packageName + ".RobolectricTestAnnotator"};
return new String[] {
packageName + ".AndroidVersionUtils", packageName + ".RobolectricTestAnnotator"
};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package datadog.trace.instrumentation.robolectric;

import android.os.Build;
import datadog.trace.api.gateway.RequestContext;
import datadog.trace.api.gateway.RequestContextSlot;
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
Expand All @@ -13,7 +14,6 @@
import java.util.regex.Pattern;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.versioning.AndroidVersions;

public final class RobolectricTestAnnotator {

Expand All @@ -40,10 +40,10 @@ public static void annotate() {
}

span.setTag(Tags.TEST_ANDROID_API_LEVEL, apiLevel);
AndroidVersions.AndroidRelease release = AndroidVersions.getReleaseForSdkInt(apiLevel);
if (release != null) {
span.setTag(Tags.TEST_ANDROID_RELEASE, release.getVersion());
span.setTag(Tags.TEST_ANDROID_CODENAME, release.getShortCode());
span.setTag(Tags.TEST_ANDROID_RELEASE, Build.VERSION.RELEASE);
String androidCodename = AndroidVersionUtils.codename(apiLevel);
if (androidCodename != null) {
span.setTag(Tags.TEST_ANDROID_CODENAME, androidCodename);
}
String robolectricVersion = robolectricVersion();
if (robolectricVersion != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,20 @@ void testNew(
}

@TableTest({
"scenario | gradleVersion | projectName | expectedTraces",
"robolectric-latest | latest | test-succeed-robolectric | 7 "
"scenario | gradleVersion | robolectricVersion | expectedVersion | projectName | expectedTraces",
"robolectric-4.16 | latest | 4.16.1 | 4.16.1 | test-succeed-robolectric | 7 ",
"robolectric-latest | latest | + | any | test-succeed-robolectric | 7 "
})
@ParameterizedTest
void testRobolectric(String gradleVersion, String projectName, int expectedTraces)
void testRobolectric(
String gradleVersion,
String robolectricVersion,
String expectedVersion,
String projectName,
int expectedTraces)
throws IOException {
Assumptions.assumeTrue(
JavaVirtualMachine.isJavaVersionBetween(17, 22), "Robolectric 4.16 supports JDK 17-21");
JavaVirtualMachine.isJavaVersionBetween(17, 22), "Robolectric supports JDK 17-21");
Assumptions.assumeFalse(
OperatingSystem.architecture().isArm64(),
"Robolectric does not support arm64 (missing native runtime binaries, follow https://github.com/robolectric/robolectric/issues/9166)");
Expand All @@ -163,15 +169,43 @@ void testRobolectric(String gradleVersion, String projectName, int expectedTrace
givenGradleProjectProperties();
ensureDependenciesDownloaded(gradleVersion);

BuildResult buildResult = runGradleTests(gradleVersion, true, false);
Map<String, String> additionalEnvVars =
Collections.singletonMap("SMOKE_TEST_ROBOLECTRIC_VERSION", robolectricVersion);
BuildResult buildResult = runGradleTests(gradleVersion, true, false, additionalEnvVars);
assertBuildSuccessful(buildResult);

List<? extends Map<?, ?>> events = mockBackend.waitForEvents(expectedTraces);
assertRobolectricVersion(events, expectedVersion);
verifyEventsAndCoverages(
projectName,
"gradle",
gradleVersion,
mockBackend.waitForEvents(expectedTraces),
mockBackend.waitForCoverages(0));
events,
mockBackend.waitForCoverages(0),
Collections.singletonList("content.meta.['test.android.robolectric.version']"));
}

private static void assertRobolectricVersion(
List<? extends Map<?, ?>> events, String expectedVersion) {
int taggedEvents = 0;
for (Map<?, ?> event : events) {
Object content = event.get("content");
if (!(content instanceof Map)) {
continue;
}
Object meta = ((Map<?, ?>) content).get("meta");
if (!(meta instanceof Map)) {
continue;
}
Object version = ((Map<?, ?>) meta).get("test.android.robolectric.version");
if (version != null) {
if (!"any".equals(expectedVersion)) {
assertEquals(expectedVersion, version);
}
taggedEvents++;
}
}
assertEquals(2, taggedEvents);
}

@TableTest({
Expand Down Expand Up @@ -371,6 +405,16 @@ private void givenGradleProjectProperties(Map<String, String> additionalArgs) th
private BuildResult runGradleTests(
String gradleVersion, boolean successExpected, boolean configurationCache)
throws IOException {
return runGradleTests(
gradleVersion, successExpected, configurationCache, Collections.emptyMap());
}

private BuildResult runGradleTests(
String gradleVersion,
boolean successExpected,
boolean configurationCache,
Map<String, String> additionalEnvVars)
throws IOException {
List<String> arguments = new java.util.ArrayList<>(Arrays.asList("test", "--stacktrace"));
if (gradleVersion.compareTo("4.5") > 0) {
// warning mode available starting from Gradle 4.5
Expand All @@ -379,7 +423,7 @@ private BuildResult runGradleTests(
if (configurationCache) {
arguments.addAll(Arrays.asList("--configuration-cache", "--rerun-tasks"));
}
return runGradle(gradleVersion, arguments, successExpected);
return runGradle(gradleVersion, arguments, successExpected, additionalEnvVars);
}

/**
Expand Down Expand Up @@ -417,6 +461,15 @@ private void ensureDependenciesDownloaded(String gradleVersion) {

private BuildResult runGradle(
String gradleVersion, List<String> arguments, boolean successExpected) throws IOException {
return runGradle(gradleVersion, arguments, successExpected, Collections.emptyMap());
}

private BuildResult runGradle(
String gradleVersion,
List<String> arguments,
boolean successExpected,
Map<String, String> additionalEnvVars)
throws IOException {
Map<String, String> buildEnv = new HashMap<>();
buildEnv.put("GRADLE_ARGS", "");
buildEnv.put("GRADLE_OPTS", "");
Expand All @@ -425,6 +478,7 @@ private BuildResult runGradle(
buildEnv.put(
GradleDistribution.GRADLE_DISTRIBUTION_URL_ENV,
GradleDistribution.uriFor(gradleVersion).toString());
buildEnv.putAll(additionalEnvVars);

String mavenRepositoryProxy = System.getenv("MAVEN_REPOSITORY_PROXY");
if (mavenRepositoryProxy != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ configurations.configureEach {

dependencies {
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.robolectric:robolectric:4.16.1'
testImplementation "org.robolectric:robolectric:${System.getenv('SMOKE_TEST_ROBOLECTRIC_VERSION')}"
// Pre-built Android SDK jar for the level the fixtures configure.
testImplementation 'org.robolectric:android-all:14-robolectric-10818077'
// androidx.test:core pulls in androidx.test:monitor (InstrumentationRegistry); ext:junit provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,9 @@
"runtime.vendor" : ${content_meta_runtime_vendor},
"runtime.version" : ${content_meta_runtime_version},
"span.kind" : "test",
"test.android.codename" : "U",
"test.android.codename" : "UPSIDE_DOWN_CAKE",
"test.android.release" : "14",
"test.android.robolectric.version" : "4.16.1",
"test.android.robolectric.version" : ${content_meta_test_android_robolectric_version},
"test.final_status" : "pass",
"test.framework" : "junit4",
"test.framework_version" : "4.13.2",
Expand Down Expand Up @@ -505,9 +505,9 @@
"runtime.vendor" : ${content_meta_runtime_vendor},
"runtime.version" : ${content_meta_runtime_version},
"span.kind" : "test",
"test.android.codename" : "U",
"test.android.codename" : "UPSIDE_DOWN_CAKE",
"test.android.release" : "14",
"test.android.robolectric.version" : "4.16.1",
"test.android.robolectric.version" : ${content_meta_test_android_robolectric_version},
"test.final_status" : "pass",
"test.framework" : "junit4",
"test.framework_version" : "4.13.2",
Expand Down Expand Up @@ -688,4 +688,4 @@
},
"type" : "span",
"version" : 1
} ]
} ]