blob: 1c3f77cd0fa52e7e771ffcb3f03883449a6de004 [file] [log] [blame]
// Copyright (c) 2019, 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;
import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.TestRuntime.DexRuntime;
import com.android.tools.r8.TestRuntime.NoneRuntime;
import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.errors.Unreachable;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class TestParametersBuilder {
// Static computation of VMs configured as available by the testing invocation.
private static final List<TestRuntime> availableRuntimes =
getAvailableRuntimes().collect(Collectors.toList());
// Predicate describing which test parameters are applicable to the test.
// Built via the methods found below. Default to no applicable parameters, i.e., the emtpy set.
private Predicate<TestParameters> filter = param -> false;
private TestParametersBuilder() {}
public static TestParametersBuilder builder() {
return new TestParametersBuilder();
}
private TestParametersBuilder withFilter(Predicate<TestParameters> predicate) {
filter = filter.or(predicate);
return this;
}
private TestParametersBuilder withCfRuntimeFilter(Predicate<CfVm> predicate) {
return withFilter(p -> p.isCfRuntime() && predicate.test(p.getRuntime().asCf().getVm()));
}
private TestParametersBuilder withDexRuntimeFilter(Predicate<DexVm.Version> predicate) {
return withFilter(
p -> p.isDexRuntime() && predicate.test(p.getRuntime().asDex().getVm().getVersion()));
}
public TestParametersBuilder withNoneRuntime() {
return withFilter(p -> p.getRuntime() == NoneRuntime.getInstance());
}
public TestParametersBuilder withAllRuntimes() {
return withCfRuntimes().withDexRuntimes();
}
/** Add specific runtime if available. */
public TestParametersBuilder withCfRuntime(CfVm runtime) {
return withCfRuntimeFilter(vm -> vm == runtime);
}
/** Add all available CF runtimes. */
public TestParametersBuilder withCfRuntimes() {
return withCfRuntimeFilter(vm -> true);
}
/** Add all available CF runtimes between {@param startInclusive} and {@param endInclusive}. */
public TestParametersBuilder withCfRuntimes(CfVm startInclusive, CfVm endInclusive) {
return withCfRuntimeFilter(
vm -> startInclusive.lessThanOrEqual(vm) && vm.lessThanOrEqual(endInclusive));
}
/** Add all available CF runtimes starting from and including {@param startInclusive}. */
public TestParametersBuilder withCfRuntimesStartingFromIncluding(CfVm startInclusive) {
return withCfRuntimeFilter(vm -> startInclusive.lessThanOrEqual(vm));
}
/** Add all available CF runtimes starting from and excluding {@param startExcluding}. */
public TestParametersBuilder withCfRuntimesStartingFromExcluding(CfVm startExcluding) {
return withCfRuntimeFilter(vm -> startExcluding.lessThan(vm));
}
/** 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. */
public TestParametersBuilder withDexRuntimes() {
return withDexRuntimeFilter(vm -> true);
}
/** Add specific runtime if available. */
public TestParametersBuilder withDexRuntime(DexVm.Version runtime) {
return withDexRuntimeFilter(vm -> vm == runtime);
}
/** Add all available CF runtimes between {@param startInclusive} and {@param endInclusive}. */
public TestParametersBuilder withDexRuntimes(
DexVm.Version startInclusive, DexVm.Version endInclusive) {
return withDexRuntimeFilter(
vm -> startInclusive.isOlderThanOrEqual(vm) && vm.isOlderThanOrEqual(endInclusive));
}
/** Add all available DEX runtimes that support native multidex. */
public TestParametersBuilder withNativeMultidexDexRuntimes() {
return withDexRuntimesStartingFromIncluding(DexVm.Version.V5_1_1);
}
/** Add all available DEX runtimes starting from and including {@param startInclusive}. */
public TestParametersBuilder withDexRuntimesStartingFromIncluding(DexVm.Version startInclusive) {
return withDexRuntimeFilter(vm -> startInclusive.isOlderThanOrEqual(vm));
}
/** Add all available DEX runtimes starting from and excluding {@param startExcluding}. */
public TestParametersBuilder withDexRuntimesStartingFromExcluding(DexVm.Version startExcluding) {
return withDexRuntimeFilter(
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));
}
/** 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 TestParametersCollection build() {
return new TestParametersCollection(
getAvailableRuntimes()
.map(TestParameters::new)
.filter(filter)
.collect(Collectors.toList()));
}
// Public method to check that the CF runtime coincides with the system runtime.
public static boolean isSystemJdk(CfVm vm) {
String version = System.getProperty("java.version");
switch (vm) {
case JDK8:
return version.startsWith("1.8.");
case JDK9:
return version.startsWith("9.");
}
throw new Unreachable();
}
// Currently the only supported VM is the system VM. This should be extended to start supporting
// the checked in versions too, making it possible to run tests on more than one JDK at a time.
private static boolean isSupportedJdk(CfVm vm) {
return isSystemJdk(vm);
}
private static Stream<TestRuntime> getAvailableRuntimes() {
String runtimesProperty = System.getProperty("runtimes");
Stream<TestRuntime> runtimes;
if (runtimesProperty != null) {
runtimes =
Arrays.stream(runtimesProperty.split(":"))
.filter(s -> !s.isEmpty())
.map(
name -> {
TestRuntime runtime = TestRuntime.fromName(name);
if (runtime != null) {
return runtime;
}
throw new RuntimeException("Unexpected runtime property name: " + name);
});
} else {
runtimes =
Stream.concat(
Stream.of(NoneRuntime.getInstance()),
Stream.concat(
Arrays.stream(TestRuntime.CfVm.values()).map(CfRuntime::new),
Arrays.stream(DexVm.Version.values()).map(DexRuntime::new)));
}
// TODO(b/127785410) Support multiple VMs at the same time.
return runtimes.filter(runtime -> !runtime.isCf() || isSupportedJdk(runtime.asCf().getVm()));
}
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());
}
}