[Metadata] Add test for compiling old R8'ed metadata with new kotlinc
Bug: 187781614
Change-Id: I3cb2c1da60402cc37d26c3a2166fb68ce8e3bf52
diff --git a/src/test/java/com/android/tools/r8/KotlinCompilerTool.java b/src/test/java/com/android/tools/r8/KotlinCompilerTool.java
index 61efff1..f830f0e 100644
--- a/src/test/java/com/android/tools/r8/KotlinCompilerTool.java
+++ b/src/test/java/com/android/tools/r8/KotlinCompilerTool.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.utils.ArrayUtils;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.structural.Ordered;
import java.io.IOException;
@@ -39,6 +40,10 @@
KotlinCompilerVersion(String folder) {
this.folder = folder;
}
+
+ public static KotlinCompilerVersion latest() {
+ return ArrayUtils.last(values());
+ }
}
public static final class KotlinCompiler {
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataFirstToLatestTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataFirstToLatestTest.java
new file mode 100644
index 0000000..c16c2f5
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataFirstToLatestTest.java
@@ -0,0 +1,135 @@
+// Copyright (c) 2021, 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.kotlin.metadata;
+
+import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar;
+import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar;
+import static org.hamcrest.CoreMatchers.equalTo;
+
+import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler;
+import com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion;
+import com.android.tools.r8.KotlinTestParameters;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.StringUtils;
+import java.nio.file.Path;
+import java.util.Collection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/**
+ * Kotlin has limited support for metadata of older versions. In particular, kotlinc 1.5 has
+ * deprecated byte-code version which is expected by kotlinc 1.3. The expectation is that if we
+ * compile with kotlinc 1.3 and then compile with R8 with a new version of the kolin-metadata-jvm
+ * library, the kotlin library is no longer usable in kotlinc 1.3. However, it should be usable in
+ * kotlinc 1.5.
+ */
+@RunWith(Parameterized.class)
+public class MetadataFirstToLatestTest extends KotlinMetadataTestBase {
+
+ private final String EXPECTED = StringUtils.lines("foo");
+ private static final String PKG_LIB = PKG + ".crossinline_anon_lib";
+ private static final String PKG_APP = PKG + ".crossinline_anon_app";
+ private final TestParameters parameters;
+
+ private static final KotlinCompileMemoizer libJars =
+ getCompileMemoizer(
+ getKotlinFileInTest(DescriptorUtils.getBinaryNameFromJavaType(PKG_LIB), "lib"));
+
+ @Parameterized.Parameters(name = "{0}, {1}")
+ public static Collection<Object[]> data() {
+ return buildParameters(
+ getTestParameters().withCfRuntimes().build(),
+ getKotlinTestParameters()
+ .withCompiler(KotlinCompilerVersion.KOTLINC_1_3_72)
+ .withAllTargetVersions()
+ .build());
+ }
+
+ public MetadataFirstToLatestTest(
+ TestParameters parameters, KotlinTestParameters kotlinParameters) {
+ super(kotlinParameters);
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void smokeTest() throws Exception {
+ runTest(
+ KotlinCompilerVersion.KOTLINC_1_5_0,
+ libJars.getForConfiguration(kotlinc, targetVersion),
+ getKotlinStdlibJar(kotlinc));
+ }
+
+ @Test
+ public void testOnFirst() throws Exception {
+ Path libJar =
+ testForR8(parameters.getBackend())
+ .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion))
+ .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc))
+ .addKeepAllClassesRule()
+ .addKeepAllAttributes()
+ .compile()
+ .writeToZip();
+ Path stdLibJar =
+ testForR8(parameters.getBackend())
+ .addProgramFiles(
+ ToolHelper.getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinAnnotationJar(kotlinc))
+ .addKeepAllClassesRule()
+ .addKeepAllAttributes()
+ .allowDiagnosticWarningMessages()
+ .compile()
+ .assertAllWarningMessagesMatch(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
+ .writeToZip();
+ // TODO(b/187781614): This is expected to fail when upgrading.
+ runTest(KotlinCompilerVersion.KOTLINC_1_3_72, libJar, stdLibJar);
+ }
+
+ @Test
+ public void testOnLatest() throws Exception {
+ Path libJar =
+ testForR8(parameters.getBackend())
+ .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion))
+ .addClasspathFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc))
+ .addKeepAllClassesRule()
+ .addKeepAllAttributes()
+ .compile()
+ .writeToZip();
+ Path stdLibJar =
+ testForR8(parameters.getBackend())
+ .addProgramFiles(
+ ToolHelper.getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinAnnotationJar(kotlinc))
+ .addKeepAllClassesRule()
+ .addKeepAllAttributes()
+ .allowDiagnosticWarningMessages()
+ .compile()
+ .assertAllWarningMessagesMatch(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
+ .writeToZip();
+ runTest(KotlinCompilerVersion.KOTLINC_1_5_0, libJar, stdLibJar);
+ }
+
+ private void runTest(KotlinCompilerVersion kotlinCompilerVersion, Path libJar, Path stdLibJar)
+ throws Exception {
+ Path output =
+ kotlinc(
+ parameters.getRuntime().asCf(),
+ new KotlinCompiler(kotlinCompilerVersion),
+ targetVersion)
+ .addClasspathFiles(libJar, stdLibJar)
+ .addSourceFiles(
+ getKotlinFileInTest(DescriptorUtils.getBinaryNameFromJavaType(PKG_APP), "main"))
+ .setOutputPath(temp.newFolder().toPath())
+ .noStdLib()
+ .compile();
+ testForJvm()
+ .addRunClasspathFiles(stdLibJar, libJar)
+ .addClasspath(output)
+ .run(parameters.getRuntime(), PKG_APP + ".MainKt")
+ .assertSuccessWithOutput(EXPECTED);
+ }
+}