// 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;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import com.android.tools.r8.JctfTestSpecifications.Outcome;
import com.android.tools.r8.TestCondition.Runtime;
import com.android.tools.r8.TestCondition.RuntimeSet;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.TestRuntime.DexRuntime;
import com.android.tools.r8.ToolHelper.ArtCommandBuilder;
import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.ToolHelper.DexVm.Kind;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.ArtErrorParser;
import com.android.tools.r8.utils.ArtErrorParser.ArtErrorInfo;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.InternalOptions.LineNumberOptimization;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.TestDescriptionWatcher;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multimap;
import com.google.common.collect.ObjectArrays;
import com.google.common.collect.Sets;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.stream.Collectors;
import org.junit.ComparisonFailure;
import org.junit.Rule;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;

/**
 * This test class is not invoked directly. Instead, the gradle script generates one subclass per
 * actual art test. This allows us to run these in parallel.
 */
public abstract class R8RunArtTestsTest {

  private static final boolean DEX_COMPARE_WITH_DEX_REFERENCE_ON_FAILURE = true;

  private final String name;
  private final DexTool toolchain;

  @Rule
  public ExpectedException thrown = ExpectedException.none();
  private boolean expectedException = false;

  public enum DexTool {
    DX,
    NONE // Working directly on .class files.
  }

  public enum CompilerUnderTest {
    D8,
    R8,
    R8_AFTER_D8, // refers to the R8 (default: debug) step but implies a previous D8 step as well
    D8_AFTER_R8CF,
    R8CF
  }

  public static final String ART_TESTS_DIR = "tests/2017-10-04/art";
  private static final String ART_LEGACY_TESTS_DIR = "tests/2016-12-19/art/";
  private static final String ART_TESTS_NATIVE_LIBRARY_DIR = "tests/2017-10-04/art/lib64";
  private static final String ART_LEGACY_TESTS_NATIVE_LIBRARY_DIR = "tests/2016-12-19/art/lib64";

  private static final RuntimeSet LEGACY_RUNTIME = TestCondition.runtimes(
      DexVm.Version.V4_0_4,
      DexVm.Version.V4_4_4,
      DexVm.Version.V5_1_1,
      DexVm.Version.V6_0_1,
      DexVm.Version.V7_0_0,
      DexVm.Version.V8_1_0,
      DexVm.Version.V9_0_0,
      DexVm.Version.V10_0_0);

  // Input jar for jctf tests.
  private static final String JCTF_COMMON_JAR = "build/libs/jctfCommon.jar";

  // Parent dir for on-the-fly compiled jctf dex output.
  private static final String JCTF_TESTS_PREFIX = "build/classes/java/jctfTests";
  private static final String JCTF_TESTS_LIB_PREFIX =
      JCTF_TESTS_PREFIX + "/com/google/jctf/test/lib";
  private static final String JUNIT_TEST_RUNNER = "org.junit.runner.JUnitCore";
  private static final String JUNIT_JAR = "third_party/junit/junit-4.13-beta-2.jar";
  private static final String HAMCREST_JAR =
      "third_party/gradle/gradle/lib/plugins/hamcrest-core-1.3.jar";

  // Test that required to set min-api to a specific value.
  private static Map<String, AndroidApiLevel> needMinSdkVersion =
      new ImmutableMap.Builder<String, AndroidApiLevel>()
          .put("004-JniTest", AndroidApiLevel.N)
          // Has a non-abstract class with an abstract method.
          .put("800-smali", AndroidApiLevel.L)
          // Android O
          .put("952-invoke-custom", AndroidApiLevel.O)
          .put("952-invoke-custom-kinds", AndroidApiLevel.O)
          .put("953-invoke-polymorphic-compiler", AndroidApiLevel.O)
          .put("957-methodhandle-transforms", AndroidApiLevel.O)
          .put("958-methodhandle-stackframe", AndroidApiLevel.O)
          .put("959-invoke-polymorphic-accessors", AndroidApiLevel.O)
          .put("979-const-method-handle", AndroidApiLevel.P)
          .put("990-method-handle-and-mr", AndroidApiLevel.O)
          // Test intentionally asserts presence of bridge default methods desugar removes.
          .put("044-proxy", AndroidApiLevel.N)
          // Test intentionally asserts absence of default interface method in a class.
          .put("048-reflect-v8", AndroidApiLevel.N)
          // Uses default interface methods.
          .put("162-method-resolution", AndroidApiLevel.N)
          .put("616-cha-interface-default", AndroidApiLevel.N)
          .put("1910-transform-with-default", AndroidApiLevel.N)
          .put("960-default-smali", AndroidApiLevel.N)
          // Interface initializer is not triggered after desugaring.
          .put("962-iface-static", AndroidApiLevel.N)
          // Interface initializer is not triggered after desugaring.
          .put("964-default-iface-init-gen", AndroidApiLevel.N)
          .put("966-default-conflict", AndroidApiLevel.N)
          // AbstractMethodError (for method not implemented in class) instead of
          // IncompatibleClassChangeError (for conflict of default interface methods).
          .put("968-default-partial-compile-gen", AndroidApiLevel.N)
          // NoClassDefFoundError (for companion class) instead of NoSuchMethodError.
          .put("970-iface-super-resolution-gen", AndroidApiLevel.N)
          // NoClassDefFoundError (for companion class) instead of AbstractMethodError.
          .put("971-iface-super", AndroidApiLevel.N)
          // Test for miranda methods is not relevant for desugaring scenario.
          .put("972-default-imt-collision", AndroidApiLevel.N)
          // Uses default interface methods.
          .put("972-iface-super-multidex", AndroidApiLevel.N)
          // java.util.Objects is missing and test has default methods.
          .put("973-default-multidex", AndroidApiLevel.N)
          // a.klass.that.does.not.Exist is missing and test has default methods.
          .put("974-verify-interface-super", AndroidApiLevel.N)
          // Desugaring of interface private methods is not yet supported.
          .put("975-iface-private", AndroidApiLevel.N)
          .build();

