Skip to content
Merged
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
@@ -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,17 +40,98 @@ 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 = androidCodename(apiLevel);
if (androidCodename != null) {
span.setTag(Tags.TEST_ANDROID_CODENAME, androidCodename);
}
String robolectricVersion = robolectricVersion();
if (robolectricVersion != null) {
span.setTag(Tags.TEST_ANDROID_ROBOLECTRIC_VERSION, robolectricVersion);
}
}

private static String androidCodename(int apiLevel) {
switch (apiLevel) {
case 1:
return "BASE";
case 2:
return "BASE_1_1";
case 3:
return "CUPCAKE";
case 4:
return "DONUT";
case 5:
return "ECLAIR";
case 6:
return "ECLAIR_0_1";
case 7:
return "ECLAIR_MR1";
case 8:
return "FROYO";
case 9:
return "GINGERBREAD";
case 10:
return "GINGERBREAD_MR1";
case 11:
return "HONEYCOMB";
case 12:
return "HONEYCOMB_MR1";
case 13:
return "HONEYCOMB_MR2";
case 14:
return "ICE_CREAM_SANDWICH";
case 15:
return "ICE_CREAM_SANDWICH_MR1";
case 16:
return "JELLY_BEAN";
case 17:
return "JELLY_BEAN_MR1";
case 18:
return "JELLY_BEAN_MR2";
case 19:
return "KITKAT";
case 20:
return "KITKAT_WATCH";
case 21:
return "LOLLIPOP";
case 22:
return "LOLLIPOP_MR1";
case 23:
return "M";
case 24:
return "N";
case 25:
return "N_MR1";
case 26:
return "O";
case 27:
return "O_MR1";
case 28:
return "P";
case 29:
return "Q";
case 30:
return "R";
case 31:
return "S";
case 32:
return "S_V2";
case 33:
return "TIRAMISU";
case 34:
return "UPSIDE_DOWN_CAKE";
case 35:
return "VANILLA_ICE_CREAM";
case 36:
return "BAKLAVA";
case 37:
return "CINNAMON_BUN";
default:
return null;
}
}

private static String robolectricVersion() {
try {
// RuntimeEnvironment is re-loaded by the sandbox classloader with no CodeSource, but the
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
} ]
} ]