Multi-JDKS support for tests in Intellij

Introduced a checkedin jdk8 version from aosp and change the tests so that within IntelliJ running the tests runs the tests on all checked ins JDKs based on parameters. Also refactored one runJava method to avoid code duplication. A follow-up on this would be to port old tests to new APIs and avoid using default JDK/Dex runtimes

Change-Id: Ifa86f0a041e818029dd050a8f5a48703e8a46551
diff --git a/.gitignore b/.gitignore
index dd39fad..9432723 100644
--- a/.gitignore
+++ b/.gitignore
@@ -95,6 +95,10 @@
 third_party/openjdk/openjdk-9.0.4/osx.tar.gz
 third_party/openjdk/openjdk-9.0.4/windows
 third_party/openjdk/openjdk-9.0.4/windows.tar.gz
+third_party/openjdk/jdk8/linux-x86
+third_party/openjdk/jdk8/darwin-x86
+third_party/openjdk/jdk8/linux-x86.tar.gz
+third_party/openjdk/jdk8/darwin-x86.tar.gz
 third_party/openjdk/openjdk-rt-1.8
 third_party/openjdk/openjdk-rt-1.8.tar.gz
 third_party/r8
diff --git a/build.gradle b/build.gradle
index cbfae61..4b8b793 100644
--- a/build.gradle
+++ b/build.gradle
@@ -303,10 +303,12 @@
 
 def cloudSystemDependencies = [
         linux: [
-                "third_party": ["openjdk/openjdk-9.0.4/linux"],
+                "third_party": ["openjdk/openjdk-9.0.4/linux",
+                                "openjdk/jdk8/linux-x86"],
         ],
         osx: [
-                "third_party": ["openjdk/openjdk-9.0.4/osx"],
+                "third_party": ["openjdk/openjdk-9.0.4/osx",
+                                "openjdk/jdk8/darwin-x86"],
         ],
         windows: [
                 "third_party": ["openjdk/openjdk-9.0.4/windows"],
diff --git a/src/test/java/com/android/tools/r8/JvmTestBuilder.java b/src/test/java/com/android/tools/r8/JvmTestBuilder.java
index 2eaa6cd..c57dd27 100644
--- a/src/test/java/com/android/tools/r8/JvmTestBuilder.java
+++ b/src/test/java/com/android/tools/r8/JvmTestBuilder.java
@@ -115,8 +115,7 @@
 
   public JvmTestRunResult run(TestRuntime runtime, String mainClass) throws IOException {
     assert runtime.isCf();
-    assert TestParametersBuilder.isSystemJdk(runtime.asCf().getVm());
-    ProcessResult result = ToolHelper.runJava(classpath, mainClass);
+    ProcessResult result = ToolHelper.runJava(runtime.asCf().getVm(), classpath, mainClass);
     return new JvmTestRunResult(builder.build(), result);
   }
 
diff --git a/src/test/java/com/android/tools/r8/TestCompileResult.java b/src/test/java/com/android/tools/r8/TestCompileResult.java
index c03c10e..106cfac 100644
--- a/src/test/java/com/android/tools/r8/TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/TestCompileResult.java
@@ -65,7 +65,10 @@
       case DEX:
         return runArt(null, additionalRunClassPath, mainClassSubject.getFinalName());
       case CF:
-        return runJava(null, additionalRunClassPath, mainClassSubject.getFinalName());
+        return runJava(
+            TestRuntime.getDefaultJavaRuntime(),
+            additionalRunClassPath,
+            mainClassSubject.getFinalName());
       default:
         throw new Unreachable();
     }
@@ -214,15 +217,15 @@
 
   private RR runJava(TestRuntime runtime, List<Path> additionalClassPath, String... arguments)
       throws IOException {
-    // TODO(b/127785410): Always assume a non-null runtime.
-    assert runtime == null || TestParametersBuilder.isSystemJdk(runtime.asCf().getVm());
+    assert runtime != null;
     Path out = state.getNewTempFolder().resolve("out.zip");
     app.writeToZip(out, OutputMode.ClassFile);
     List<Path> classPath = ImmutableList.<Path>builder()
         .addAll(additionalClassPath)
         .add(out)
         .build();
-    ProcessResult result = ToolHelper.runJava(vmArguments, classPath, arguments);
+    ProcessResult result =
+        ToolHelper.runJava(runtime.asCf().getVm(), vmArguments, classPath, arguments);
     return createRunResult(result);
   }
 
diff --git a/src/test/java/com/android/tools/r8/TestParametersBuilder.java b/src/test/java/com/android/tools/r8/TestParametersBuilder.java
index 89f071a..ad35541 100644
--- a/src/test/java/com/android/tools/r8/TestParametersBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestParametersBuilder.java
@@ -183,8 +183,9 @@
 
   // 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);
+    return isSystemJdk(vm) || TestRuntime.CHECKED_IN_JDKS.containsKey(vm);
   }
 
   private static Stream<TestRuntime> getAvailableRuntimes() {
diff --git a/src/test/java/com/android/tools/r8/TestRuntime.java b/src/test/java/com/android/tools/r8/TestRuntime.java
index cd0bd3f..66c6ec1 100644
--- a/src/test/java/com/android/tools/r8/TestRuntime.java
+++ b/src/test/java/com/android/tools/r8/TestRuntime.java
@@ -7,6 +7,9 @@
 import com.android.tools.r8.ToolHelper.DexVm;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.utils.AndroidApiLevel;
+import com.google.common.collect.ImmutableMap;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 
 // Base class for the runtime structure in the test parameters.
 public class TestRuntime {
@@ -70,6 +73,26 @@
     }
   }
 
