Use prebuilt dex version of JDWP in debug tests.

Testing D8 compilation of JDWP is done by RunJdwpTest which will D8-compile JDWP
and run the set of smoke tests with both the debugger and debuggee being run on
ART.

Change-Id: Ib671fc6d17f7ed193bd8cc13d10b983530a5fd4f
diff --git a/build.gradle b/build.gradle
index 8a5830d..7fcbda6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1165,6 +1165,23 @@
     includeEmptyDirs = false
 }
 
+task buildPreNJdwpTestsDex(type: Exec, dependsOn: "buildPreNJdwpTestsJar") {
+    def inFile = buildPreNJdwpTestsJar.archivePath
+    def outFile = new File(buildPreNJdwpTestsJar.destinationDir, buildPreNJdwpTestsJar.baseName + '-dex.jar')
+    inputs.file inFile
+    outputs.file outFile
+    if (OperatingSystem.current().isWindows()) {
+        executable file("tools/windows/dx/bin/dx.bat")
+    } else if (OperatingSystem.current().isMacOsX()) {
+        executable file("tools/mac/dx/bin/dx");
+    } else {
+        executable file("tools/linux/dx/bin/dx");
+    }
+    args "--dex"
+    args "--output=${outFile}"
+    args inFile
+}
+
 task supportLibDir() {
     doLast {
         File dir = file("build/supportlibraries")
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 321e712..ea1a6c6 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -448,7 +448,7 @@
         minSdkVersion == AndroidApiLevel.getDefault().getLevel() ? DEFAULT_MIN_SDK : minSdkVersion);
   }
 
