Extend test parameters to partial compilation
This extends the TestParameters to include a PartialCompilationTestParameters, which is either NONE (default), INCLUDE_ALL, EXCLUDE_ALL or RANDOM.
The non-default PartialCompilationTestParameters can be obtained by calling .withPartialCompilation() on the TestParametersBuilder.
Change-Id: I74dce0e116100403b44764bd883d33319a9000bf
diff --git a/src/test/examplesJava21/desugaredlibrary/Java21CollectionTest.java b/src/test/examplesJava21/desugaredlibrary/Java21CollectionTest.java
index 6b1c8fe..d86ef1d 100644
--- a/src/test/examplesJava21/desugaredlibrary/Java21CollectionTest.java
+++ b/src/test/examplesJava21/desugaredlibrary/Java21CollectionTest.java
@@ -60,7 +60,7 @@
@Parameters(name = "{0}, spec: {1}, {2}")
public static List<Object[]> data() {
return buildParameters(
- getTestParameters().withDexRuntimesIncludingMaster().withAllApiLevels().build(),
+ getTestParameters().withDexRuntimesAndAllApiLevels().build(),
// Note that JDK8 is completely broken here.
ImmutableList.of(JDK11, JDK11_PATH),
DEFAULT_SPECIFICATIONS);
diff --git a/src/test/examplesJava21/desugaredlibrary/MapMultiTest.java b/src/test/examplesJava21/desugaredlibrary/MapMultiTest.java
index 32bf566..cd3203b 100644
--- a/src/test/examplesJava21/desugaredlibrary/MapMultiTest.java
+++ b/src/test/examplesJava21/desugaredlibrary/MapMultiTest.java
@@ -41,7 +41,7 @@
@Parameters(name = "{0}, spec: {1}, {2}")
public static List<Object[]> data() {
return buildParameters(
- getTestParameters().withDexRuntimesIncludingMaster().withAllApiLevels().build(),
+ getTestParameters().withDexRuntimesAndAllApiLevels().build(),
// Note that JDK8 is completely broken here.
ImmutableList.of(JDK11, JDK11_PATH),
DEFAULT_SPECIFICATIONS);
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LinkedListJdk8BrokenByAndroidVUpdateTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LinkedListJdk8BrokenByAndroidVUpdateTest.java
index 3555c2d..0800f37 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LinkedListJdk8BrokenByAndroidVUpdateTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LinkedListJdk8BrokenByAndroidVUpdateTest.java
@@ -38,7 +38,7 @@
@Parameters(name = "{0}, spec: {1}, {2}")
public static List<Object[]> data() {
return buildParameters(
- getTestParameters().withDexRuntimesIncludingMaster().withAllApiLevels().build(),
+ getTestParameters().withDexRuntimesAndAllApiLevels().build(),
ImmutableList.of(JDK8, JDK11, JDK11_PATH),
DEFAULT_SPECIFICATIONS);
}
diff --git a/src/test/testbase/java/com/android/tools/r8/PartialCompilationTestParameters.java b/src/test/testbase/java/com/android/tools/r8/PartialCompilationTestParameters.java
new file mode 100644
index 0000000..74fc752
--- /dev/null
+++ b/src/test/testbase/java/com/android/tools/r8/PartialCompilationTestParameters.java
@@ -0,0 +1,31 @@
+// Copyright (c) 2025, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8;
+
+public enum PartialCompilationTestParameters {
+ NONE,
+ INCLUDE_ALL,
+ EXCLUDE_ALL,
+ RANDOM;
+
+ public boolean isNone() {
+ return this == NONE;
+ }
+
+ public boolean isSome() {
+ return !isNone();
+ }
+
+ public boolean isIncludeAll() {
+ return this == INCLUDE_ALL;
+ }
+
+ public boolean isExcludeAll() {
+ return this == EXCLUDE_ALL;
+ }
+
+ public boolean isRandom() {
+ return this == RANDOM;
+ }
+}
diff --git a/src/test/testbase/java/com/android/tools/r8/TestParameters.java b/src/test/testbase/java/com/android/tools/r8/TestParameters.java
index ef797e2..3eaa3c1 100644
--- a/src/test/testbase/java/com/android/tools/r8/TestParameters.java
+++ b/src/test/testbase/java/com/android/tools/r8/TestParameters.java
@@ -22,21 +22,29 @@
private final TestRuntime runtime;
private final AndroidApiLevel apiLevel;
+ private final PartialCompilationTestParameters partialCompilationTestParameters;
private final boolean representativeApiLevelForRuntime;
public TestParameters(TestRuntime runtime) {
- this(runtime, null);
- }
-
- public TestParameters(TestRuntime runtime, AndroidApiLevel apiLevel) {
- this(runtime, apiLevel, true);
+ this(runtime, null, PartialCompilationTestParameters.NONE);
}
public TestParameters(
- TestRuntime runtime, AndroidApiLevel apiLevel, boolean representativeApiLevelForRuntime) {
+ TestRuntime runtime,
+ AndroidApiLevel apiLevel,
+ PartialCompilationTestParameters partialCompilationTestParameters) {
+ this(runtime, apiLevel, partialCompilationTestParameters, true);
+ }
+
+ public TestParameters(
+ TestRuntime runtime,
+ AndroidApiLevel apiLevel,
+ PartialCompilationTestParameters partialCompilationTestParameters,
+ boolean representativeApiLevelForRuntime) {
assert runtime != null;
this.runtime = runtime;
this.apiLevel = apiLevel;
+ this.partialCompilationTestParameters = partialCompilationTestParameters;
this.representativeApiLevelForRuntime = representativeApiLevelForRuntime;
}
@@ -205,6 +213,10 @@
return runtime.asCf();
}
+ public PartialCompilationTestParameters getPartialCompilationTestParameters() {
+ return partialCompilationTestParameters;
+ }
+
// Access to underlying runtime/wrapper.
public TestRuntime getRuntime() {
return runtime;
@@ -222,10 +234,14 @@
@Override
public String toString() {
+ StringBuilder builder = new StringBuilder(runtime.toString());
if (apiLevel != null) {
- return runtime.toString() + ", api:" + apiLevel.getLevel();
+ builder.append(", api:").append(apiLevel.getLevel());
}
- return runtime.toString();
+ if (partialCompilationTestParameters.isSome()) {
+ builder.append(", partial:").append(partialCompilationTestParameters);
+ }
+ return builder.toString();
}
public void assertCfRuntime() {
@@ -308,4 +324,11 @@
assertTrue(isDexRuntime());
return getRuntime().asDex().getVm().getVersion();
}
+
+ TestParameters withPartialCompilationTestParameters(
+ PartialCompilationTestParameters partialCompilationTestParameters) {
+ assert getPartialCompilationTestParameters().isNone();
+ return new TestParameters(
+ runtime, apiLevel, partialCompilationTestParameters, representativeApiLevelForRuntime);
+ }
}
diff --git a/src/test/testbase/java/com/android/tools/r8/TestParametersBuilder.java b/src/test/testbase/java/com/android/tools/r8/TestParametersBuilder.java
index 16a0997..36ecb2f 100644
--- a/src/test/testbase/java/com/android/tools/r8/TestParametersBuilder.java
+++ b/src/test/testbase/java/com/android/tools/r8/TestParametersBuilder.java
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
+import static com.google.common.base.Predicates.alwaysFalse;
+
import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.TestRuntime.DexRuntime;
@@ -25,10 +27,9 @@
// Predicate describing which test parameters are applicable to the test.
// Built via the methods found below. Defaults to no applicable parameters, i.e., the emtpy set.
- private Predicate<TestParameters> filter = param -> false;
+ private Predicate<TestParameters> filter = alwaysFalse();
+ private Predicate<TestParameters> partialFilter = alwaysFalse();
private boolean hasDexRuntimeFilter = false;
- // TODO(b/245066448): Enable bot with testing new art master.
- private boolean allowMaster = System.getProperty("com.android.tools.r8.artmaster") != null;
TestParametersBuilder() {}
@@ -46,10 +47,17 @@
return withFilter(
p ->
p.isDexRuntime()
- && (allowMaster || p.getDexRuntimeVersion().isOlderThan(DexVm.Version.MASTER))
+ && p.getDexRuntimeVersion().isOlderThan(DexVm.Version.MASTER)
&& predicate.test(p.getDexRuntimeVersion()));
}
+ private TestParametersBuilder withPartialCompilationFilter(
+ Predicate<PartialCompilationTestParameters> predicate) {
+ enablePartialCompilation = true;
+ partialFilter = partialFilter.or(p -> predicate.test(p.getPartialCompilationTestParameters()));
+ return this;
+ }
+
public TestParametersBuilder withNoneRuntime() {
return withFilter(p -> p.getRuntime() == NoneRuntime.getInstance());
}
@@ -120,32 +128,11 @@
return withCfRuntimeFilter(startInclusive::lessThanOrEqual);
}
- /** Add all available CF runtimes starting from and excluding {@param startExcluding}. */
- public TestParametersBuilder withCfRuntimesStartingFromExcluding(CfVm startExcluding) {
- return withCfRuntimeFilter(startExcluding::lessThan);
- }
-
- /** Add all available CF runtimes ending at and including {@param endInclusive}. */
- public TestParametersBuilder withCfRuntimesEndingAtIncluding(CfVm endInclusive) {
- return withCfRuntimeFilter(vm -> vm.lessThanOrEqual(endInclusive));
- }
-
/** Add all available CF runtimes ending at and excluding {@param endExclusive}. */
public TestParametersBuilder withCfRuntimesEndingAtExcluding(CfVm endExclusive) {
return withCfRuntimeFilter(vm -> vm.lessThan(endExclusive));
}
- /** Add all available DEX runtimes including master. */
- public TestParametersBuilder withDexRuntimesIncludingMaster() {
- this.allowMaster = true;
- return withDexRuntimes();
- }
-
- public TestParametersBuilder allowMaster() {
- this.allowMaster = true;
- return this;
- }
-
/** Add all available DEX runtimes except master. */
public TestParametersBuilder withDexRuntimes() {
return withDexRuntimeFilter(vm -> true);
@@ -165,11 +152,6 @@
return withDexRuntimesStartingFromIncluding(DexVm.Version.V5_1_1);
}
- /** Add all available DEX runtimes that do not support native multidex. */
- public TestParametersBuilder withMainDexRuntimes() {
- return withDexRuntimesEndingAtExcluding(DexVm.Version.V5_1_1);
- }
-
/** Add all available DEX runtimes starting from and including {@param startInclusive}. */
public TestParametersBuilder withDexRuntimesStartingFromIncluding(DexVm.Version startInclusive) {
return withDexRuntimeFilter(startInclusive::isOlderThanOrEqual);
@@ -181,14 +163,22 @@
vm -> vm != startExcluding && startExcluding.isOlderThanOrEqual(vm));
}
- /** Add all available DEX runtimes ending at and including {@param endInclusive}. */
- public TestParametersBuilder withDexRuntimesEndingAtIncluding(DexVm.Version endInclusive) {
- return withDexRuntimeFilter(vm -> vm.isOlderThanOrEqual(endInclusive));
+ public TestParametersBuilder withPartialCompilation() {
+ return withIncludeAllPartialCompilation()
+ .withExcludeAllPartialCompilation()
+ .withRandomPartialCompilation();
}
- /** Add all available DEX runtimes ending at and excluding {@param endExclusive}. */
- public TestParametersBuilder withDexRuntimesEndingAtExcluding(DexVm.Version endExclusive) {
- return withDexRuntimeFilter(vm -> vm != endExclusive && vm.isOlderThanOrEqual(endExclusive));
+ public TestParametersBuilder withIncludeAllPartialCompilation() {
+ return withPartialCompilationFilter(PartialCompilationTestParameters::isIncludeAll);
+ }
+
+ public TestParametersBuilder withExcludeAllPartialCompilation() {
+ return withPartialCompilationFilter(PartialCompilationTestParameters::isExcludeAll);
+ }
+
+ public TestParametersBuilder withRandomPartialCompilation() {
+ return withPartialCompilationFilter(PartialCompilationTestParameters::isRandom);
}
/**
@@ -202,10 +192,10 @@
private boolean enableApiLevels = false;
private boolean enableApiLevelsForCf = false;
+ private boolean enablePartialCompilation = false;
private BiPredicate<AndroidApiLevel, TestRuntime> apiLevelFilter = (api, runtime) -> false;
- private List<AndroidApiLevel> explicitApiLevels = new ArrayList<>();
- private List<TestRuntime> customRuntimes = new ArrayList<>();
+ private final List<AndroidApiLevel> explicitApiLevels = new ArrayList<>();
private TestParametersBuilder withApiFilter(BiPredicate<AndroidApiLevel, TestRuntime> filter) {
enableApiLevels = true;
@@ -243,10 +233,6 @@
return withApiFilter((api, runtime) -> startInclusive.getLevel() <= api.getLevel());
}
- public TestParametersBuilder withApiLevelsStartingAtExcluding(AndroidApiLevel startExclusive) {
- return withApiFilter((api, runtime) -> startExclusive.getLevel() < api.getLevel());
- }
-
public TestParametersBuilder withApiLevelsEndingAtIncluding(AndroidApiLevel endInclusive) {
return withApiFilter((api, runtime) -> api.getLevel() <= endInclusive.getLevel());
}
@@ -255,34 +241,52 @@
return withApiFilter((api, runtime) -> api.getLevel() < endExclusive.getLevel());
}
- public TestParametersBuilder withApiLevelsWithoutNativeMultiDex() {
- return withApiLevelsEndingAtExcluding(AndroidApiLevel.L);
- }
-
public TestParametersBuilder apiLevelWithDefaultMethodsSupport() {
return withApiLevelsStartingAtIncluding(TestBase.apiLevelWithDefaultInterfaceMethodsSupport());
}
- public TestParametersBuilder withCustomRuntime(TestRuntime runtime) {
- assert getUnfilteredAvailableRuntimes().noneMatch(r -> r == runtime);
- customRuntimes.add(runtime);
- return this;
- }
-
public TestParametersCollection build() {
assert !enableApiLevels || enableApiLevelsForCf || hasDexRuntimeFilter;
List<TestParameters> availableParameters =
getAvailableRuntimes()
- .flatMap(this::createParameters)
+ .flatMap(this::createTestParameters)
.filter(filter)
.collect(Collectors.toList());
- List<TestParameters> customParameters =
- customRuntimes.stream().flatMap(this::createParameters).collect(Collectors.toList());
- availableParameters.addAll(customParameters);
return new TestParametersCollection(availableParameters);
}
- public Stream<TestParameters> createParameters(TestRuntime runtime) {
+ private Stream<TestParameters> createTestParameters(TestRuntime runtime) {
+ Stream<TestParameters> parameters = createBasicTestParametersForRuntime(runtime);
+ if (enablePartialCompilation) {
+ parameters = createPartialCompilationTestParameters(parameters);
+ }
+ return parameters;
+ }
+
+ private Stream<TestParameters> createPartialCompilationTestParameters(
+ Stream<TestParameters> parameters) {
+ return parameters.flatMap(this::createPartialCompilationTestParameters);
+ }
+
+ private Stream<TestParameters> createPartialCompilationTestParameters(TestParameters parameters) {
+ if (!parameters.isR8PartialTestParameters()) {
+ return Stream.of(parameters);
+ }
+ assert parameters.getPartialCompilationTestParameters().isNone();
+ Stream.Builder<TestParameters> builder = Stream.builder();
+ builder.add(parameters);
+ for (PartialCompilationTestParameters partialCompilationTestParameters :
+ PartialCompilationTestParameters.values()) {
+ TestParameters newParameters =
+ parameters.withPartialCompilationTestParameters(partialCompilationTestParameters);
+ if (partialFilter.test(newParameters)) {
+ builder.add(newParameters);
+ }
+ }
+ return builder.build();
+ }
+
+ private Stream<TestParameters> createBasicTestParametersForRuntime(TestRuntime runtime) {
if (!enableApiLevels) {
return Stream.of(new TestParameters(runtime));
}
@@ -319,14 +323,19 @@
.map(
api -> {
TestParameters parameters =
- new TestParameters(runtime, api, representativeApiLevelForRuntime.get());
+ new TestParameters(
+ runtime,
+ api,
+ PartialCompilationTestParameters.NONE,
+ representativeApiLevelForRuntime.get());
representativeApiLevelForRuntime.unset();
return parameters;
});
}
}
}
- return Stream.of(new TestParameters(runtime, lowestApplicable));
+ return Stream.of(
+ new TestParameters(runtime, lowestApplicable, PartialCompilationTestParameters.NONE, true));
}
// Public method to check that the CF runtime coincides with the system runtime.
@@ -371,18 +380,4 @@
}
return getUnfilteredAvailableRuntimes();
}
-
- public static List<CfVm> getAvailableCfVms() {
- return getAvailableRuntimes()
- .filter(TestRuntime::isCf)
- .map(runtime -> runtime.asCf().getVm())
- .collect(Collectors.toList());
- }
-
- public static List<DexVm> getAvailableDexVms() {
- return getAvailableRuntimes()
- .filter(TestRuntime::isDex)
- .map(runtime -> runtime.asDex().getVm())
- .collect(Collectors.toList());
- }
}