  // Tests that timeout when run with Art.
  private static final Multimap<String, TestCondition> timeoutOrSkipRunWithArt =
      new ImmutableListMultimap.Builder<String, TestCondition>()
          // Loops on art - timeout.
          .put(
              "109-suspend-check",
              TestCondition.match(TestCondition.runtimes(DexVm.Version.V5_1_1)))
          // Flaky loops on art.
          .put("129-ThreadGetId", TestCondition.match(TestCondition.runtimes(DexVm.Version.V5_1_1)))
          // Takes ages to run on art 5.1.1 and behaves the same as on 6.0.1. Running this
          // tests on 5.1.1 makes our buildbot cycles time too long.
          .put("800-smali", TestCondition.match(TestCondition.runtimes(DexVm.Version.V5_1_1)))
          // Hangs on dalvik.
          .put(
              "802-deoptimization",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // TODO(b/144975341): Triage
          .put(
              "134-reg-promotion",
              TestCondition.match(TestCondition.runtimes(DexVm.Version.V10_0_0)))
          .build();

  // Tests that are flaky with the Art version we currently use.
  // TODO(zerny): Amend flaky tests with an expected flaky result to track issues.
  private static Multimap<String, TestCondition> flakyRunWithArt =
      new ImmutableListMultimap.Builder<String, TestCondition>()
          // Can crash but mostly passes
          // Crashes:
          // check_reference_map_visitor.h:44] At Main.f
          // Check failed: size() >= sizeof(T) (size()=0, sizeof(T)=1)
          // If art is passed -Xrelocate instead of -Xnorelocate the test passes.
          .put("004-ReferenceMap", TestCondition.any())
          // Also marked flaky in the art repo, sometimes hangs, sometimes fails with a segfault:
          // line 105: 23283 Segmentation fault
          .put("004-ThreadStress", TestCondition.any())
          // When it fails:
          // stack_walk_jni.cc:57] Check failed: 0xdU == GetDexPc() (0xdU=13, GetDexPc()=23)
          // The R8/D8 code does not produce code with the same instructions.
          .put("004-StackWalk", TestCondition.any())
          // Nothing ensures the weak-ref is not cleared between makeRef and
          // printWeakReference on lines Main.java:78-79. An expected flaky
          // result contains: "but was:<wimp: [null]".
          .put("036-finalizer", TestCondition.any())
          // The test waits for a maximum of 500 ms which is unreliable when running on buildbots:
          // Elapsed time was too long: elapsed=552 max=550
          .put("053-wait-some", TestCondition.any())
          // Failed on buildbot with: terminate called after throwing an instance
          // of '__gnu_cxx::recursive_init_error'
          .put("096-array-copy-concurrent-gc",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // Failing with: expected "second > first =[tru]e" was "second > first =[fals]e"
          .put("098-ddmc", TestCondition.match(TestCondition.runtimes(DexVm.Version.V6_0_1)))
          // Sometimes fails with out of memory on Dalvik.
          .put("114-ParallelGC",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // Seen crash: currently no more information
          .put("144-static-field-sigquit", TestCondition.any())
          // Opens a lot of file descriptors and depending on the state of the machine this
          // can crash art or not. Skip the run on art.
          .put("151-OpenFileLimit", TestCondition.any())
          // Can cause a segfault in the art vm 7.0.0
          // tools/linux/art-7.0.0/bin/art: line 105: 14395 Segmentation fault
          .put("607-daemon-stress", TestCondition.any())
          // Marked as flaky in the Art repository.
          .put("149-suspend-all-stress", TestCondition.any())
          .build();

  // Tests that are never compiled or run.
  private static List<String> skipAltogether = ImmutableList.of(
      // Those tests contains an invalid type hierarchy, which we cannot currently handle.
      "065-mismatched-implements",
      "066-mismatched-super",
      // This test contains invalid dex code that reads uninitialized registers after an
      // an instruction that would in any case throw (implicit via aget null 0).
      "706-jit-skip-compilation",
      // This test uses a user defined class loader to validate correct execution order
      // between loadclass event and the execution of a static method.
      // This does not work when performing inlining across classes.
      "496-checker-inlining-class-loader",
      // These all test OOM behavior and segfault doing GC on some machines. We just ignore them.
      "080-oom-throw",
      "080-oom-fragmentation",
      "159-app-image-fields",
      "163-app-image-methods",
      "061-out-of-memory",
      "617-clinit-oome"
  );

  // Tests that may produce different output on consecutive runs or when processed or not.
  private static List<String> outputMayDiffer = ImmutableList.of(
      // One some versions of art, this will print the address of the boot classloader, which
      // may change between runs.
      "506-verify-aput",
      // Art does fail during validation of dex files if it encounters an ill-typed virtual-invoke
      // but allows interface-invokes to pass. As we rewrite one kind into the other, we remove
      // a verification error and thus change output.
      "135-MirandaDispatch",
      // We resolve a conflicting definition of default methods, thus removing an ICCE.
      "972-iface-super-multidex"
  );

  // Tests that make use of agents/native code.
  // Our test setup does not handle flags/linking of these.
  private static List<String> usesNativeAgentCode = ImmutableList.of(
      "497-inlining-and-class-loader",
      "626-const-class-linking",
      "642-fp-callees",
      "660-clinit",
      "909-attach-agent",
      "914-hello-obsolescence",
      "915-obsolete-2",
      "916-obsolete-jit",
      "917-fields-transformation",
      "918-fields",
      "919-obsolete-fields",
      "920-objects",
      "921-hello-failure",
      "922-properties",
      "923-monitors",
      "924-threads",
      "925-threadgroups",
      "926-multi-obsolescence",
      "927-timers",
      "928-jni-table",
      "929-search",
      "930-hello-retransform",
      "931-agent-thread",
      "932-transform-saves",
      "933-misc-events",
      "934-load-transform",
      "935-non-retransformable",
      "936-search-onload",
      "937-hello-retransform-package",
      "938-load-transform-bcp",
      "939-hello-transformation-bcp",
      "940-recursive-obsolete",
      "941-recurive-obsolete-jit",
      "942-private-recursive",
      "943-private-recursive-jit",
      "944-transform-classloaders",
      "945-obsolete-native",
      "946-obsolete-throw",
      "947-reflect-method",
      "948-change-annotations",
      "949-in-memory-transform",
      "950-redefine-intrinsic",
      "951-threaded-obsolete",
      "980-redefine-object",
      "1900-track-alloc",
      "1901-get-bytecodes",
      "1902-suspend",
      "1903-suspend-self",
      "1904-double-suspend",
      "1906-suspend-list-me-first",
      "1907-suspend-list-self-twice",
      "1909-per-agent-tls",
      "1910-transform-with-default",
      "1911-get-local-var-table",
      "1912-get-set-local-primitive",
      "1913-get-set-local-objects",
      "1914-get-local-instance",
      "1915-get-set-local-current-thread",
      "1916-get-set-current-frame",
      "1917-get-stack-frame",
      "1919-vminit-thread-start-timing",
      "1920-suspend-native-monitor",
      "1921-suspend-native-recursive-monitor",
      "1922-owned-monitors-info",
      "1923-frame-pop",
      "1924-frame-pop-toggle",
      "1925-self-frame-pop",
      "1926-missed-frame-pop",
      "1927-exception-event",
      "1928-exception-event-exception",
      "1929-exception-catch-exception",
      "1930-monitor-info",
      "1931-monitor-events",
      "1932-monitor-events-misc",
      "1933-monitor-current-contended",
      "1934-jvmti-signal-thread",
      "1935-get-set-current-frame-jit",
      "1936-thread-end-events",
      // These tests need a library name as parameter
      "164-resolution-trampoline-dex-cache",
      "597-deopt-invoke-stub",
      "597-deopt-busy-loop",
      "661-oat-writer-layout",
      "661-classloader-allocator",
      "664-aget-verifier"
  );

  // Tests with custom run.
  private static List<String> customRun = ImmutableList.of(
      "000-nop",
      "018-stack-overflow",
      "055-enum-performance",
      "071-dexfile-map-clean",
      "091-override-package-private-method",
      "103-string-append",
      "115-native-bridge",
      "116-nodex2oat",
      "117-nopatchoat",
      "118-noimage-dex2oat",
      "119-noimage-patchoat",
      "126-miranda-multidex",
      "127-checker-secondarydex",
      "131-structural-change",
      "133-static-invoke-super",
      "134-nodex2oat-nofallback",
      "137-cfi",
      "138-duplicate-classes-check2",
      "146-bad-interface",
      "147-stripped-dex-fallback",
      "304-method-tracing",
      "529-checker-unresolved",
      "555-checker-regression-x86const",
      "569-checker-pattern-replacement",
      "570-checker-osr",
      "574-irreducible-and-constant-area",
      "577-profile-foreign-dex",
      "595-profile-saving",
      "597-deopt-new-string",
      "608-checker-unresolved-lse",
      "613-inlining-dex-cache",
      "636-wrong-static-access",
      "900-hello-plugin",
      "901-hello-ti-agent",
      "902-hello-transformation",
      "910-methods",
      "911-get-stack-trace",
      "912-classes",
      "913-heaps"
  );

  // Tests with C++ code (JNI)
  private static List<String> useJNI = ImmutableList.of(
      "004-JniTest",
      "004-NativeAllocations",
      "004-ReferenceMap",
      "004-SignalTest",
      "004-StackWalk",
      "004-ThreadStress",
      "004-UnsafeTest",
      "044-proxy",
      "051-thread",
      "115-native-bridge",
      "117-nopatchoat",
      "136-daemon-jni-shutdown",
      "137-cfi",
      "139-register-natives",
      "141-class-unload",
      "148-multithread-gc-annotations",
      "149-suspend-all-stress",
      "154-gc-loop",
      "155-java-set-resolved-type",
      "157-void-class",
      "158-app-image-class-table",
      "454-get-vreg",
      "457-regs",
      "461-get-reference-vreg",
      "466-get-live-vreg",
      "497-inlining-and-class-loader",
      "543-env-long-ref",
      "566-polymorphic-inlining",
      "570-checker-osr",
      "595-profile-saving",
      "596-app-images",
      "597-deopt-new-string",
      "616-cha",
      "616-cha-abstract",
      "616-cha-interface",
      "616-cha-interface-default",
      "616-cha-miranda",
      "616-cha-regression-proxy-method",
      "616-cha-native",
      "616-cha-proxy-method-inline",
      "626-const-class-linking",
      "626-set-resolved-string",
      "900-hello-plugin",
      "901-hello-ti-agent",
      "1337-gc-coverage"
  );

  private static List<String> expectedToFailRunWithArtNonDefault = ImmutableList.of(
      // Fails due to missing symbol, jni tests, fails on non-R8/D8 run.
      "004-JniTest",
      "004-SignalTest",
      "004-ThreadStress",
      "004-UnsafeTest",
      "044-proxy",
      "051-thread",
      "136-daemon-jni-shutdown",
      "139-register-natives",
      "148-multithread-gc-annotations",
      "149-suspend-all-stress",
      "154-gc-loop",
      "155-java-set-resolved-type",
      "157-void-class",
      "158-app-image-class-table",
      "466-get-live-vreg",
      "497-inlining-and-class-loader",
      "566-polymorphic-inlining",
      "596-app-images",
      "616-cha",
      "616-cha-abstract",
      "616-cha-regression-proxy-method",
      "616-cha-native",
      "626-set-resolved-string",
      "629-vdex-speed",
      "1337-gc-coverage",

      // Fails on non-R8/D8 run
      "031-class-attributes"
  );

  private static Map<DexVm.Version, List<String>> expectedToFailRunWithArtVersion;

  static {
    ImmutableMap.Builder<DexVm.Version, List<String>> builder = ImmutableMap.builder();
    builder
        .put(DexVm.Version.V10_0_0, ImmutableList.of(
            // TODO(b/144975341): Triage, Verif error.
            "518-null-array-get",
            // TODO(b/144975341): Triage, Linking error.
            "457-regs",
            "543-env-long-ref",
            "454-get-vreg"
        ))
        .put(DexVm.Version.V9_0_0, ImmutableList.of(
            // TODO(120400625): Triage.
            "454-get-vreg",
            // TODO(120402198): Triage.
            "457-regs",
            // TODO(120401674): Triage.
            "543-env-long-ref",
            // TODO(120261858) Triage.
            "518-null-array-get"
        ))
        .put(DexVm.Version.V8_1_0, ImmutableList.of(
            // TODO(119938529): Triage.
            "709-checker-varhandles",
            "454-get-vreg",
            "457-regs"
        ))
        .put(DexVm.Version.V7_0_0, ImmutableList.of(
            // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
            "008-exceptions",

            // Fails due to non-matching Exception messages.
            "201-built-in-except-detail-messages",

            // Generally fails on non-R8/D8 running.
            "156-register-dex-file-multi-loader",
            "412-new-array",
            "610-arraycopy",
            "625-checker-licm-regressions"))
        .put(DexVm.Version.V6_0_1, ImmutableList.of(
            // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
            "008-exceptions",

            // Fails due to non-matching Exception messages.
            "201-built-in-except-detail-messages",

            // Generally fails on non-R8/D8 running.
            "004-checker-UnsafeTest18",
            "005-annotations",
            "008-exceptions",
            "082-inline-execute",
            "099-vmdebug",
            "156-register-dex-file-multi-loader",
            "412-new-array",
            "580-checker-round",
            "594-invoke-super",
            "625-checker-licm-regressions",
            "626-const-class-linking"))
        .put(DexVm.Version.V5_1_1, ImmutableList.of(
            // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
            "008-exceptions",

            // Fails due to non-matching Exception messages.
            "201-built-in-except-detail-messages",

            // Generally fails on non R8/D8 running.
            "004-checker-UnsafeTest18",
            "004-NativeAllocations",
            "005-annotations",
            "008-exceptions",
            "082-inline-execute",
            "099-vmdebug",
            "143-string-value",
            "156-register-dex-file-multi-loader",
            "536-checker-intrinsic-optimization",
            "552-invoke-non-existent-super",
            "580-checker-round",
            "580-checker-string-fact-intrinsics",
            "594-invoke-super",
            "605-new-string-from-bytes",
            "626-const-class-linking"))
        .put(DexVm.Version.V4_4_4, ImmutableList.of(
            // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
            "008-exceptions",

            // Fails due to non-matching Exception messages.
            "201-built-in-except-detail-messages",

            // Generally fails on non R8/D8 running.
            "004-checker-UnsafeTest18",
            "004-NativeAllocations",
            "005-annotations",
            "008-exceptions",
            "082-inline-execute",
            "099-vmdebug",
            "143-string-value",
            "156-register-dex-file-multi-loader",
            "536-checker-intrinsic-optimization",
            "552-invoke-non-existent-super",
            "580-checker-round",
            "580-checker-string-fact-intrinsics",
            "594-invoke-super",
            "605-new-string-from-bytes",
            "626-const-class-linking"))
        .put(DexVm.Version.V4_0_4, ImmutableList.of(
            // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
            "008-exceptions",

            // Fails due to non-matching Exception messages.
            "201-built-in-except-detail-messages",

            // Generally fails on non R8/D8 running.
            "004-checker-UnsafeTest18",
            "004-NativeAllocations",
            "005-annotations",
            "008-exceptions",
            "082-inline-execute",
            "099-vmdebug",
            "143-string-value",
            "156-register-dex-file-multi-loader",
            "536-checker-intrinsic-optimization",
            "552-invoke-non-existent-super",
            "580-checker-round",
            "580-checker-string-fact-intrinsics",
            "594-invoke-super",
            "605-new-string-from-bytes",
            "626-const-class-linking"));
    expectedToFailRunWithArtVersion = builder.build();
  }

  // Tests where the R8/D8 output runs in Art but the original does not.
  private static Multimap<String, TestCondition> failingRunWithArtOriginalOnly =
      new ImmutableListMultimap.Builder<String, TestCondition>()
          .put("095-switch-MAX_INT",
              TestCondition.match(
                  TestCondition.runtimes(DexVm.Version.V4_0_4)))
          .build();

  // Tests where the output of R8 fails when run with Art.
  private static final Multimap<String, TestCondition> failingRunWithArt =
      new ImmutableListMultimap.Builder<String, TestCondition>()
          // The growth limit test fails after processing by R8 because R8 will eliminate an
          // "unneeded" const store. The following reflective call to the VM's GC will then see the
          // large array as still live and the subsequent allocations will fail to reach the desired
          // size before an out-of-memory error occurs. See:
          // tests/art/dx/104-growth-limit/src/Main.java:40
          .put(
              "104-growth-limit",
              TestCondition.match(TestCondition.R8_COMPILER, TestCondition.RELEASE_MODE))
          .put(
              "461-get-reference-vreg",
              TestCondition.match(
                  TestCondition.D8_COMPILER,
                  TestCondition
                      .runtimes(DexVm.Version.V7_0_0, DexVm.Version.V6_0_1, DexVm.Version.V5_1_1)))
          // Dalvik fails on reading an uninitialized local.
          .put(
              "471-uninitialized-locals",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // Out of memory.
          .put("152-dead-large-object",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // Cannot resolve exception handler. Interestingly, D8 generates different code in
          // release mode (which is also the code generated by R8) which passes.
          .put("111-unresolvable-exception",
              TestCondition.match(
                  TestCondition.D8_COMPILER,
                  TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // Fails because the code has to be desugared to run on art <= 6.0.1
          // When running from dx code we don't desugar.
          .put("530-checker-lse2",
              TestCondition.match(
                  TestCondition.tools(DexTool.DX),
                  TestCondition.D8_COMPILER,
                  TestCondition.runtimesUpTo(DexVm.Version.V6_0_1)))
          .put("534-checker-bce-deoptimization",
              TestCondition
                  .match(TestCondition.D8_COMPILER, TestCondition.runtimes(DexVm.Version.V6_0_1)))
          // Type not present.
          .put("124-missing-classes",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // Failed creating vtable.
          .put("587-inline-class-error",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // Failed creating vtable.
          .put("595-error-class",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // NoSuchFieldException: systemThreadGroup on Art 4.4.4.
          .put("129-ThreadGetId",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // Verifier says: can't modify final field LMain;.staticFinalField.
          .put("600-verifier-fails",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // VFY: tried to get class from non-ref register.
          .put("506-verify-aput",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // NoSuchMethod: startMethodTracing.
          .put("545-tracing-and-jit",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // filled-new-array arg 0(1) not valid.
          .put("412-new-array",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // TODO(ager): unclear what is failing here.
          .put("098-ddmc",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // Unsatisfiable link error:
          // libarttest.so: undefined symbol: _ZN3art6Thread18RunEmptyCheckpointEv
          .put("543-env-long-ref",
              TestCondition.match(
                  TestCondition.D8_COMPILER,
                  TestCondition
                      .runtimes(
                          DexVm.Version.V8_1_0,
                          DexVm.Version.V7_0_0,
                          DexVm.Version.V6_0_1,
                          DexVm.Version.V5_1_1)))
          // lib64 libarttest.so: wrong ELF class ELFCLASS64.
          .put("543-env-long-ref",
              TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // Leaving two static-get triggers LSE bug on 6.0.1 (b/25735083).
          // R8, with subtyping, knows the first sget is dead, and removing it avoids the bug.
          // Due to the lack of subtype hierarchy, D8 can't guarantee <clinit> side effects.
          .put("550-new-instance-clinit",
              TestCondition.match(
                  TestCondition.D8_COMPILER, TestCondition.runtimes(DexVm.Version.V6_0_1)))
          // Regression test for an issue that is not fixed on version 5.1.1. Throws an Exception
          // instance instead of the expected NullPointerException. This bug is only tickled when
          // running the R8 generated code when starting from jar or from dex code generated with
          // dx. However, the code that R8 generates is valid and there is nothing we can do for
          // this one.
          .put("551-implicit-null-checks",
              TestCondition.match(
                  TestCondition.tools(DexTool.NONE, DexTool.DX),
                  TestCondition.R8DEX_COMPILER,
                  TestCondition.runtimes(DexVm.Version.V5_1_1)))
          // Contains a method (B.<init>) which pass too few arguments to invoke. Also, contains an
          // iput on a static field.
          .put("600-verifier-fails",
              TestCondition.match(
                  TestCondition.D8_COMPILER,
                  TestCondition.runtimes(DexVm.Version.V7_0_0, DexVm.Version.V6_0_1,
                      DexVm.Version.V5_1_1)))
          // Dalvik 4.0.4 is missing ReflectiveOperationException class.
          .put("140-field-packing",
              TestCondition.match(
                  TestCondition.runtimes(DexVm.Version.V4_0_4)))
          // Dalvik 4.0.4 is missing theUnsafe field.
          .put("528-long-hint",
              TestCondition.match(
                  TestCondition.runtimes(DexVm.Version.V4_0_4)))
          // Cannot catch exception in Dalvik 4.0.4.
          .put("084-class-init",
              TestCondition.match(
                  TestCondition.runtimes(DexVm.Version.V4_0_4)))
          // Tested regression still exists in Dalvik 4.0.4.
          .put("301-abstract-protected",
              TestCondition.match(
                  TestCondition.runtimes(DexVm.Version.V4_0_4)))
          // Illegal class flags in Dalvik 4.0.4.
          .put("121-modifiers",
              TestCondition.match(
                  TestCondition.runtimes(DexVm.Version.V4_0_4)))
          // Switch regression still present in Dalvik 4.0.4.
          .put("095-switch-MAX_INT",
              TestCondition.match(
                  TestCondition.tools(DexTool.DX),
                  TestCondition.D8_COMPILER,
                  TestCondition.runtimes(DexVm.Version.V4_0_4)))
          .build();

  // Tests where the output of R8/D8 runs in Art but produces different output than the expected.txt
  // checked into the Art repo.
  private static final Multimap<String, TestCondition> failingRunWithArtOutput =
      new ImmutableListMultimap.Builder<String, TestCondition>()
          // This test assumes that class-retention annotations are preserved by the compiler and
          // then checks for backwards compatibility with M where they could incorrectly be observed
          // by the program at runtime.
          .put("005-annotations", TestCondition.match(TestCondition.D8_COMPILER))
          // On Art 4.4.4 we have fewer refs than expected (except for d8 when compiled with dx).
          .put("072-precise-gc",
              TestCondition.match(
                  TestCondition.R8_COMPILER,
                  TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          .put("072-precise-gc",
              TestCondition.match(
                  TestCondition.tools(DexTool.NONE),
                  TestCondition.D8_COMPILER,
                  TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
          // This one is expected to have different output. It counts instances, but the list that
          // keeps the instances alive is dead and could be garbage collected. The compiler reuses
          // the register for the list and therefore there are no live instances.
          .put("099-vmdebug", TestCondition.any())
          // This test relies on output on stderr, which we currently do not collect.
          .put("143-string-value", TestCondition.any())
          .put("800-smali",
              TestCondition.match(
                  TestCondition.D8_COMPILER,
                  TestCondition.runtimes(DexVm.Version.V5_1_1, DexVm.Version.V6_0_1)))
          // Triggers regression test in 6.0.1 when using R8/D8 in debug mode.
          .put("474-fp-sub-neg",
              TestCondition.match(
                  TestCondition.tools(DexTool.NONE),
                  TestCondition.D8_NOT_AFTER_R8CF_COMPILER,
                  TestCondition.runtimes(DexVm.Version.V6_0_1)))
          .build();

  private static final TestCondition beforeAndroidN =
      TestCondition
          .match(TestCondition
              .runtimes(DexVm.Version.V4_0_4, DexVm.Version.V4_4_4, DexVm.Version.V5_1_1,
                  DexVm.Version.V6_0_1));
  // TODO(herhut): Change to V8_0_0 once we have a new art VM.
  private static final TestCondition beforeAndroidO =
      TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V7_0_0));
  // TODO(herhut): Change to V8_0_0 once we have a new art VM.
  private static final TestCondition beforeAndroidP =
      TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V7_0_0));

  // TODO(ager): Could we test that these fail in the way that we expect?
  private static final Multimap<String, TestCondition> expectedToFailRunWithArt =
      new ImmutableListMultimap.Builder<String, TestCondition>()
          // Contains bad finalizer that times out.
          .put("030-bad-finalizer", TestCondition.any())
          // Contains a direct method call with a null receiver.
          .put("034-call-null", TestCondition.any())
          // Testing uncaught exceptions.
          .put("054-uncaught", TestCondition.any())
          // Contains a null pointer exception.
          .put("038-inner-null", TestCondition.any())
          // Null pointer exception.
          .put("071-dexfile", TestCondition.any())
          // Array index out of bounds exception.
          .put("088-monitor-verification", TestCondition.any())
          // Attempts to run hprof.
          .put("130-hprof", TestCondition.any())
          // Null pointer exception. Test doesn't exist for dx.
          .put("138-duplicate-classes-check", TestCondition.any())
          // Array index out of bounds exception.
          .put("150-loadlibrary", TestCondition.any())
          // Uses dex file version 37 and therefore only runs on Android N and above.
          .put(
              "370-dex-v37",
              TestCondition.match(
                  TestCondition.tools(DexTool.DX),
                  TestCondition.compilers(CompilerUnderTest.D8),
                  TestCondition.runtimes(
                      DexVm.Version.V4_0_4,
                      DexVm.Version.V4_4_4,
                      DexVm.Version.V5_1_1,
                      DexVm.Version.V6_0_1)))
          // Array index out of bounds exception.
          .put("449-checker-bce", TestCondition.any())
          // Fails: get_vreg_jni.cc:46] Check failed: value == 42u (value=314630384, 42u=42)
          // The R8/D8 code does not produce values in the same registers as the tests expects in
          // Main.testPairVReg where Main.doNativeCall is called (v1 vs v0).
          .put(
              "454-get-vreg",
              TestCondition.match(
                  TestCondition.runtimes(
                      DexVm.Version.V4_0_4,
                      DexVm.Version.V4_4_4,
                      DexVm.Version.V5_1_1,
                      DexVm.Version.V6_0_1,
                      DexVm.Version.V7_0_0)))
          .put("454-get-vreg", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // Fails: regs_jni.cc:42] Check failed: GetVReg(m, 0, kIntVReg, &value)
          // The R8/D8 code does not put values in the same registers as the tests expects.
          .put(
              "457-regs",
              TestCondition.match(
                  TestCondition.runtimes(
                      DexVm.Version.V4_0_4,
                      DexVm.Version.V4_4_4,
                      DexVm.Version.V5_1_1,
                      DexVm.Version.V6_0_1,
                      DexVm.Version.V7_0_0)))
          .put("457-regs", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // Class not found.
          .put("529-checker-unresolved", TestCondition.any())
          // Fails: env_long_ref.cc:44] Check failed: GetVReg(m, 1, kReferenceVReg, &value)
          // The R8/D8 code does not produce values in the same registers as the tests expects in
          // the stack frame for TestCase.testCase checked by the native Main.lookForMyRegisters
          // (v1 vs v0).
          .put("543-env-long-ref", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // Array index out of bounds exception.
          .put("555-UnsafeGetLong-regression", TestCondition.any())
          // Array index out of bounds exception.
          .put("563-checker-fakestring", TestCondition.any())
          // Array index out of bounds exception.
          .put("575-checker-string-init-alias", TestCondition.any())
          // Runtime exception.
          .put("577-profile-foreign-dex", TestCondition.any())
          // Array index out of bounds exception.
          .put("602-deoptimizeable", TestCondition.any())
          // Array index out of bounds exception.
          .put("604-hot-static-interface", TestCondition.any())
          // Array index out of bounds exception.
          .put("612-jit-dex-cache", TestCondition.any())
          // Fails: get_reference_vreg_jni.cc:43] Check failed: GetVReg(m, 1, kReferenceVReg,
          // &value)
          // The R8 code does not put values in the same registers as the tests expects in
          // Main.testThisWithInstanceCall checked by the native Main.doNativeCallRef (v0 vs. v1 and
          // only 1 register instead fof 2).
          .put("461-get-reference-vreg", TestCondition.match(TestCondition.R8_COMPILER))
          // This test uses register r1 in method that is declared to only use 1 register (r0).
          // This is in dex code which D8 does not convert and which R8/CF does not process.
          // Therefore the error is a verification error at runtime and that is expected.
          .put("142-classloader2", TestCondition.match(TestCondition.D8_COMPILER))
          // Invoke-custom is supported by D8 and R8, but it can only run on our newest version
          // of art.
          .put("952-invoke-custom", beforeAndroidO)
          .put("952-invoke-custom-kinds", beforeAndroidO)
          // Invoke-polymorphic is supported by D8 and R8, but it can only run on our newest version
          // of art.
          .put("953-invoke-polymorphic-compiler", beforeAndroidO)
          .put("957-methodhandle-transforms", beforeAndroidO)
          .put("958-methodhandle-stackframe", beforeAndroidO)
          .put("959-invoke-polymorphic-accessors", beforeAndroidO)
          .put("044-proxy", beforeAndroidN) // --min-sdk = 24
          .put("048-reflect-v8", beforeAndroidN) // --min-sdk = 24
          .put("962-iface-static", beforeAndroidN) // --min-sdk = 24
          .put("964-default-iface-init-gen", beforeAndroidN) // --min-sdk = 24
          .put("968-default-partial-compile-gen", beforeAndroidN) // --min-sdk = 24
          .put("970-iface-super-resolution-gen", beforeAndroidN) // --min-sdk = 24
          .put("971-iface-super", beforeAndroidN) // --min-sdk = 24
          .put("972-default-imt-collision", beforeAndroidN) // --min-sdk = 24
          .put("973-default-multidex", beforeAndroidN) // --min-sdk = 24
          .put("974-verify-interface-super", beforeAndroidN) // --min-sdk = 24
          .put("975-iface-private", beforeAndroidN) // --min-sdk = 24
          // Uses dex file version 37 and therefore only runs on Android N and above.
          .put(
              "972-iface-super-multidex",
              TestCondition.match(
                  TestCondition.tools(DexTool.DX),
                  TestCondition.runtimes(
                      DexVm.Version.V4_0_4,
                      DexVm.Version.V4_4_4,
                      DexVm.Version.V5_1_1,
                      DexVm.Version.V6_0_1)))
          // Uses dex file version 37 and therefore only runs on Android N and above.
          .put(
              "978-virtual-interface",
              TestCondition.or(
                  TestCondition.match(
                      TestCondition.tools(DexTool.DX),
                      TestCondition.compilers(CompilerUnderTest.D8),
                      TestCondition.runtimes(
                          DexVm.Version.V4_0_4,
                          DexVm.Version.V4_4_4,
                          DexVm.Version.V5_1_1,
                          DexVm.Version.V6_0_1)),
                  // On V4_0_4 and V4_4_4 the test will throw a verification error.
                  TestCondition.match(
                      TestCondition.tools(DexTool.DX),
                      TestCondition.compilers(
                          CompilerUnderTest.R8,
                          CompilerUnderTest.R8_AFTER_D8,
                          CompilerUnderTest.D8_AFTER_R8CF),
                      TestCondition.runtimes(DexVm.Version.V4_0_4, DexVm.Version.V4_4_4))))
          .put("979-const-method-handle", beforeAndroidP)
          // Missing class junit.framework.Assert (see JunitAvailabilityInHostArtTest).
          // TODO(120884788): Add this again.
          /*
          .put(
              "021-string2",
              TestCondition.or(
                  TestCondition.match(
                      TestCondition.compilers(CompilerUnderTest.D8_AFTER_R8CF),
                      TestCondition.runtimesFrom(DexVm.Version.V7_0_0)),
                  TestCondition.match(
                      TestCondition.compilers(CompilerUnderTest.D8_AFTER_R8CF),
                      TestCondition.runtimes(DexVm.Version.V4_0_4, DexVm.Version.V4_4_4))))
          */
          // Missing class junit.framework.Assert (see JunitAvailabilityInHostArtTest).
          // TODO(120884788): Add this again.
          /*
          .put(
              "082-inline-execute",
              TestCondition.or(
                  TestCondition.match(
                      TestCondition.compilers(CompilerUnderTest.D8_AFTER_R8CF),
                      TestCondition.runtimesFrom(DexVm.Version.V7_0_0)),
                  TestCondition.match(
                      TestCondition.compilers(CompilerUnderTest.D8_AFTER_R8CF),
                      TestCondition.runtimes(DexVm.Version.V4_0_4, DexVm.Version.V4_4_4))))
          */
          .build();

  // Tests where code generation fails.
  private static final Multimap<String, TestCondition> failingWithCompiler =
      new ImmutableListMultimap.Builder<String, TestCondition>()
          // Contains two methods with the same name and signature but different code.
          .put("097-duplicate-method", TestCondition.any())
          // Dex code contains a method (B.<init>) which pass too few arguments to invoke, and it
          // also contains an iput on a static field.
          .put("600-verifier-fails", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // Contains a method that falls off the end without a return.
          .put(
              "606-erroneous-class",
              TestCondition.match(
                  TestCondition.tools(DexTool.DX),
                  TestCondition.R8_NOT_AFTER_D8_COMPILER,
                  LEGACY_RUNTIME))
          // Dex input contains an illegal InvokeSuper in Z.foo() to Y.foo()
          // that R8 will fail to compile.
          .put("974-verify-interface-super", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // R8 generates too large code in Goto.bigGoto(). b/74327727
          .put("003-omnibus-opcodes", TestCondition.match(TestCondition.D8_AFTER_R8CF_COMPILER))
          .build();

  // Tests that are invalid dex files and on which R8/D8 fails and that is OK.
  private static final Multimap<String, TestCondition> expectedToFailWithCompiler =
      new ImmutableListMultimap.Builder<String, TestCondition>()
          // When starting from the Jar frontend we see the A$B class both from the Java source
          // code and from the smali dex code. We reject that because there are then two definitions
          // of the same class in the application. When running from the final dex files there is
          // only one A$B class because of a custom build script that merges them.
          .put("121-modifiers", TestCondition.match(TestCondition.tools(DexTool.NONE)))
          // This test uses register r1 in method that is declared to only use 1 register (r0).
          .put("142-classloader2", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // Test with invalid register usage: invoke-static {v2,v2,v2} f(LIF)V
          .put("457-regs", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // This test uses an uninitialized register.
          .put("471-uninitialized-locals", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // Test which mixes int and float registers.
          .put("459-dead-phi", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // Test for verification error: contains an aput-object with an single-valued input.
          .put("506-verify-aput", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // Test with invalid register usage: returns a register of either long or double.
          .put("510-checker-try-catch", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // Test with invalid register usage: contains an int-to-byte on the result of aget-object.
          .put("518-null-array-get", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // Test with invalid register usage: phi of int and float.
          .put("535-regression-const-val", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // Test with invalid register usage: phi of int and float.
          .put("552-checker-primitive-typeprop", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // Test with invalid register usage: invoke-static {v0,v0}, foo(IL)V
          .put("557-checker-ref-equivalent", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // This test is starting from invalid dex code. It splits up a double value and uses
          // the first register of a double with the second register of another double.
          .put("800-smali", TestCondition.match(TestCondition.R8DEX_COMPILER))
          // Contains a loop in the class hierarchy.
          .put("804-class-extends-itself", TestCondition.any())
          // These tests have illegal class flag combinations, so we reject them.
          .put("161-final-abstract-class", TestCondition.any())
          .build();

  // Tests that does not have dex input for some toolchains.
  private static Multimap<String, TestCondition> noInputDex =
      new ImmutableListMultimap.Builder<String, TestCondition>()
          .put("914-hello-obsolescence", TestCondition.match(
              TestCondition.tools(DexTool.NONE, DexTool.DX),
              LEGACY_RUNTIME))
          .put("915-obsolete-2", TestCondition.match(
              TestCondition.tools(DexTool.NONE, DexTool.DX),
              LEGACY_RUNTIME))
          .put("916-obsolete-jit", TestCondition.match(
              TestCondition.tools(DexTool.NONE, DexTool.DX),
              LEGACY_RUNTIME))
          .put("919-obsolete-fields", TestCondition.match(
              TestCondition.tools(DexTool.NONE, DexTool.DX),
              LEGACY_RUNTIME))
          .put("926-multi-obsolescence", TestCondition.match(
              TestCondition.tools(DexTool.NONE, DexTool.DX),
              LEGACY_RUNTIME))
          .put("941-recurive-obsolete-jit", TestCondition.match(
              TestCondition.tools(DexTool.NONE, DexTool.DX),
              LEGACY_RUNTIME))
          .put("940-recursive-obsolete", TestCondition.match(
              TestCondition.tools(DexTool.NONE, DexTool.DX),
              LEGACY_RUNTIME))
          .put("942-private-recursive", TestCondition.match(
              TestCondition.tools(DexTool.NONE, DexTool.DX),
              LEGACY_RUNTIME))
          .put("943-private-recursive-jit", TestCondition.match(
              TestCondition.tools(DexTool.NONE, DexTool.DX),
              LEGACY_RUNTIME))
          .put("945-obsolete-native", TestCondition.match(
              TestCondition.tools(DexTool.NONE, DexTool.DX),
              LEGACY_RUNTIME))
          .put("948-change-annotations", TestCondition.match(
              TestCondition.tools(DexTool.NONE, DexTool.DX),
              LEGACY_RUNTIME))
          .put("952-invoke-custom", TestCondition.match(
              TestCondition.tools(DexTool.NONE, DexTool.DX),
              LEGACY_RUNTIME))
          .put("952-invoke-custom-kinds",
              TestCondition.match(TestCondition.tools(DexTool.DX)))
          .put("979-const-method-handle",
              TestCondition.match(TestCondition.tools(DexTool.DX)))
          .build();

  // Tests that does not have valid input for us to be compatible with dx running.
  private static List<String> noInputJar = ImmutableList.of(
      "097-duplicate-method", // No input class files.
      "630-safecast-array", // No input class files.
      "801-VoidCheckCast", // No input class files.
      "804-class-extends-itself", // No input class files.
      "972-iface-super-multidex", // Based on multiple smali files
      "973-default-multidex", // Based on multiple smali files.
      "974-verify-interface-super", // No input class files.
      "975-iface-private", // No input class files.
      "976-conflict-no-methods", // No input class files
      "978-virtual-interface", // No input class files
      "663-odd-dex-size", // No input class files
      "663-odd-dex-size2", // No input class files
      "663-odd-dex-size3", // No input class files
      "663-odd-dex-size4" // No input class files
  );

  // Some JCTF test cases require test classes from other tests. These are listed here.
  private static final Map<String, List<String>> jctfTestsExternalClassFiles =
      new ImmutableMap.Builder<String, List<String>>()
          .put("lang.RuntimePermission.Class.RuntimePermission_class_A13",
              new ImmutableList.Builder<String>()
                  .add("lang/Thread/stop/Thread_stop_A02.class")
                  .add("lang/Thread/stopLjava_lang_Throwable/Thread_stop_A02.class")
                  .build())
          .put("lang.RuntimePermission.Class.RuntimePermission_class_A02",
              new ImmutableList.Builder<String>()
                  .add("lang/Class/getClassLoader/Class_getClassLoader_A03.class")
                  .add("lang/ClassLoader/getParent/ClassLoader_getParent_A02.class")
                  .add("lang/Thread/getContextClassLoader/Thread_getContextClassLoader_A02.class")
                  .add("lang/Runtime/exitI/Runtime_exit_A02.class")
                  .build())
          .put("lang.Runtime.exitI.Runtime_exit_A03",
              new ImmutableList.Builder<String>()
                  .add("lang/Runtime/exitI/Runtime_exit_A02.class")
                  .build())
          .build();

  // Tests to skip on some conditions
  private static final Multimap<String, TestCondition> testToSkip =
      new ImmutableListMultimap.Builder<String, TestCondition>()
          // When running R8 on dex input (D8, DX) this test non-deterministically fails
          // with a compiler exception, due to invoke-virtual on an interface, or it completes but
          // the output when run on Art is not as expected. b/65233869
          .put(
              "162-method-resolution",
              TestCondition.match(
                  TestCondition.tools(DexTool.DX, DexTool.NONE), TestCondition.R8_COMPILER))
          // Produces wrong output when compiled in release mode, which we cannot express.
          .put("015-switch", TestCondition.match(TestCondition.runtimes(DexVm.Version.V4_0_4)))
          // To prevent "Dex file with version '37' cannot be used with min sdk level '21'", which
          // would otherwise happen because D8 passes through the DEX code from DX.
          .put(
              "800-smali",
              TestCondition.match(
                  TestCondition.tools(DexTool.DX),
                  TestCondition.D8_COMPILER,
                  TestCondition.runtimesFrom(DexVm.Version.V5_1_1)))
          .build();

  public static List<String> requireInliningToBeDisabled =
      ImmutableList.of(
          // Test for a specific stack trace that gets destroyed by inlining.
          "008-exceptions",
          "492-checker-inline-invoke-interface",
          "493-checker-inline-invoke-interface",
          "488-checker-inline-recursive-calls",
          "487-checker-inline-calls",
          "122-npe",
          "141-class-unload",

          // Calls some internal art methods that cannot tolerate inlining.
          "466-get-live-vreg",

          // Requires a certain call pattern to surface an Art bug.
          "534-checker-bce-deoptimization",

          // Requires something to be allocated in a method so that it goes out of scope.
          "059-finalizer-throw",

          // Has tests in submethods, which we should not inline.
          "625-checker-licm-regressions");

  private static List<String> requireClassInliningToBeDisabled = ImmutableList.of(
      // Test is registered to be failing (failingRunWithArt), it fails only on 4.0.4
      // (because of a bug in this version of dalvik) but succeeds on later versions.
      // If class inliner us enabled it actually works fine on 4.0.4 since the class
      // instantiation is properly inlined.
      "301-abstract-protected",
      // Test depends on exception produced for missing method or similar cases, but
      // after class inlining removes class instantiations and references the exception
      // is not produced.
      "435-new-instance"
  );

  private static List<String> requireUninstantiatedTypeOptimizationToBeDisabled = ImmutableList.of(
      // This test inspects the message of the exception that is thrown when calling a virtual
      // method with a null-receiver. This message changes when the invocation is rewritten to
      // "throw null".
      "201-built-in-except-detail-messages"
  );

  private static List<String> hasMissingClasses = ImmutableList.of(
      "091-override-package-private-method",
      "003-omnibus-opcodes",
      "608-checker-unresolved-lse",
      "529-checker-unresolved",
      "803-no-super",
      "127-checker-secondarydex",
      "952-invoke-custom-kinds",
      // Depends on java.lang.invoke.Transformers, which is hidden.
      "958-methodhandle-stackframe"
  );

  private static Map<String, List<String>> keepRules =
      ImmutableMap.of(
          "021-string2", ImmutableList.of("-dontwarn junit.framework.**"),
          "082-inline-execute", ImmutableList.of("-dontwarn junit.framework.**"));

  private static Map<String, Consumer<InternalOptions>> configurations =
      ImmutableMap.of(
          // Has a new-instance instruction that attempts to instantiate an interface.
          "435-new-instance", options -> options.testing.allowTypeErrors = true);

  private static List<String> failuresToTriage = ImmutableList.of(
      // Dex file input into a jar file, not yet supported by the test framework.
      "663-odd-dex-size",
      "663-odd-dex-size2",
      "663-odd-dex-size3",
      "663-odd-dex-size4",

      // This is flaky.
      "104-growth-limit",

      // Various failures.
      "138-duplicate-classes-check",
      "461-get-reference-vreg",
      "629-vdex-speed",
      "638-no-line-number",
      "647-jni-get-field-id",
      "649-vdex-duplicate-method",
      "652-deopt-intrinsic",
      "655-jit-clinit",
      "656-annotation-lookup-generic-jni",
      "656-loop-deopt",
      "707-checker-invalid-profile",
      "708-jit-cache-churn",

      // These use "native trace".
      "981-dedup-original-dex",
      "982-ok-no-retransform",
      "983-source-transform-verify",
      "984-obsolete-invoke",
      "985-re-obsolete",
      "986-native-method-bind",
      "987-agent-bind",
      "988-method-trace",
      "989-method-trace-throw",
      "990-field-trace",
      "991-field-trace-2",
      "992-source-data",
      "993-breakpoints",
      "994-breakpoint-line",
      "995-breakpoints-throw",
      "996-breakpoint-obsolete",
      "997-single-step",

      // These two fail with missing *-hostdex.jar files.
      "648-inline-caches-unresolved",
      "998-redefine-use-after-free"
  );

  private static class TestSpecification {

    // Name of the Art test
    private final String name;
    // Directory of the test files (containing prebuild dex/jar files and expected output).
    private final File directory;
    // Compiler that these expectations are for dx, or none if running on class files.
    private final DexTool dexTool;
    // Native library to use for running this test - if any.
    private final String nativeLibrary;
    // Skip running this test with Art or Java - most likely due to timeout.
    private final boolean skipRun;
    // Skip running this test altogether. For example, there might be no input in this configuration
    // (e.g. no class files).
    private final boolean skipTest;
    // Fails compilation - most likely throws an exception.
    private final boolean failsWithX8;
    // Expected to fail compilation with a CompilationError.
    private final boolean expectedToFailWithX8;
    // Fails running the output in Art or on Java with an assertion error. On Art it's typically due
    // to verification errors.
    private final boolean failsOnRun;
    // Runs in art but fails the run because it produces different results.
    private final boolean failsWithArtOutput;
    // Original fails in art but the R8/D8 version can run in art.
    private final boolean failsWithArtOriginalOnly;
    // Test might produce different outputs.
    private final boolean outputMayDiffer;
    // Whether to disable inlining
    private final boolean disableInlining;
    // Whether to disable class inlining
    private final boolean disableClassInlining;
    // Whether to disable the uninitialized type optimization.
    private final boolean disableUninstantiatedTypeOptimization;
    // Has missing classes.
    private final boolean hasMissingClasses;
    // Explicitly disable desugaring.
    private final boolean disableDesugaring;
    // Extra keep rules to use when running with R8.
    private final List<String> keepRules;
    private final Consumer<InternalOptions> configuration;

    TestSpecification(
        String name,
        DexTool dexTool,
        File directory,
        boolean skipRun,
        boolean skipTest,
        boolean failsWithX8,
        boolean failsOnRun,
        boolean failsWithArtOutput,
        boolean failsWithArtOriginalOnly,
        String nativeLibrary,
        boolean expectedToFailWithX8,
        boolean outputMayDiffer,
        boolean disableInlining,
        boolean disableClassInlining,
        boolean disableUninstantiatedTypeOptimization,
        boolean hasMissingClasses,
        boolean disableDesugaring,
        List<String> keepRules,
        Consumer<InternalOptions> configuration) {
      this.name = name;
      this.dexTool = dexTool;
      this.nativeLibrary = nativeLibrary;
      this.directory = directory;
      this.skipRun = skipRun;
      this.skipTest = skipTest;
      this.failsWithX8 = failsWithX8;
      this.failsOnRun = failsOnRun;
      this.failsWithArtOutput = failsWithArtOutput;
      this.failsWithArtOriginalOnly = failsWithArtOriginalOnly;
      this.expectedToFailWithX8 = expectedToFailWithX8;
      this.outputMayDiffer = outputMayDiffer;
      this.disableInlining = disableInlining;
      this.disableClassInlining = disableClassInlining;
      this.disableUninstantiatedTypeOptimization = disableUninstantiatedTypeOptimization;
      this.hasMissingClasses = hasMissingClasses;
      this.disableDesugaring = disableDesugaring;
      this.keepRules = keepRules;
      this.configuration = configuration;
    }

    TestSpecification(
        String name,
        DexTool dexTool,
        File directory,
        boolean skipRun,
        boolean failsOnRun,
        boolean disableInlining,
        DexVm dexVm) {
      this(
          name,
          dexTool,
          directory,
          skipRun,
          ToolHelper.isWindows() && dexVm.getKind() == Kind.HOST,
          false,
          failsOnRun,
          false,
          false,
          null,
          false,
          false,
          disableInlining,
          true, // Disable class inlining for JCTF tests.
          false,
          false,
          true, // Disable desugaring for JCTF tests.
          ImmutableList.of(),
          null);
    }

    TestSpecification(
        String name,
        DexTool dexTool,
        File directory,
        boolean skipRun,
        boolean failsOnRun,
        boolean disableInlining) {
      this(
          name,
          dexTool,
          directory,
          skipRun,
          false,
          false,
          failsOnRun,
          false,
          false,
          null,
          false,
          false,
          disableInlining,
          true, // Disable class inlining for JCTF tests.
          false,
          false,
          true, // Disable desugaring for JCTF tests.
          ImmutableList.of(),
          null);
    }

    public File resolveFile(String name) {
      return directory.toPath().resolve(name).toFile();
    }

    public String toString() {
      return name + " (" + dexTool + ")";
    }
  }

  private static class SpecificationKey {

    private final String name;
    private final DexTool toolchain;

    private SpecificationKey(String name, DexTool toolchain) {
      assert name != null;
      this.name = name;
      this.toolchain = toolchain;
    }

    @Override
    public boolean equals(Object o) {
      if (!(o instanceof SpecificationKey)) {
        return false;
      }

      SpecificationKey that = (SpecificationKey) o;
      return name.equals(that.name) && toolchain == that.toolchain;
    }

    @Override
    public int hashCode() {
      return 31 * name.hashCode() + toolchain.hashCode();
    }
  }

  private static Set<String> collectTestsMatchingConditions(
      DexTool dexTool,
      CompilerUnderTest compilerUnderTest,
      DexVm.Version dexVmVersion,
      CompilationMode mode,
      Multimap<String, TestCondition> testConditionsMap) {
    Set<String> set = Sets.newHashSet();
    for (Map.Entry<String, TestCondition> kv : testConditionsMap.entries()) {
      if (kv.getValue().test(dexTool, compilerUnderTest, dexVmVersion, mode)) {
        set.add(kv.getKey());
      }
    }
    return set;
  }

  private static Map<SpecificationKey, TestSpecification> getTestsMap(
      CompilerUnderTest compilerUnderTest, CompilationMode compilationMode, DexVm dexVm) {
    DexVm.Version version = dexVm.getVersion();
    File defaultArtTestDir = new File(ART_TESTS_DIR);
    File legacyArtTestDir = new File(ART_LEGACY_TESTS_DIR);
    if (!defaultArtTestDir.exists() || !legacyArtTestDir.exists()) {
      // Don't run any tests if the directory does not exist.
      return Collections.emptyMap();
    }
    Map<SpecificationKey, TestSpecification> data = new HashMap<>();

    // Collect tests where running Art is skipped (we still run R8/D8 on these).
    Set<String> skipArt = new HashSet<>(customRun);

    // Collect the tests requiring the native library.
    Set<String> useNativeLibrary = Sets.newHashSet(useJNI);
    for (DexTool dexTool : DexTool.values()) {
      Set<String> skipTest = Sets.newHashSet(skipAltogether);
      skipTest.addAll(usesNativeAgentCode);
      skipTest.addAll(failuresToTriage);

      File artTestDir =
          LEGACY_RUNTIME.contains(Runtime.fromDexVmVersion(version))
              ? legacyArtTestDir
              : defaultArtTestDir;
      // Collect the tests failing code generation.
      Set<String> failsWithCompiler =
          collectTestsMatchingConditions(
              dexTool, compilerUnderTest, version, compilationMode, failingWithCompiler);

      // Collect the tests that are flaky.
      skipArt.addAll(collectTestsMatchingConditions(
              dexTool, compilerUnderTest, version, compilationMode, flakyRunWithArt));

      // Collect tests that has no input:
      if (dexTool == DexTool.NONE) {
        skipTest.addAll(noInputJar);
      }

      // Collect the test that we should skip in this configuration because there is no dex input
      skipTest.addAll(collectTestsMatchingConditions(
          dexTool, compilerUnderTest, version, compilationMode, noInputDex));

      // Collect the test that we should skip in this configuration
      skipTest.addAll(collectTestsMatchingConditions(
          dexTool, compilerUnderTest, version, compilationMode, testToSkip));

      // Collect the test that we should skip in this configuration.
      skipArt.addAll(
          collectTestsMatchingConditions(
              dexTool, compilerUnderTest, version, compilationMode, timeoutOrSkipRunWithArt));

      // Collect the tests failing to run in Art (we still run R8/D8 on these).
      Set<String> failsWithArt =
          collectTestsMatchingConditions(
              dexTool, compilerUnderTest, version, compilationMode, failingRunWithArt);
      {
        Set<String> tmpSet =
            collectTestsMatchingConditions(
                dexTool, compilerUnderTest, version, compilationMode, expectedToFailRunWithArt);
        failsWithArt.addAll(tmpSet);
      }

      if (!ToolHelper.isDefaultDexVm(dexVm)) {
        // Generally failing when not TOT art.
        failsWithArt.addAll(expectedToFailRunWithArtNonDefault);
        // Version specific failures
        failsWithArt.addAll(expectedToFailRunWithArtVersion.get(version));
      }

      // Collect the tests failing with output differences in Art.
      Set<String> failsRunWithArtOutput =
          collectTestsMatchingConditions(
              dexTool, compilerUnderTest, version, compilationMode, failingRunWithArtOutput);
      Set<String> expectedToFailWithCompilerSet =
          collectTestsMatchingConditions(
              dexTool, compilerUnderTest, version, compilationMode, expectedToFailWithCompiler);

      // Collect the tests where the original works in Art and the R8/D8 generated output does not.
      Set<String> failsRunWithArtOriginalOnly =
          collectTestsMatchingConditions(
              dexTool, compilerUnderTest, version, compilationMode, failingRunWithArtOriginalOnly);

      File compilerTestDir = artTestDir.toPath().resolve(dexToolDirectory(dexTool)).toFile();
      File[] testDirs = compilerTestDir.listFiles();
      assert testDirs != null;
      for (File testDir : testDirs) {
        String name = testDir.getName();
        boolean skip = skipTest.contains(name);
        // All the native code for all Art tests is currently linked into the
        // libarttest.so file.
        data.put(
            new SpecificationKey(name, dexTool),
            new TestSpecification(
                name,
                dexTool,
                testDir,
                skipArt.contains(name),
                skip || ToolHelper.isWindows() && dexVm.getKind() == Kind.HOST,
                failsWithCompiler.contains(name),
                failsWithArt.contains(name),
                failsRunWithArtOutput.contains(name),
                failsRunWithArtOriginalOnly.contains(name),
                useNativeLibrary.contains(name) ? "arttest" : null,
                expectedToFailWithCompilerSet.contains(name),
                outputMayDiffer.contains(name),
                requireInliningToBeDisabled.contains(name),
                requireClassInliningToBeDisabled.contains(name),
                requireUninstantiatedTypeOptimizationToBeDisabled.contains(name),
                hasMissingClasses.contains(name),
                false,
                keepRules.getOrDefault(name, ImmutableList.of()),
                configurations.get(name)));
      }
    }
    return data;
  }

  private static CompilationMode defaultCompilationMode(CompilerUnderTest compilerUnderTest) {
    CompilationMode compilationMode = null;
    switch (compilerUnderTest) {
      case R8:
      case R8CF:
        compilationMode = CompilationMode.RELEASE;
        break;
      case D8:
      case R8_AFTER_D8:
      case D8_AFTER_R8CF:
        compilationMode = CompilationMode.DEBUG;
        break;
      default:
        throw new RuntimeException("Unreachable.");
    }
    return compilationMode;
  }

  private static String dexToolDirectory(DexTool tool) {
    // DexTool.NONE uses class files in the dx directory.
    return "dx";
  }

  @Rule
  public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest();

  @Rule
  public TestDescriptionWatcher watcher = new TestDescriptionWatcher();

  public R8RunArtTestsTest(String name, DexTool toolchain) {
    this.name = name;
    this.toolchain = toolchain;
  }

  private ArtCommandBuilder buildArtCommand(
      File dexFile, TestSpecification specification, DexVm artVersion) {
    ArtCommandBuilder builder = new ArtCommandBuilder(artVersion);
    builder.appendClasspath(dexFile.toString());
    // All Art tests have the main class Main.
    builder.setMainClass("Main");
    if (specification.nativeLibrary != null) {
      // All the native libraries for all Art tests is in the same directory.
      File artTestNativeLibraryDir = new File(ART_TESTS_NATIVE_LIBRARY_DIR);
      if (artVersion != DexVm.ART_DEFAULT) {
        artTestNativeLibraryDir = new File(ART_LEGACY_TESTS_NATIVE_LIBRARY_DIR);
      }
      builder.addToJavaLibraryPath(artTestNativeLibraryDir);
      builder.appendProgramArgument(specification.nativeLibrary);
    }
    return builder;
  }

  protected void runArtTest(CompilerUnderTest compilerUnderTest) throws Throwable {
    // Use the default dex VM specified.
    runArtTest(ToolHelper.getDexVm(), compilerUnderTest);
  }

  private static class CompilationOptions implements Consumer<InternalOptions> {

    private final boolean disableInlining;
    private final boolean disableClassInlining;
    private final boolean disableUninstantiatedTypeOptimization;
    private final boolean hasMissingClasses;
    private final boolean disableDesugaring;
    private final List<String> keepRules;
    private final Consumer<InternalOptions> configuration;

    private CompilationOptions(TestSpecification spec) {
      this.disableInlining = spec.disableInlining;
      this.disableClassInlining = spec.disableClassInlining;
      this.disableUninstantiatedTypeOptimization = spec.disableUninstantiatedTypeOptimization;
      this.hasMissingClasses = spec.hasMissingClasses;
      this.disableDesugaring = spec.disableDesugaring;
      this.keepRules = spec.keepRules;
      this.configuration = spec.configuration;
    }

    @Override
    public void accept(InternalOptions options) {
      if (disableInlining) {
        options.enableInlining = false;
      }
      if (disableClassInlining) {
        options.enableClassInlining = false;
      }
      if (disableUninstantiatedTypeOptimization) {
        options.enableUninstantiatedTypeOptimization = false;
      }
      // Some tests actually rely on missing classes for what they test.
      options.ignoreMissingClasses = hasMissingClasses;
      if (configuration != null) {
        configuration.accept(options);
      }
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      CompilationOptions options = (CompilationOptions) o;
      return disableInlining == options.disableInlining
          && disableClassInlining == options.disableClassInlining
          && disableUninstantiatedTypeOptimization == options.disableUninstantiatedTypeOptimization
          && hasMissingClasses == options.hasMissingClasses;
    }

    @Override
    public int hashCode() {
      return Objects.hash(
          disableInlining,
          disableClassInlining,
          disableUninstantiatedTypeOptimization,
          hasMissingClasses);
    }
  }

  private void executeCompilerUnderTest(
      CompilerUnderTest compilerUnderTest,
      Collection<String> fileNames,
      String resultPath,
      CompilationMode compilationMode,
      CompilationOptions compilationOptions)
      throws CompilationFailedException {
    executeCompilerUnderTest(
        compilerUnderTest, fileNames, resultPath, compilationMode, null, compilationOptions);
  }

  private void executeCompilerUnderTest(
      CompilerUnderTest compilerUnderTest,
      Collection<String> fileNames,
      String resultPath,
      CompilationMode mode,
      String keepRulesFile,
      CompilationOptions compilationOptions)
      throws CompilationFailedException {
    assert mode != null;
    switch (compilerUnderTest) {
      case D8_AFTER_R8CF:
        {
          assert keepRulesFile == null : "Keep-rules file specified for D8.";

          List<ProgramResource> dexInputs = new ArrayList<>();
          List<ProgramResource> cfInputs = new ArrayList<>();
          for (String f : fileNames) {
            Path p = Paths.get(f);
            if (FileUtils.isDexFile(p)) {
              dexInputs.add(ProgramResource.fromFile(ProgramResource.Kind.DEX, p));
            } else if (FileUtils.isClassFile(p)) {
              cfInputs.add(ProgramResource.fromFile(ProgramResource.Kind.CF, p));
            } else {
              assert FileUtils.isArchive(p);
              ArchiveProgramResourceProvider provider =
                  ArchiveProgramResourceProvider.fromArchive(p);

              try {
                for (ProgramResource pr : provider.getProgramResources()) {
                  if (pr.getKind() == ProgramResource.Kind.DEX) {
                    dexInputs.add(pr);
                  } else {
                    assert pr.getKind() == ProgramResource.Kind.CF;
                    cfInputs.add(pr);
                  }
                }
              } catch (ResourceException e) {
                throw new CompilationError("", e);
              }
            }
          }

          D8Command.Builder builder =
              D8Command.builder()
                  .setMode(mode)
                  .addProgramResourceProvider(
                      new ProgramResourceProvider() {
                        @Override
                        public Collection<ProgramResource> getProgramResources() {
                          return dexInputs;
                        }
                      })
                  .setOutput(Paths.get(resultPath), OutputMode.DexIndexed);

          Origin cfOrigin =
              new Origin(Origin.root()) {
                @Override
                public String part() {
                  return "R8/CF";
                }
              };

          R8Command.Builder r8builder =
              R8Command.builder()
                  .setMode(mode)
                  .setDisableTreeShaking(true)
                  .setDisableMinification(true)
                  .addProguardConfiguration(ImmutableList.of("-keepattributes *"), Origin.unknown())
                  .addProguardConfiguration(compilationOptions.keepRules, Origin.unknown())
                  .setProgramConsumer(
                      new ClassFileConsumer() {

                        @Override
                        public synchronized void accept(
                            ByteDataView data, String descriptor, DiagnosticsHandler handler) {
                          builder.addClassProgramData(data.copyByteData(), cfOrigin);
                        }

                        @Override
                        public void finished(DiagnosticsHandler handler) {}
                      })
                  .addProgramResourceProvider(
                      new ProgramResourceProvider() {
                        @Override
                        public Collection<ProgramResource> getProgramResources()
                            throws ResourceException {
                          return cfInputs;
                        }
                      });

          AndroidApiLevel minSdkVersion = needMinSdkVersion.get(name);
          if (minSdkVersion != null) {
            builder.setMinApiLevel(minSdkVersion.getLevel());
            builder.addLibraryFiles(ToolHelper.getAndroidJar(minSdkVersion));
            r8builder.addLibraryFiles(ToolHelper.getAndroidJar(minSdkVersion));
          } else {
            builder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.getDefault()));
            r8builder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.getDefault()));
          }
          ToolHelper.runR8(r8builder.build(), options -> options.ignoreMissingClasses = true);
          D8.run(builder.build());
          break;
        }
      case D8: {
        assert keepRulesFile == null : "Keep-rules file specified for D8.";
          D8Command.Builder builder =
              D8Command.builder()
                  .setMode(mode)
                  .addProgramFiles(ListUtils.map(fileNames, Paths::get))
                  .setOutput(Paths.get(resultPath), OutputMode.DexIndexed)
                  .setDisableDesugaring(compilationOptions.disableDesugaring);
        AndroidApiLevel minSdkVersion = needMinSdkVersion.get(name);
        if (minSdkVersion != null) {
          builder.setMinApiLevel(minSdkVersion.getLevel());
          builder.addLibraryFiles(ToolHelper.getAndroidJar(minSdkVersion));
        } else {
          builder
              .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.getDefault()));
        }
        D8.run(builder.build());
        break;
      }
      case R8:
      case R8CF:
        {
          boolean cfBackend = compilerUnderTest == CompilerUnderTest.R8CF;
          R8Command.Builder builder =
              R8Command.builder()
                  .setMode(mode)
                  .setDisableTreeShaking(true)
                  .setDisableMinification(true)
                  .setDisableDesugaring(compilationOptions.disableDesugaring)
                  .addProguardConfiguration(ImmutableList.of("-keepattributes *"), Origin.unknown())
                  .addProguardConfiguration(compilationOptions.keepRules, Origin.unknown())
                  .setOutput(
                      Paths.get(resultPath),
                      cfBackend ? OutputMode.ClassFile : OutputMode.DexIndexed);
          ToolHelper.allowTestProguardOptions(builder);
          // Add program files directly to the underlying app to avoid errors on DEX inputs.
          ToolHelper.getAppBuilder(builder).addProgramFiles(ListUtils.map(fileNames, Paths::get));
          if (cfBackend) {
            builder.addLibraryFiles(ToolHelper.getJava8RuntimeJar());
          } else {
            AndroidApiLevel minSdkVersion = needMinSdkVersion.get(name);
            if (minSdkVersion != null) {
              builder.setMinApiLevel(minSdkVersion.getLevel());
              ToolHelper.addFilteredAndroidJar(builder, minSdkVersion);
            } else {
              ToolHelper.addFilteredAndroidJar(builder, AndroidApiLevel.getDefault());
            }
          }
          if (keepRulesFile != null) {
            builder.addProguardConfigurationFiles(Paths.get(keepRulesFile));
          }
          // Add internal flags for testing purposes.
          ToolHelper.runR8(
              builder.build(),
              options -> {
                compilationOptions.accept(options);
                // Make sure we don't depend on this settings.
                options.classInliningInstructionAllowance = 10000;
                options.lineNumberOptimization = LineNumberOptimization.OFF;
              });
          break;
        }
      default:
        assert false : compilerUnderTest;
    }
  }

  private static boolean isAuxClassFile(String fileName, String auxClassFileBase) {
    return fileName.endsWith(".class")
        && (fileName.startsWith(auxClassFileBase + "$")
        || fileName.startsWith(auxClassFileBase + "_"));
  }


  private ArrayList<File> getJctfTestAuxClassFiles(File classFile) {
    // Collect additional files from the same directory with file names like
    // <dir>/<filename_wo_ext>$*.class and <dir>/<filename_wo_ext>_*.class
    String classFileString = classFile.toString();
    assert classFileString.endsWith(".class");

    String auxClassFileBase =
        new File(
            classFileString.substring(0, classFileString.length() - ".class".length()))
            .getName();

    ArrayList<File> auxClassFiles = new ArrayList<>();

    File[] files = classFile.getParentFile()
        .listFiles(
            (File file) -> isAuxClassFile(file.getName(), auxClassFileBase));
    if (files != null) {
      auxClassFiles.addAll(Arrays.asList(files));
    }

    if (auxClassFileBase.matches(".*[A-Z]\\d\\d")) {
      // Also collect all the files in this directory that doesn't match this pattern
      // They will be helper classes defined in one of the test class files but we don't know in
      // which one, so we just add them to all tests.
      final int SUFFIX_LENGTH_TO_STRIP = 3; // one letter (usually 'A' and two digits)
      String testClassFilePattern =
          auxClassFileBase.substring(0, auxClassFileBase.length() - SUFFIX_LENGTH_TO_STRIP)
              + "[A-Z]\\d\\d.*\\.class";
      files = classFile.getParentFile()
          .listFiles(
              (File file) -> file.getName().matches(".*\\.class") && !file.getName()
                  .matches(testClassFilePattern));
      if (files != null) {
        auxClassFiles.addAll(Arrays.asList(files));
      }
    }

    return auxClassFiles;
  }

  private static BiFunction<Outcome, Boolean, TestSpecification> jctfOutcomeToSpecification(
      String name, DexTool dexTool, File resultDir, DexVm dexVm) {
    return (outcome, noInlining) ->
        new TestSpecification(
            name,
            dexTool,
            resultDir,
            outcome == JctfTestSpecifications.Outcome.TIMEOUTS_WHEN_RUN
                || outcome == JctfTestSpecifications.Outcome.FLAKY_WHEN_RUN,
            outcome == JctfTestSpecifications.Outcome.FAILS_WHEN_RUN,
            noInlining,
            dexVm);
  }

  private static BiFunction<Outcome, Boolean, TestSpecification> jctfOutcomeToSpecificationJava(
      String name, File resultDir) {
    return (outcome, noInlining) ->
        new TestSpecification(
            name,
            DexTool.NONE,
            resultDir,
            outcome == JctfTestSpecifications.Outcome.TIMEOUTS_WHEN_RUN
                || outcome == JctfTestSpecifications.Outcome.FLAKY_WHEN_RUN,
            outcome == JctfTestSpecifications.Outcome.FAILS_WHEN_RUN,
            noInlining);
  }

  private static Runtime getRuntime(TestRuntime vm) {
    if (vm.isCf()) {
      return Runtime.JAVA;
    } else if (vm.isDex()) {
      return Runtime.fromDexVmVersion(vm.asDex().getVm().getVersion());
    } else {
      throw new Unreachable();
    }
  }

  private static class VmSpec {
    final TestRuntime vm;
    final TestSpecification spec;

    private VmSpec(TestRuntime vm, TestSpecification testSpecification) {
      this.vm = vm;
      this.spec = testSpecification;
    }
  }

  private static class VmErrors {
    private final Set<TestRuntime> failedVms = new HashSet<>();
    private StringBuilder message;

    private void addShouldHaveFailedError(CompilerUnderTest compilerUnderTest, TestRuntime vm) {
      addFailure(vm);
      message.append(
          "FAILURE: Test should have failed on "
              + vm
              + " after compiling with "
              + compilerUnderTest
              + ".\n");
    }

    private void addFailedOnRunError(
        CompilerUnderTest compilerUnderTest, TestRuntime vm, AssertionError error) {
      addFailure(vm);
      message.append(
          "FAILURE: Test failed on "
              + vm
              + " after compiling with "
              + compilerUnderTest
              + ", error:\n"
              + error.getMessage()
              + "\n");
    }

    private void addFailure(TestRuntime vm) {
      if (message == null) {
        message = new StringBuilder();
      }
      failedVms.add(vm);
    }
  }

  protected void runJctfTest(
      CompilerUnderTest compilerUnderTest, String classFilePath, String fullClassName)
      throws IOException, CompilationFailedException {
    VmErrors vmErrors = runJctfTestCore(compilerUnderTest, classFilePath, fullClassName);
    if (vmErrors.message != null) {
      throw new RuntimeException(vmErrors.message.toString());
    }
  }

  private VmErrors runJctfTestCore(
      CompilerUnderTest compilerUnderTest, String classFilePath, String fullClassName)
      throws IOException, CompilationFailedException {
    VmErrors vmErrors = new VmErrors();
    List<TestRuntime> vms = new ArrayList<>();
    if (compilerUnderTest == CompilerUnderTest.R8CF) {
      // TODO(b/135411839): Run on all java runtimes.
      vms.add(TestRuntime.getDefaultJavaRuntime());
    } else {
      for (DexVm vm : TestParametersBuilder.getAvailableDexVms()) {
        // TODO(144966342): Disabled for triaging failures
        if (vm.getVersion() == DexVm.Version.V10_0_0) {
          System.out.println("Running on 10.0.0 is disabled, see b/144966342");
          continue;
        }
        vms.add(new DexRuntime(vm));
      }
    }

    CompilerUnderTest firstCompilerUnderTest =
        compilerUnderTest == CompilerUnderTest.R8_AFTER_D8
            ? CompilerUnderTest.D8
            : compilerUnderTest;
    CompilationMode compilationMode = defaultCompilationMode(compilerUnderTest);

    List<VmSpec> vmSpecs = new ArrayList<>();
    for (TestRuntime vm : vms) {
      File resultDir =
          temp.newFolder(
              firstCompilerUnderTest.toString().toLowerCase() + "-output-" + vm.toString());

      TestSpecification specification =
          JctfTestSpecifications.getExpectedOutcome(
              name,
              firstCompilerUnderTest,
              getRuntime(vm),
              compilationMode,
              compilerUnderTest == CompilerUnderTest.R8CF
                  ? jctfOutcomeToSpecificationJava(name, resultDir)
                  : jctfOutcomeToSpecification(name, DexTool.NONE, resultDir, vm.asDex().getVm()));

      if (!specification.skipTest) {
        vmSpecs.add(new VmSpec(vm, specification));
      }
    }

    if (vmSpecs.isEmpty()) {
      return vmErrors;
    }

    File classFile = new File(JCTF_TESTS_PREFIX + "/" + classFilePath);
    if (!classFile.exists()) {
      throw new FileNotFoundException(
          "Class file for Jctf test not found: \"" + classFile.toString() + "\".");
    }

    ArrayList<File> classFiles = new ArrayList<>();
    classFiles.add(classFile);

    // some tests need files from other tests
    int langIndex = fullClassName.indexOf(".java.");
    assert langIndex >= 0;
    List<String> externalClassFiles = jctfTestsExternalClassFiles
        .get(fullClassName.substring(langIndex + ".java.".length()));

    if (externalClassFiles != null) {
      for (String s : externalClassFiles) {
        classFiles.add(new File(JCTF_TESTS_LIB_PREFIX + "/java/" + s));
      }
    }

    ArrayList<File> allClassFiles = new ArrayList<>();

    for (File f : classFiles) {
      allClassFiles.add(f);
      allClassFiles.addAll(getJctfTestAuxClassFiles(f));
    }

    File jctfCommonFile = new File(JCTF_COMMON_JAR);
    if (!jctfCommonFile.exists()) {
      throw new FileNotFoundException(
          "Jar file of Jctf tests common code not found: \"" + jctfCommonFile.toString() + "\".");
    }

    File junitFile = new File(JUNIT_JAR);
    if (!junitFile.exists()) {
      throw new FileNotFoundException(
          "Junit Jar not found: \"" + junitFile.toString() + "\".");
    }

    File hamcrestFile = new File(HAMCREST_JAR);
    if (!hamcrestFile.exists()) {
      throw new FileNotFoundException(
          "Hamcrest Jar not found: \"" + hamcrestFile.toString() + "\".");
    }

    // allClassFiles may contain duplicated files, that's why the HashSet
    Set<String> fileNames = new HashSet<>();

    fileNames.addAll(Arrays.asList(
        jctfCommonFile.getCanonicalPath(),
        junitFile.getCanonicalPath(),
        hamcrestFile.getCanonicalPath()
    ));

    for (File f : allClassFiles) {
      fileNames.add(f.getCanonicalPath());
    }

    if (compilerUnderTest == CompilerUnderTest.R8CF) {
      assert vmSpecs.size() == 1
          : "Running the same test on multiple JVMs should share the same build.";
      for (VmSpec vmSpec : vmSpecs) {
        runJctfTestDoRunOnJava(
            fileNames, vmSpec.spec, fullClassName, compilationMode, vmSpec.vm.asCf().getVm());
      }
      return vmErrors;
    }

    CompilationOptions compilationOptions = null;
    File compiledDir = temp.newFolder();
    for (VmSpec vmSpec : vmSpecs) {
      CompilationOptions thisOptions = new CompilationOptions(vmSpec.spec);
      if (compilationOptions == null) {
        compilationOptions = thisOptions;
        executeCompilerUnderTest(
            firstCompilerUnderTest,
            fileNames,
            compiledDir.getAbsolutePath(),
            compilationMode,
            compilationOptions);
      } else {
        // For now compile options don't change across vms.
        assert compilationOptions.equals(thisOptions);
      }
      Files.copy(
          compiledDir.toPath().resolve("classes.dex"),
          vmSpec.spec.directory.toPath().resolve("classes.dex"));

      AssertionError vmError = null;
      try {
        runJctfTestDoRunOnArt(fileNames, vmSpec.spec, fullClassName, vmSpec.vm.asDex().getVm());
      } catch (AssertionError e) {
        vmError = e;
      }
      if (vmSpec.spec.failsOnRun && vmError == null) {
        vmErrors.addShouldHaveFailedError(firstCompilerUnderTest, vmSpec.vm);
      } else if (!vmSpec.spec.failsOnRun && vmError != null) {
        vmErrors.addFailedOnRunError(firstCompilerUnderTest, vmSpec.vm, vmError);
      }
    }

    if (compilerUnderTest != CompilerUnderTest.R8_AFTER_D8) {
      return vmErrors;
    }

    // Second pass (R8), if R8_AFTER_D8.
    CompilationOptions r8CompilationOptions = null;
    File r8CompiledDir = temp.newFolder();
    for (VmSpec vmSpec : vmSpecs) {
      if (vmSpec.spec.failsOnRun || vmErrors.failedVms.contains(vmSpec.vm)) {
        continue;
      }
      File r8ResultDir = temp.newFolder("r8-output-" + vmSpec.vm.toString());
      TestSpecification specification =
          JctfTestSpecifications.getExpectedOutcome(
              name,
              CompilerUnderTest.R8_AFTER_D8,
              getRuntime(vmSpec.vm),
              CompilationMode.RELEASE,
              jctfOutcomeToSpecification(name, DexTool.DX, r8ResultDir, vmSpec.vm.asDex().getVm()));
      if (specification.skipTest) {
        continue;
      }
      CompilationOptions thisOptions = new CompilationOptions(specification);
      if (r8CompilationOptions == null) {
        r8CompilationOptions = thisOptions;
        executeCompilerUnderTest(
            CompilerUnderTest.R8,
            Collections.singletonList(compiledDir.toPath().resolve("classes.dex").toString()),
            r8CompiledDir.getAbsolutePath(),
            CompilationMode.RELEASE,
            r8CompilationOptions);
      } else {
        // For now compile options don't change across vms.
        assert r8CompilationOptions.equals(thisOptions);
      }
      Files.copy(
          r8CompiledDir.toPath().resolve("classes.dex"),
          specification.directory.toPath().resolve("classes.dex"));
      try {
        runJctfTestDoRunOnArt(fileNames, specification, fullClassName, vmSpec.vm.asDex().getVm());
      } catch (AssertionError e) {
        if (!specification.failsOnRun) {
          vmErrors.addFailedOnRunError(CompilerUnderTest.R8, vmSpec.vm, e);
        }
      }
    }
    return vmErrors;
  }

  private void runJctfTestDoRunOnArt(
      Collection<String> fileNames,
      TestSpecification specification,
      String fullClassName,
      DexVm dexVm)
      throws IOException {
    if (!ToolHelper.artSupported() && !ToolHelper.dealsWithGoldenFiles()) {
      return;
    }

    File processedFile;

    // Collect the generated dex files.
    File[] outputFiles =
        specification.directory.listFiles((File file) -> file.getName().endsWith(".dex"));
    assert outputFiles.length == 1;
    processedFile = outputFiles[0];

    boolean compileOnly = System.getProperty("jctf_compile_only", "0").equals("1");
    if (compileOnly || specification.skipRun) {
      if (ToolHelper.isDex2OatSupported()) {
        // verify dex code instead of running it
        Path oatFile = temp.getRoot().toPath().resolve("all.oat");
        ToolHelper.runDex2Oat(processedFile.toPath(), oatFile);
      }
      return;
    }

    ArtCommandBuilder builder = buildArtCommand(processedFile, specification, dexVm);
    if (dexVm.isNewerThan(DexVm.ART_4_4_4_HOST)) {
      builder.appendArtOption("-Ximage:/system/non/existent/image.art");
      builder.appendArtOption("-Xnoimage-dex2oat");
    }
    for (String s : ToolHelper.getBootLibs(dexVm)) {
      builder.appendBootClassPath(new File(s).getCanonicalPath());
    }
    builder.setMainClass(JUNIT_TEST_RUNNER);
    builder.appendProgramArgument(fullClassName);

    try {
      ToolHelper.runArt(builder);
    } catch (AssertionError e) {
      addDexInformationToVerificationError(fileNames, processedFile,
          specification.resolveFile("classes.dex"), e);
      throw e;
    }
  }

  private void runJctfTestDoRunOnJava(
      Collection<String> fileNames,
      TestSpecification specification,
      String fullClassName,
      CompilationMode mode,
      CfVm vm)
      throws IOException, CompilationFailedException {
    assert TestParametersBuilder.isSystemJdk(vm);
    if (JctfTestSpecifications.compilationFailsWithAsmMethodTooLarge.contains(specification.name)) {
      expectException(org.objectweb.asm.MethodTooLargeException.class);
    }
    executeCompilerUnderTest(
        CompilerUnderTest.R8CF,
        fileNames,
        specification.directory.getAbsolutePath(),
        mode,
        new CompilationOptions(specification));

    boolean compileOnly = System.getProperty("jctf_compile_only", "0").equals("1");

    if (compileOnly || specification.skipRun) {
      return;
    }

    if (specification.failsOnRun) {
      expectException(AssertionError.class);
    }

    // Some tests rely on an OutOfMemoryError being thrown (fx MemoryHog.getBigArray()). To ensure
    // compatible test results locally and externally, we need to synchronize the max heap size when
    // running the test.
    ProcessResult result =
        ToolHelper.runJava(
            specification.directory.toPath(),
            "-Xmx" + ToolHelper.BOT_MAX_HEAP_SIZE,
            JUNIT_TEST_RUNNER,
            fullClassName);

    if (result.exitCode != 0) {
      throw new AssertionError(
          "Test failed on java.\nSTDOUT >>>\n"
              + result.stdout
              + "\n<<< STDOUT\nSTDERR >>>\n"
              + result.stderr
              + "\n<<< STDERR\n");
    }

    if (specification.failsOnRun) {
      System.err.println("Should have failed run with java.");
    }
  }

  protected void runArtTest(DexVm dexVm, CompilerUnderTest compilerUnderTest) throws Throwable {
    CompilerUnderTest firstCompilerUnderTest =
        compilerUnderTest == CompilerUnderTest.R8_AFTER_D8
            ? CompilerUnderTest.D8
            : compilerUnderTest;

    CompilationMode compilationMode = defaultCompilationMode(compilerUnderTest);

    TestSpecification specification =
        getTestsMap(firstCompilerUnderTest, compilationMode, dexVm)
            .get(new SpecificationKey(name, toolchain));

    if (specification == null) {
      if (dexVm.getVersion() == DexVm.Version.DEFAULT) {
        throw new RuntimeException("Test " + name + " has no specification for toolchain"
            + toolchain + ".");
      } else {
        // For older VMs the test might not exist, as the tests are currently generates from the
        // directories present in the art test directory for AOSP master.
        return;
      }
    }

    if (specification.skipTest) {
      return;
    }

    if (specification.nativeLibrary != null && dexVm.getKind() == Kind.TARGET) {
      // JNI tests not yet supported for devices
      return;
    }

    File[] inputFiles;
    if (toolchain == DexTool.NONE) {
      inputFiles = addFileTree(new File[0], new File(specification.directory, "classes"));
      inputFiles = addFileTree(inputFiles, new File(specification.directory, "jasmin_classes"));
      File smali = new File(specification.directory, "smali");
      if (smali.exists()) {
        File smaliDex = new File(smali, "out.dex");
        assert smaliDex.exists();
        inputFiles = ObjectArrays.concat(inputFiles, smaliDex);
      }
      inputFiles = addFileTree(inputFiles, new File(specification.directory, "classes2"));
      inputFiles = addFileTree(inputFiles, new File(specification.directory, "jasmin_classes2"));
    } else {
      inputFiles =
          specification.directory.listFiles((File file) ->
              file.getName().endsWith(".dex") && !file.getName().startsWith("jasmin"));
    }

    List<String> fileNames = new ArrayList<>();
    for (File file : inputFiles) {
      fileNames.add(file.getCanonicalPath());
    }

    File resultDir = temp.newFolder(firstCompilerUnderTest.toString().toLowerCase() + "-output");

    runArtTestDoRunOnArt(
        dexVm, firstCompilerUnderTest, specification, fileNames, resultDir, compilationMode);

    if (compilerUnderTest == CompilerUnderTest.R8_AFTER_D8) {
      if (expectedException) {
        // The expected exception was not thrown while running D8.
        return;
      }

      compilationMode = CompilationMode.DEBUG;
      specification =
          getTestsMap(CompilerUnderTest.R8_AFTER_D8, compilationMode, dexVm)
              .get(new SpecificationKey(name, DexTool.DX));

      if (specification == null) {
        throw new RuntimeException(
            "Test " + name + " has no specification for toolchain" + toolchain + ".");
      }

      if (specification.skipTest) {
        return;
      }

      fileNames.clear();
      for (File file : resultDir.listFiles((File file) -> file.getName().endsWith(".dex"))) {
        fileNames.add(file.getCanonicalPath());
      }

      resultDir = temp.newFolder("r8-output");

      runArtTestDoRunOnArt(
          dexVm, CompilerUnderTest.R8, specification, fileNames, resultDir, compilationMode);
    }
  }

  private File[] addFileTree(File[] files, File directory) {
    if (!directory.exists()) {
      return files;
    }
    return ObjectArrays.concat(
        files,
        com.google.common.io.Files.fileTreeTraverser().breadthFirstTraversal(directory)
            .filter(f -> !f.isDirectory())
            .toArray(File.class),
        File.class);
  }

  private void runArtTestDoRunOnArt(
      DexVm version,
      CompilerUnderTest compilerUnderTest,
      TestSpecification specification,
      List<String> fileNames,
      File resultDir,
      CompilationMode compilationMode)
      throws Throwable {
    if (specification.expectedToFailWithX8) {
      expectException(CompilationError.class);
      try {
        executeCompilerUnderTest(
            compilerUnderTest,
            fileNames,
            resultDir.getCanonicalPath(),
            compilationMode,
            new CompilationOptions(specification));
      } catch (CompilationFailedException e) {
        throw new CompilationError(e.getMessage(), e);
      }
      System.err.println("Should have failed R8/D8 compilation with a CompilationError.");
      return;
    } else if (specification.failsWithX8) {
      expectException(Throwable.class);
      executeCompilerUnderTest(
          compilerUnderTest,
          fileNames,
          resultDir.getCanonicalPath(),
          compilationMode,
          new CompilationOptions(specification));
      System.err.println("Should have failed R8/D8 compilation with an exception.");
      return;
    } else {
      executeCompilerUnderTest(
          compilerUnderTest,
          fileNames,
          resultDir.getCanonicalPath(),
          compilationMode,
          new CompilationOptions(specification));
    }

    if (!specification.skipRun
        && (ToolHelper.artSupported() || ToolHelper.dealsWithGoldenFiles())) {
      File originalFile;
      File processedFile;

      // Collect the generated dex files.
      File[] outputFiles =
          resultDir.listFiles((File file) -> file.getName().endsWith(".dex"));
      if (outputFiles.length == 1) {
        // Just run Art on classes.dex.
        processedFile = outputFiles[0];
      } else {
        // Run Art on JAR file with multiple dex files.
        processedFile
            = temp.getRoot().toPath().resolve(specification.name + ".jar").toFile();
        buildJar(outputFiles, processedFile);
      }

      File expectedFile = specification.resolveFile("expected.txt");
      String expected =
          com.google.common.io.Files.asCharSource(expectedFile, Charsets.UTF_8).read();
      if (specification.failsOnRun) {
        expectException(AssertionError.class);
      }

      ArtCommandBuilder builder = buildArtCommand(processedFile, specification, version);
      String output;
      try {
        output = ToolHelper.runArt(builder);
      } catch (AssertionError e) {
        addDexInformationToVerificationError(fileNames, processedFile,
            specification.resolveFile("classes.dex"), e);
        throw e;
      }
      if (specification.failsOnRun) {
        System.err.println("Should have failed run with art");
        return;
      }

      File checkCommand = specification.resolveFile("check");
      if (checkCommand.exists() && !ToolHelper.isWindows()) {
        // Run the Art test custom check command.
        File actualFile = temp.newFile();
        com.google.common.io.Files.asByteSink(actualFile).write(output.getBytes(Charsets.UTF_8));
        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.command(
            specification.resolveFile("check").toString(), expectedFile.toString(),
            actualFile.toString());
        ProcessResult result = ToolHelper.runProcess(processBuilder);
        if (result.exitCode != 0 && !specification.failsWithArtOutput) {
          System.err.println("ERROR: check script failed. Building comparison of dex files");
          failWithDexDiff(specification.resolveFile("classes.dex"), processedFile);
        }
      } else {
        if (!expected.equals(output)) {
          // The expected.txt in the Android repository might not match what our version of Art
          // produces.
          originalFile = specification.resolveFile(specification.name + ".jar");
          if (specification.failsWithArtOriginalOnly) {
            expectException(AssertionError.class);
          }
          builder = buildArtCommand(originalFile, specification, version);
          expected = ToolHelper.runArt(builder);
          if (specification.failsWithArtOriginalOnly) {
            System.err.println("Original file should have failed run with art");
            return;
          }
        }
        if (specification.failsWithArtOutput) {
          expectException(ComparisonFailure.class);
        }
        if (!specification.outputMayDiffer) {
          assertEquals(expected, output);
        }
      }
    }
  }

  private void expectException(Class<? extends Throwable> exception) {
    thrown.expect(exception);
    expectedException = true;
  }

  private void failWithDexDiff(File originalFile, File processedFile)
      throws IOException, ExecutionException {
    CodeInspector inspectOriginal =
        new CodeInspector(originalFile.toPath().toAbsolutePath());
    CodeInspector inspectProcessed =
        new CodeInspector(processedFile.toPath().toAbsolutePath());
    StringBuilder builderOriginal = new StringBuilder();
    StringBuilder builderProcessed = new StringBuilder();
    inspectOriginal.forAllClasses((clazz) -> builderOriginal.append(clazz.dumpMethods()));
    inspectProcessed.forAllClasses((clazz) -> builderProcessed.append(clazz.dumpMethods()));
    assertEquals(builderOriginal.toString(), builderProcessed.toString());
    fail();
  }

  private void addDexInformationToVerificationError(
      Collection<String> inputFiles, File processedFile, File referenceFile,
      AssertionError verificationError) {
    List<ComparisonFailure> errors;
    try {
      // Parse all the verification errors.
      CodeInspector processed = new CodeInspector(processedFile.toPath());
      CodeInspector original = DEX_COMPARE_WITH_DEX_REFERENCE_ON_FAILURE
          ? new CodeInspector(referenceFile.toPath())
          : new CodeInspector(inputFiles.stream().map(Paths::get).collect(Collectors.toList()));
      List<ArtErrorInfo> errorInfo = ArtErrorParser.parse(verificationError.getMessage());
      errors = ListUtils.map(errorInfo, (error) ->
          new ComparisonFailure(
              error.getMessage(),
              "ORIGINAL\n" + error.dump(original, false) + "\nEND ORIGINAL",
              "PROCESSED\n" + error.dump(processed, true) + "\nEND PROCESSED"));
    } catch (Throwable e) {
      System.err.println("Failed to add extra dex information to the verification error:");
      e.printStackTrace();
      throw verificationError;
    }

    // If we failed to annotate anything, rethrow the original exception.
    if (errors.isEmpty()) {
      throw verificationError;
    }

    // Otherwise, we print each error and throw the last one, since Intellij only supports nice
    // comparison-diff if thrown and we can only throw one :-(
    System.err.println(verificationError.getMessage());
    for (ComparisonFailure error : errors.subList(0, errors.size() - 1)) {
      System.err.println(error.toString());
    }
    throw errors.get(errors.size() - 1);
  }

  // TODO(zerny): Refactor tests to output jar files directly and eliminate this method.
  private static void buildJar(File[] files, File jarFile) throws IOException {
    try (JarOutputStream target = new JarOutputStream(new FileOutputStream(jarFile))) {
      for (File file : files) {
        // Only use the file name in the JAR entry (classes.dex, classes2.dex, ...)
        JarEntry entry = new JarEntry(file.getName());
        entry.setTime(file.lastModified());
        target.putNextEntry(entry);
        Files.copy(file.toPath(), target);
        target.closeEntry();
      }
    }
  }
}
