blob: c7d7c3ab20fdb405ca7947667af4185f09da75f8 [file] [log] [blame]
// Copyright (c) 2023, 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.desugar.desugaredlibrary.jdktests;
import static com.android.tools.r8.ToolHelper.JDK_TESTS_BUILD_DIR;
import static com.android.tools.r8.desugar.desugaredlibrary.jdktests.Jdk11SupportFiles.testNGSupportProgramFiles;
import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.D8_L8DEBUG;
import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.D8_L8SHRINK;
import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK11;
import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK11_MINIMAL;
import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK11_PATH;
import static com.android.tools.r8.utils.FileUtils.CLASS_EXTENSION;
import static com.android.tools.r8.utils.FileUtils.JAVA_EXTENSION;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import com.android.tools.r8.SingleTestRunResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
import com.android.tools.r8.desugar.desugaredlibrary.test.DesugaredLibraryTestCompileResult;
import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class Jdk11ConcurrentLinkedQueueTests extends DesugaredLibraryTestBase {
private static final String WHITEBOX = "WhiteBox";
private static Path[] JDK_11_CONCURRENT_LINKED_QUEUE_TEST_CLASS_FILES;
// JDK 11 test constants.
private static final Path JDK_11_CONCURRENT_LINKED_QUEUE_JAVA_DIR =
Paths.get(ToolHelper.JDK_11_TESTS_DIR + "java/util/concurrent/ConcurrentLinkedQueue");
private static final Path[] JDK_11_CONCURRENT_LINKED_QUEUE_JAVA_FILES =
new Path[] {JDK_11_CONCURRENT_LINKED_QUEUE_JAVA_DIR.resolve(WHITEBOX + JAVA_EXTENSION)};
@Parameter(0)
public static TestParameters parameters;
@Parameter(1)
public static LibraryDesugaringSpecification libraryDesugaringSpecification;
@Parameter(2)
public static CompilationSpecification compilationSpecification;
@Parameters(name = "{0}, spec: {1}, {2}")
public static List<Object[]> data() {
return buildParameters(
// TODO(134732760): Support Dalvik VMs, currently fails because libjavacrypto is required
// and present only in ART runtimes.
getTestParameters()
.withDexRuntimesStartingFromIncluding(Version.V5_1_1)
.withAllApiLevels()
.withApiLevel(AndroidApiLevel.N)
.build(),
ImmutableList.of(JDK11_MINIMAL, JDK11, JDK11_PATH),
ImmutableSet.of(D8_L8DEBUG, D8_L8SHRINK));
}
@BeforeClass
public static void compileConcurrentLinkedQueueClasses() throws Exception {
// Build test constants.
Path jdk11MathTestsDir = getStaticTemp().newFolder("ConcurrentLinkedQueue").toPath();
javac(TestRuntime.getCheckedInJdk11(), getStaticTemp())
.addClasspathFiles(
Collections.singletonList(Paths.get(JDK_TESTS_BUILD_DIR + "testng-6.10.jar")))
.addSourceFiles(JDK_11_CONCURRENT_LINKED_QUEUE_JAVA_FILES)
.setOutputPath(jdk11MathTestsDir)
.compile();
JDK_11_CONCURRENT_LINKED_QUEUE_TEST_CLASS_FILES =
new Path[] {jdk11MathTestsDir.resolve(WHITEBOX + CLASS_EXTENSION)};
}
private void inspect(CodeInspector inspector) {
// Right now we only expect one backport coming out of DesugarVarHandle - the backport with
// forwarding of Unsafe.compareAndSwapObject.
MethodReference firstBackportFromDesugarVarHandle =
SyntheticItemsTestUtils.syntheticBackportWithForwardingMethod(
Reference.classFromDescriptor("Lj$/com/android/tools/r8/DesugarVarHandle;"),
0,
Reference.method(
Reference.classFromDescriptor("Lsun/misc/Unsafe;"),
"compareAndSwapObject",
ImmutableList.of(
Reference.typeFromDescriptor("Ljava/lang/Object;"),
Reference.LONG,
Reference.typeFromDescriptor("Ljava/lang/Object;"),
Reference.typeFromDescriptor("Ljava/lang/Object;")),
Reference.BOOL));
assertThat(
inspector.clazz(
DescriptorUtils.descriptorToJavaType(DexItemFactory.varHandleDescriptorString)),
not(isPresent()));
assertThat(
inspector.clazz(
DescriptorUtils.descriptorToJavaType(
DexItemFactory.methodHandlesLookupDescriptorString)),
not(isPresent()));
assertThat(
inspector.clazz(
"j$." + DescriptorUtils.descriptorToJavaType(DexItemFactory.varHandleDescriptorString)),
not(isPresent()));
assertThat(
inspector.clazz(
"j$."
+ DescriptorUtils.descriptorToJavaType(
DexItemFactory.methodHandlesLookupDescriptorString)),
not(isPresent()));
assertThat(
inspector.clazz(
DescriptorUtils.descriptorToJavaType(DexItemFactory.desugarVarHandleDescriptorString)),
not(isPresent()));
assertThat(
inspector.clazz(
DescriptorUtils.descriptorToJavaType(
DexItemFactory.desugarMethodHandlesLookupDescriptorString)),
not(isPresent()));
boolean usesNativeVarHandle =
parameters.asDexRuntime().getVersion().isNewerThanOrEqual(Version.V13_0_0)
&& parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.T);
assertThat(
inspector.clazz(
"j$."
+ DescriptorUtils.descriptorToJavaType(
DexItemFactory.desugarVarHandleDescriptorString)),
usesNativeVarHandle ? not(isPresent()) : isPresent());
assertThat(
inspector.clazz(firstBackportFromDesugarVarHandle.getHolderClass()),
usesNativeVarHandle ? not(isPresent()) : isPresent());
// Currently DesugarMethodHandlesLookup this is fully inlined by R8.
assertThat(
inspector.clazz(
"j$."
+ DescriptorUtils.descriptorToJavaType(
DexItemFactory.desugarMethodHandlesLookupDescriptorString)),
usesNativeVarHandle || compilationSpecification.isL8Shrink()
? not(isPresent())
: isPresent());
}
void runTest(List<String> toRun) throws Exception {
// Skip test with minimal configuration before API level 24, as the test use stream.
assumeTrue(
libraryDesugaringSpecification != JDK11_MINIMAL
|| parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.N));
String verbosity = "2";
DesugaredLibraryTestCompileResult<?> compileResult =
testForDesugaredLibrary(
parameters, libraryDesugaringSpecification, compilationSpecification)
.addProgramFiles(JDK_11_CONCURRENT_LINKED_QUEUE_TEST_CLASS_FILES)
.addProgramFiles(testNGSupportProgramFiles())
// The WhiteBox test is using VarHandle and MethodHandles.privateLookupIn to inspect the
// internal state of the implementation, so desugaring is needed for the program here.
.addOptionsModification(options -> options.enableVarHandleDesugaring = true)
.compile()
.inspectL8(this::inspect)
.withArt6Plus64BitsLib();
for (String success : toRun) {
SingleTestRunResult<?> result =
compileResult.run(parameters.getRuntime(), "TestNGMainRunner", verbosity, success);
assertTrue(
"Failure in " + success + "\n" + result,
result.getStdOut().contains(StringUtils.lines(success + ": SUCCESS")));
}
}
@Test
public void testWhiteBox() throws Exception {
runTest(ImmutableList.of("WhiteBox"));
}
}