-  public static Path getJdwpTestsJarPath(int minSdk) {
+  public static Path getJdwpTestsCfJarPath(int minSdk) {
     if (minSdk >= AndroidApiLevel.N.getLevel()) {
       return Paths.get("third_party", "jdwp-tests", "apache-harmony-jdwp-tests-host.jar");
     } else {
@@ -456,6 +456,14 @@
     }
   }
 
+  public static Path getJdwpTestsDexJarPath(int minSdk) {
+    if (minSdk >= AndroidApiLevel.N.getLevel()) {
+      return Paths.get("third_party", "jdwp-tests", "apache-harmony-jdwp-tests-hostdex.jar");
+    } else {
+      return Paths.get(ToolHelper.BUILD_DIR, "libs", "jdwp-tests-preN-dex.jar");
+    }
+  }
+
   static class RetainedTemporaryFolder extends TemporaryFolder {
 
     RetainedTemporaryFolder(java.io.File parentFolder) {
diff --git a/src/test/java/com/android/tools/r8/debug/BlockReorderingTest.java b/src/test/java/com/android/tools/r8/debug/BlockReorderingTest.java
index cdc3ae4..4d4844f 100644
--- a/src/test/java/com/android/tools/r8/debug/BlockReorderingTest.java
+++ b/src/test/java/com/android/tools/r8/debug/BlockReorderingTest.java
@@ -29,11 +29,12 @@
   public static void setup() throws Exception {
     // Force inversion of all conditionals to reliably construct a regression test for incorrect
     // line information when reordering blocks.
-    d8Config = new D8DebugTestConfig(temp);
-    d8Config.compileAndAddPaths(
-        temp,
-        Collections.singletonList(DEBUGGEE_JAR),
-        options -> options.testing.invertConditionals = true);
+    d8Config =
+        new D8DebugTestConfig()
+            .compileAndAdd(
+                temp,
+                Collections.singletonList(DEBUGGEE_JAR),
+                options -> options.testing.invertConditionals = true);
   }
 
   @Test
diff --git a/src/test/java/com/android/tools/r8/debug/CfDebugTestConfig.java b/src/test/java/com/android/tools/r8/debug/CfDebugTestConfig.java
index ac1852c..6049b7d 100644
--- a/src/test/java/com/android/tools/r8/debug/CfDebugTestConfig.java
+++ b/src/test/java/com/android/tools/r8/debug/CfDebugTestConfig.java
@@ -10,9 +10,11 @@
 import java.util.Collections;
 import java.util.List;
 
+/** Base test configuration with CF version of JDWP. */
 public class CfDebugTestConfig extends DebugTestConfig {
 
-  public static final Path JDWP_JAR = ToolHelper.getJdwpTestsJarPath(AndroidApiLevel.N.getLevel());
+  public static final Path JDWP_JAR =
+      ToolHelper.getJdwpTestsCfJarPath(AndroidApiLevel.N.getLevel());
 
   public CfDebugTestConfig() {
     this(Collections.emptyList());
@@ -28,7 +30,7 @@
   }
 
   @Override
-  public RuntimeKind getRuntimeKind() {
+  public final RuntimeKind getRuntimeKind() {
     return RuntimeKind.CF;
   }
 }
diff --git a/src/test/java/com/android/tools/r8/debug/D8DebugTestConfig.java b/src/test/java/com/android/tools/r8/debug/D8DebugTestConfig.java
index 7e5ecc9..3edaaaf 100644
--- a/src/test/java/com/android/tools/r8/debug/D8DebugTestConfig.java
+++ b/src/test/java/com/android/tools/r8/debug/D8DebugTestConfig.java
@@ -11,30 +11,13 @@
 import com.android.tools.r8.utils.OutputMode;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.Collections;
+import java.util.Arrays;
 import java.util.List;
 import java.util.function.Consumer;
 import org.junit.rules.TemporaryFolder;
 
-/**
- * Base test configuration for running a DEX debuggee with a D8 compiled version of JDWP.
- *
- * <p>This class also provides utilities for compiling with D8 and adding it to the classpath.
- */
-public class D8DebugTestConfig extends DebugTestConfig {
-
-  public static final Path JDWP_JAR =
-      ToolHelper.getJdwpTestsJarPath(ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm()));
-
-  // Internal cache to avoid multiple compilations of the base JDWP code.
-  private static AndroidApp compiledJdwp = null;
-
-  private static synchronized AndroidApp getCompiledJdwp() {
-    if (compiledJdwp == null) {
-      compiledJdwp = d8Compile(Collections.singletonList(JDWP_JAR), null);
-    }
-    return compiledJdwp;
-  }
+/** Test configuration with utilities for compiling with D8 and adding results to the classpath. */
+public class D8DebugTestConfig extends DexDebugTestConfig {
 
   public static AndroidApp d8Compile(List<Path> paths, Consumer<InternalOptions> optionsConsumer) {
     try {
@@ -52,42 +35,21 @@
     }
   }
 
-  public static D8DebugTestConfig fromUncompiledPaths(TemporaryFolder temp, List<Path> paths) {
-    D8DebugTestConfig config = new D8DebugTestConfig(temp);
-    config.compileAndAddPaths(temp, paths);
-    return config;
+  public D8DebugTestConfig compileAndAdd(TemporaryFolder temp, Path... paths) {
+    return compileAndAdd(temp, Arrays.asList(paths), null);
   }
 
-  public static D8DebugTestConfig fromCompiledPaths(TemporaryFolder temp, List<Path> paths) {
-    D8DebugTestConfig config = new D8DebugTestConfig(temp);
-    config.addPaths(paths);
-    return config;
+  public D8DebugTestConfig compileAndAdd(TemporaryFolder temp, List<Path> paths) {
+    return compileAndAdd(temp, paths, null);
   }
 
-  public D8DebugTestConfig(TemporaryFolder temp) {
-    try {
-      Path out = temp.newFolder().toPath().resolve("d8_jdwp.jar");
-      getCompiledJdwp().write(out, OutputMode.Indexed);
-    } catch (Throwable e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  @Override
-  public RuntimeKind getRuntimeKind() {
-    return RuntimeKind.DEX;
-  }
-
-  public void compileAndAddPaths(TemporaryFolder temp, List<Path> paths) {
-    compileAndAddPaths(temp, paths, null);
-  }
-
-  public void compileAndAddPaths(
+  public D8DebugTestConfig compileAndAdd(
       TemporaryFolder temp, List<Path> paths, Consumer<InternalOptions> optionsConsumer) {
     try {
       Path out = temp.newFolder().toPath().resolve("d8_compiled.jar");
       d8Compile(paths, optionsConsumer).write(out, OutputMode.Indexed);
       addPaths(out);
+      return this;
     } catch (Exception e) {
       throw new RuntimeException(e);
     }
diff --git a/src/test/java/com/android/tools/r8/debug/D8DebugTestResourcesConfig.java b/src/test/java/com/android/tools/r8/debug/D8DebugTestResourcesConfig.java
index 4989df2..3534cad 100644
--- a/src/test/java/com/android/tools/r8/debug/D8DebugTestResourcesConfig.java
+++ b/src/test/java/com/android/tools/r8/debug/D8DebugTestResourcesConfig.java
@@ -22,7 +22,6 @@
   }
 
   public D8DebugTestResourcesConfig(TemporaryFolder temp) {
-    super(temp);
     try {
       Path path = temp.newFolder().toPath().resolve("d8_debug_test_resources.jar");
       getCompiledResources().write(path, OutputMode.Indexed);
diff --git a/src/test/java/com/android/tools/r8/debug/DebugInfoWhenInliningTest.java b/src/test/java/com/android/tools/r8/debug/DebugInfoWhenInliningTest.java
index a693f4e..cf7d10b 100644
--- a/src/test/java/com/android/tools/r8/debug/DebugInfoWhenInliningTest.java
+++ b/src/test/java/com/android/tools/r8/debug/DebugInfoWhenInliningTest.java
@@ -33,9 +33,7 @@
             .setOutputPath(outjar)
             .build(),
         options -> options.lineNumberOptimization = lineNumberOptimization);
-    DebugTestConfig config = new D8DebugTestConfig(temp);
-    config.addPaths(outjar);
-    return config;
+    return new DexDebugTestConfig(outjar);
   }
 
   @Test
diff --git a/src/test/java/com/android/tools/r8/debug/DexDebugTestConfig.java b/src/test/java/com/android/tools/r8/debug/DexDebugTestConfig.java
new file mode 100644
index 0000000..27e3d30
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/debug/DexDebugTestConfig.java
@@ -0,0 +1,35 @@
+// Copyright (c) 2017, 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.debug;
+
+import com.android.tools.r8.ToolHelper;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/** Base test configuration with DEX version of JDWP. */
+public class DexDebugTestConfig extends DebugTestConfig {
+
+  public static final Path JDWP_DEX_JAR =
+      ToolHelper.getJdwpTestsDexJarPath(ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm()));
+
+  public DexDebugTestConfig() {
+    this(Collections.emptyList());
+  }
+
+  public DexDebugTestConfig(Path... paths) {
+    this(Arrays.asList(paths));
+  }
+
+  public DexDebugTestConfig(List<Path> paths) {
+    addPaths(JDWP_DEX_JAR);
+    addPaths(paths);
+  }
+
+  @Override
+  public final RuntimeKind getRuntimeKind() {
+    return RuntimeKind.DEX;
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/debug/InterfaceMethodTest.java b/src/test/java/com/android/tools/r8/debug/InterfaceMethodTest.java
index c4cf839..c5c21a7 100644
--- a/src/test/java/com/android/tools/r8/debug/InterfaceMethodTest.java
+++ b/src/test/java/com/android/tools/r8/debug/InterfaceMethodTest.java
@@ -9,7 +9,6 @@
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -25,14 +24,8 @@
   @Parameters(name = "{0}")
   public static Collection configs() {
     ImmutableList.Builder<Object[]> builder = ImmutableList.builder();
-    DelayedDebugTestConfig cfConfig = temp -> {
-      DebugTestConfig config = new CfDebugTestConfig();
-      config.addPaths(JAR);
-      return config;
-    };
-    DelayedDebugTestConfig d8Config = temp -> {
-      return D8DebugTestConfig.fromUncompiledPaths(temp, Collections.singletonList(JAR));
-    };
+    DelayedDebugTestConfig cfConfig = temp -> new CfDebugTestConfig(JAR);
+    DelayedDebugTestConfig d8Config = temp -> new D8DebugTestConfig().compileAndAdd(temp, JAR);
     builder.add(new Object[]{"CF", cfConfig});
     builder.add(new Object[]{"D8", d8Config});
     return builder.build();
diff --git a/src/test/java/com/android/tools/r8/debug/JasminDebugTest.java b/src/test/java/com/android/tools/r8/debug/JasminDebugTest.java
index 91d97aa..f4ffc59 100644
--- a/src/test/java/com/android/tools/r8/debug/JasminDebugTest.java
+++ b/src/test/java/com/android/tools/r8/debug/JasminDebugTest.java
@@ -36,7 +36,7 @@
   public void testUselessCheckcastD8() throws Throwable {
     JasminBuilder builder = getBuilderForUselessCheckcast(className, methodName);
     List<Path> outputs = builder.writeClassFiles(temp.newFolder().toPath());
-    runUselessCheckcast(D8DebugTestConfig.fromUncompiledPaths(temp, outputs));
+    runUselessCheckcast(new D8DebugTestConfig().compileAndAdd(temp, outputs));
   }
 
   private void runUselessCheckcast(DebugTestConfig config) throws Throwable {
diff --git a/src/test/java/com/android/tools/r8/debug/KotlinDebugTestBase.java b/src/test/java/com/android/tools/r8/debug/KotlinDebugTestBase.java
index 065686c..cbbcfb0 100644
--- a/src/test/java/com/android/tools/r8/debug/KotlinDebugTestBase.java
+++ b/src/test/java/com/android/tools/r8/debug/KotlinDebugTestBase.java
@@ -4,14 +4,13 @@
 
 package com.android.tools.r8.debug;
 
-import com.android.tools.r8.CompilationMode;
-import com.android.tools.r8.D8Command;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.OutputMode;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import org.apache.harmony.jpda.tests.framework.jdwp.Frame.Variable;
 import org.apache.harmony.jpda.tests.framework.jdwp.Location;
@@ -32,21 +31,14 @@
 
     private static synchronized AndroidApp getCompiledResources() throws Throwable {
       if (compiledResources == null) {
-        int minSdk = ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm());
         compiledResources =
-            ToolHelper.runD8(
-                D8Command.builder()
-                    .addProgramFiles(DEBUGGEE_KOTLIN_JAR)
-                    .setMinApiLevel(minSdk)
-                    .setMode(CompilationMode.DEBUG)
-                    .addLibraryFiles(Paths.get(ToolHelper.getAndroidJar(minSdk)))
-                    .build());
+            D8DebugTestConfig.d8Compile(Collections.singletonList(DEBUGGEE_KOTLIN_JAR), null);
       }
       return compiledResources;
     }
 
     public KotlinD8Config(TemporaryFolder temp) {
-      super(temp);
+      super();
       try {
         Path out = temp.newFolder().toPath().resolve("d8_debug_test_resources_kotlin.jar");
         getCompiledResources().write(out, OutputMode.Indexed);
diff --git a/src/test/java/com/android/tools/r8/debug/LambdaTest.java b/src/test/java/com/android/tools/r8/debug/LambdaTest.java
index fc59c51..1b413ba 100644
--- a/src/test/java/com/android/tools/r8/debug/LambdaTest.java
+++ b/src/test/java/com/android/tools/r8/debug/LambdaTest.java
@@ -7,7 +7,6 @@
 import com.google.common.collect.ImmutableList;
 import java.nio.file.Path;
 import java.util.Collection;
-import java.util.Collections;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -24,14 +23,8 @@
   @Parameters(name = "{0}")
   public static Collection configs() {
     ImmutableList.Builder<Object[]> builder = ImmutableList.builder();
-    DelayedDebugTestConfig cfConfig = temp -> {
-      DebugTestConfig config = new CfDebugTestConfig();
-      config.addPaths(JAR);
-      return config;
-    };
-    DelayedDebugTestConfig d8Config = temp -> {
-      return D8DebugTestConfig.fromUncompiledPaths(temp, Collections.singletonList(JAR));
-    };
+    DelayedDebugTestConfig cfConfig = temp -> new CfDebugTestConfig(JAR);
+    DelayedDebugTestConfig d8Config = temp -> new D8DebugTestConfig().compileAndAdd(temp, JAR);
     builder.add(new Object[]{"CF", cfConfig});
     builder.add(new Object[]{"D8", d8Config});
     return builder.build();
diff --git a/src/test/java/com/android/tools/r8/debug/LineNumberOptimizationTest.java b/src/test/java/com/android/tools/r8/debug/LineNumberOptimizationTest.java
index b5221f2..0f6975b 100644
--- a/src/test/java/com/android/tools/r8/debug/LineNumberOptimizationTest.java
+++ b/src/test/java/com/android/tools/r8/debug/LineNumberOptimizationTest.java
@@ -33,7 +33,7 @@
           options.lineNumberOptimization = lineNumberOptimization;
           options.inlineAccessors = false;
         });
-    DebugTestConfig config = new D8DebugTestConfig(temp);
+    DebugTestConfig config = new D8DebugTestConfig();
     config.addPaths(outjar);
     return config;
   }
diff --git a/src/test/java/com/android/tools/r8/debug/MinificationTest.java b/src/test/java/com/android/tools/r8/debug/MinificationTest.java
index e2d366a..7acd0e0 100644
--- a/src/test/java/com/android/tools/r8/debug/MinificationTest.java
+++ b/src/test/java/com/android/tools/r8/debug/MinificationTest.java
@@ -84,9 +84,7 @@
     }
     ToolHelper.runR8(builder.build());
 
-    D8DebugTestConfig config =
-        D8DebugTestConfig.fromCompiledPaths(
-            temp, Collections.singletonList(dexOutputDir.resolve("classes.dex")));
+    DexDebugTestConfig config = new DexDebugTestConfig(dexOutputDir.resolve("classes.dex"));
     config.setProguardMap(proguardMap);
     return config;
   }
diff --git a/src/test/java/com/android/tools/r8/debug/SmaliDebugTest.java b/src/test/java/com/android/tools/r8/debug/SmaliDebugTest.java
index e830164..262297c 100644
--- a/src/test/java/com/android/tools/r8/debug/SmaliDebugTest.java
+++ b/src/test/java/com/android/tools/r8/debug/SmaliDebugTest.java
@@ -46,7 +46,7 @@
   public void testSimpleIf() throws Throwable {
     String methodName = "simpleIf";
     runDebugTest(
-        D8DebugTestConfig.fromCompiledPaths(temp, buildSimpleIf(methodName)),
+        new DexDebugTestConfig(buildSimpleIf(methodName)),
         CLASS,
         breakpoint(CLASS, methodName),
         run(),
@@ -129,7 +129,7 @@
 
     // Run debugger to verify that we step to line 4 and the values of v0 and v1 are unchanged.
     runDebugTest(
-        D8DebugTestConfig.fromCompiledPaths(temp, outs),
+        new DexDebugTestConfig(outs),
         CLASS,
         breakpoint(CLASS, methodName),
         run(),
diff --git a/src/test/java/com/android/tools/r8/jdwp/RunJdwpTests.java b/src/test/java/com/android/tools/r8/jdwp/RunJdwpTests.java
index 4b011a2..9b5b618 100644
--- a/src/test/java/com/android/tools/r8/jdwp/RunJdwpTests.java
+++ b/src/test/java/com/android/tools/r8/jdwp/RunJdwpTests.java
@@ -29,11 +29,7 @@
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 
-/**
- * Wrapper for the art JDWP tests.
- *
- * A new version of this file can be generated using ./tools/create-jdwp-tests.py.
- */
+/** Wrapper for the art JDWP tests. */
 public class RunJdwpTests {
 
   enum Tool {
@@ -238,7 +234,7 @@
   public static void compileLibraries() throws Exception {
     // Selects appropriate jar according to min api level for the selected runtime.
     int minApi = ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm());
-    Path jdwpTestsJar = ToolHelper.getJdwpTestsJarPath(minApi);
+    Path jdwpTestsJar = ToolHelper.getJdwpTestsCfJarPath(minApi);
 
     d8Out = temp.newFolder("d8-out");
     D8.run(
diff --git a/src/test/java/com/android/tools/r8/naming/RenameSourceFileDebugTest.java b/src/test/java/com/android/tools/r8/naming/RenameSourceFileDebugTest.java
index 72444d2..461f408 100644
--- a/src/test/java/com/android/tools/r8/naming/RenameSourceFileDebugTest.java
+++ b/src/test/java/com/android/tools/r8/naming/RenameSourceFileDebugTest.java
@@ -6,13 +6,12 @@
 import com.android.tools.r8.CompilationMode;
 import com.android.tools.r8.R8Command;
 import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.debug.D8DebugTestConfig;
 import com.android.tools.r8.debug.DebugTestBase;
 import com.android.tools.r8.debug.DebugTestConfig;
+import com.android.tools.r8.debug.DexDebugTestConfig;
 import com.google.common.collect.ImmutableList;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.Collections;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
@@ -43,7 +42,7 @@
                   pg.addKeepAttributePatterns(ImmutableList.of("SourceFile", "LineNumberTable"));
                 })
             .build());
-    config = D8DebugTestConfig.fromCompiledPaths(temp, Collections.singletonList(outjar));
+    config = new DexDebugTestConfig(outjar);
   }
 
   /**