+  // Values are the path in third_party/openjdk to the repository with bin"
+  public static ImmutableMap<CfVm, Path> CHECKED_IN_JDKS =
+      ImmutableMap.of(
+          CfVm.JDK8,
+          Paths.get("jdk8", "linux-x86"),
+          CfVm.JDK9,
+          Paths.get("openjdk-9.0.4", "linux"));
+
+  public static Path getCheckInJDKPathFor(CfVm jdk) {
+    assert ToolHelper.isLinux();
+    return Paths.get("third_party", "openjdk")
+        .resolve(CHECKED_IN_JDKS.get(jdk))
+        .resolve(Paths.get("bin", "java"));
+  }
+
+  public static TestRuntime getDefaultJavaRuntime() {
+    // For compatibility with old tests not specifying a Java runtime
+    return new CfRuntime(CfVm.JDK9);
+  }
+
   public static class NoneRuntime extends TestRuntime {
 
     private static final String NAME = "none";
@@ -89,6 +112,7 @@
 
   // Wrapper for the DEX runtimes.
   public static class DexRuntime extends TestRuntime {
+
     private final DexVm vm;
 
     public DexRuntime(DexVm.Version version) {
@@ -126,6 +150,7 @@
 
   // Wrapper for the CF runtimes.
   public static class CfRuntime extends TestRuntime {
+
     private final CfVm vm;
 
     public CfRuntime(CfVm vm) {
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index e8b0202..25f021f 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -11,6 +11,7 @@
 
 import com.android.tools.r8.DeviceRunner.DeviceRunnerConfigurationException;
 import com.android.tools.r8.TestBase.Backend;
+import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.ToolHelper.DexVm.Kind;
 import com.android.tools.r8.dex.ApplicationReader;
 import com.android.tools.r8.errors.Unreachable;
@@ -1103,19 +1104,24 @@
   }
 
   public static ProcessResult runJava(List<Path> classpath, String... args) throws IOException {
-    String cp =
-        classpath.stream().map(Path::toString).collect(Collectors.joining(CLASSPATH_SEPARATOR));
-    List<String> cmdline = new ArrayList<String>(Arrays.asList(getJavaExecutable(), "-cp", cp));
-    cmdline.addAll(Arrays.asList(args));
-    ProcessBuilder builder = new ProcessBuilder(cmdline);
-    return runProcess(builder);
+    return runJava(ImmutableList.of(), classpath, args);
   }
 
   public static ProcessResult runJava(List<String> vmArgs, List<Path> classpath, String... args)
       throws IOException {
+    return runJava(null, vmArgs, classpath, args);
+  }
+
+  public static ProcessResult runJava(CfVm runtime, List<Path> classpath, String... args)
+      throws IOException {
+    return runJava(runtime, ImmutableList.of(), classpath, args);
+  }
+
+  public static ProcessResult runJava(
+      CfVm runtime, List<String> vmArgs, List<Path> classpath, String... args) throws IOException {
     String cp =
         classpath.stream().map(Path::toString).collect(Collectors.joining(CLASSPATH_SEPARATOR));
-    List<String> cmdline = new ArrayList<String>(Arrays.asList(getJavaExecutable()));
+    List<String> cmdline = new ArrayList<String>(Arrays.asList(getJavaExecutable(runtime)));
     cmdline.addAll(vmArgs);
     cmdline.add("-cp");
     cmdline.add(cp);
@@ -1201,10 +1207,26 @@
     return runProcess(new ProcessBuilder(command).directory(dir.toFile()));
   }
 
+  @Deprecated
+  // Use getJavaExecutable(CfVm) to specify a JDK version or getSystemJavaExecutable
   public static String getJavaExecutable() {
+    return getSystemJavaExecutable();
+  }
+
+  public static String getSystemJavaExecutable() {
     return Paths.get(System.getProperty("java.home"), "bin", "java").toString();
   }
 
+  public static String getJavaExecutable(CfVm runtime) {
+    if (TestRuntime.CHECKED_IN_JDKS.containsKey(runtime)) {
+      return TestRuntime.getCheckInJDKPathFor(runtime).toString();
+    } else {
+      // TODO(b/127785410): Always assume a non-null runtime.
+      assert runtime == null || TestParametersBuilder.isSystemJdk(runtime);
+      return getSystemJavaExecutable();
+    }
+  }
+
   public static ProcessResult runArtRaw(ArtCommandBuilder builder) throws IOException {
     return runArtProcessRaw(builder);
   }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetSimpleNameTest.java b/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetSimpleNameTest.java
index 45f0ee7..beed662 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetSimpleNameTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetSimpleNameTest.java
@@ -15,6 +15,7 @@
 import com.android.tools.r8.R8TestRunResult;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestRunResult;
+import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
@@ -249,7 +250,7 @@
             .addOptionsModification(this::configure)
             .run(parameters.getRuntime(), MAIN);
     if (enableMinification) {
-      if (parameters.getBackend() == Backend.CF && ToolHelper.isJava8Runtime()) {
+      if (parameters.isCfRuntime() && parameters.getRuntime().asCf().getVm() == CfVm.JDK8) {
         // TODO(b/120639028): Incorrect inner-class structure fails on JVM prior to JDK 9.
         result.assertFailureWithErrorThatMatches(containsString("Malformed class name"));
         return;
diff --git a/third_party/openjdk/jdk8/darwin-x86.tar.gz.sha1 b/third_party/openjdk/jdk8/darwin-x86.tar.gz.sha1
new file mode 100644
index 0000000..fc50e9e
--- /dev/null
+++ b/third_party/openjdk/jdk8/darwin-x86.tar.gz.sha1
@@ -0,0 +1 @@
+44ba5f306fa1616a620a827590a78dbe36ad8cc6
\ No newline at end of file
diff --git a/third_party/openjdk/jdk8/linux-x86.tar.gz.sha1 b/third_party/openjdk/jdk8/linux-x86.tar.gz.sha1
new file mode 100644
index 0000000..8bb0afb
--- /dev/null
+++ b/third_party/openjdk/jdk8/linux-x86.tar.gz.sha1
@@ -0,0 +1 @@
+27bfc31a3ee6d304ce97dbc006d6af54de8c1099
\ No newline at end of file