Add run-test support for running without a working patchoat/dex2oat

Also add it to the test-art target.

Bug: 17262039

Change-Id: Id31130194c46df66fc48852d6f8884f14cb08db4
diff --git a/build/Android.common_test.mk b/build/Android.common_test.mk
index dc586a0..20c5a21 100644
--- a/build/Android.common_test.mk
+++ b/build/Android.common_test.mk
@@ -78,6 +78,15 @@
 # Do you want run-tests with no prebuilding enabled run?
 ART_TEST_RUN_TEST_NO_PREBUILD ?= $(ART_TEST_FULL)
 
+# Do you want run-tests without a pregenerated core.art?
+ART_TEST_RUN_TEST_NO_IMAGE ?= $(ART_TEST_FULL)
+
+# Do you want run-tests with relocation enabled but patchoat failing?
+ART_TEST_RUN_TEST_RELOCATE_NO_PATCHOAT ?= $(ART_TEST_FULL)
+
+# Do you want run-tests without a dex2oat?
+ART_TEST_RUN_TEST_NO_DEX2OAT ?= $(ART_TEST_FULL)
+
 # Do you want failed tests to have their artifacts cleaned up?
 ART_TEST_RUN_TEST_ALWAYS_CLEAN ?= true
 
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 2f2d283..214584d 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -65,16 +65,18 @@
 # General rules to build and run a run-test.
 
 # Test rule names or of the form:
-# test-art-{1: host or target}-run-test-{2: prebuild or no-prebuild}-
-#    {3: interpreter default optimizing}-{4: relocate or no-relocate}-{5: trace or no-trace}-
-#    {6: gcstress gcverify cms}-{7: forcecopy checkjni jni}-{8: test name}{9: 32 or 64}
+# test-art-{1: host or target}-run-test-{2: prebuild no-prebuild no-dex2oat}-
+#    {3: interpreter default optimizing}-{4: relocate no-relocate relocate-no-patchoat}-
+#    {5: trace or no-trace}-{6: gcstress gcverify cms}-{7: forcecopy checkjni jni}-
+#    {8: no-image or image}-{9: test name}{10: 32 or 64}
 TARGET_TYPES := host target
-PREBUILD_TYPES := prebuild no-prebuild
+PREBUILD_TYPES := prebuild no-prebuild no-dex2oat
 COMPILER_TYPES := default interpreter optimizing
-RELOCATE_TYPES := relocate no-relocate
+RELOCATE_TYPES := relocate no-relocate relocate-no-patchoat
 TRACE_TYPES := trace no-trace
 GC_TYPES := gcstress gcverify cms
 JNI_TYPES := jni checkjni forcecopy
+IMAGE_TYPES := image no-image
 ALL_ADDRESS_SIZES := 64 32
 # List all run test names with number arguments agreeing with the comment above.
 define all-run-test-names
@@ -85,10 +87,11 @@
           $(foreach trace, $(5), \
             $(foreach gc, $(6), \
               $(foreach jni, $(7), \
-                $(foreach test, $(8), \
-                  $(foreach address_size, $(9), \
-                    test-art-$(target)-run-test-$(prebuild)-$(compiler)-$(relocate)-$(trace)-$(gc)-$(jni)-$(test)$(address_size) \
-                )))))))))
+                $(foreach image, $(8), \
+                  $(foreach test, $(9), \
+                    $(foreach address_size, $(10), \
+                      test-art-$(target)-run-test-$(prebuild)-$(compiler)-$(relocate)-$(trace)-$(gc)-$(jni)-$(image)-$(test)$(address_size) \
+                  ))))))))))
 endef  # all-run-test-names
 
 # To generate a full list or tests:
@@ -111,6 +114,7 @@
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(PREBUILD_TYPES), \
         $(COMPILER_TYPES), $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
         $(TEST_ART_TIMING_SENSITIVE_RUN_TESTS), $(ALL_ADDRESS_SIZES))
+        $(IMAGE_TYPES), $(TEST_ART_TIMING_SENSITIVE_RUN_TESTS), $(ALL_ADDRESS_SIZES))
 endif
 
 # NB 116-nodex2oat is not broken per-se it just doesn't (and isn't meant to) work with --prebuild.
@@ -145,15 +149,36 @@
 
 ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(PREBUILD_TYPES), \
     $(COMPILER_TYPES), $(RELOCATE_TYPES),trace,$(GC_TYPES),$(JNI_TYPES), \
-    $(TEST_ART_BROKEN_TRACE_RUN_TESTS), $(ALL_ADDRESS_SIZES))
+    $(IMAGE_TYPES), $(TEST_ART_BROKEN_TRACE_RUN_TESTS), $(ALL_ADDRESS_SIZES))
 
 TEST_ART_BROKEN_TRACE_RUN_TESTS :=
 
 # 115-native-bridge setup is complicated. Need to implement it correctly for the target.
 ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(PREBUILD_TYPES),$(COMPILER_TYPES), \
-    $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),115-native-bridge, \
+    $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES),115-native-bridge, \
     $(ALL_ADDRESS_SIZES))
 
+# All these tests check that we have sane behavior if we don't have a patchoat or dex2oat.
+# Therefore we shouldn't run them in situations where we actually don't have these since they
+# explicitly test for them. These all also assume we have an image.
+TEST_ART_BROKEN_FALLBACK_RUN_TESTS := \
+  116-nodex2oat \
+  117-nopatchoat \
+  118-noimage-dex2oat \
+  119-noimage-patchoat
+
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),no-dex2oat,$(COMPILER_TYPES), \
+    $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES), \
+    $(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(PREBUILD_TYPES),$(COMPILER_TYPES), \
+    $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),no-image, \
+    $(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(PREBUILD_TYPES),$(COMPILER_TYPES), \
+    relocate-no-patchoat,$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES), \
+    $(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+
 # Clear variables ahead of appending to them when defining tests.
 $(foreach target, $(TARGET_TYPES), $(eval ART_RUN_TEST_$(call name-to-var,$(target))_RULES :=))
 $(foreach target, $(TARGET_TYPES), \
@@ -175,6 +200,9 @@
   $(foreach jni, $(JNI_TYPES), \
     $(eval ART_RUN_TEST_$(call name-to-var,$(target))_$(call name-to-var,$(jni))_RULES :=)))
 $(foreach target, $(TARGET_TYPES), \
+  $(foreach image, $(IMAGE_TYPES), \
+    $(eval ART_RUN_TEST_$(call name-to-var,$(target))_$(call name-to-var,$(image))_RULES :=)))
+$(foreach target, $(TARGET_TYPES), \
   $(foreach test, $(TEST_ART_RUN_TESTS), \
     $(eval ART_RUN_TEST_$(call name-to-var,$(target))_$(call name-to-var,$(test))_RULES :=)))
 $(foreach target, $(TARGET_TYPES), \
@@ -213,9 +241,10 @@
 endif
 
 # Create a rule to build and run a tests following the form:
-# test-art-{1: host or target}-run-test-{2: prebuild or no-prebuild}-
-#    {3: interpreter default optimizing}-{4: relocate or no-relocate}-{5: trace or no-trace}-
-#    {6: gcstress gcverify cms}-{7: forcecopy checkjni jni}-{8: test name}{9: 32 or 64}
+# test-art-{1: host or target}-run-test-{2: prebuild no-prebuild no-dex2oat}-
+#    {3: interpreter default optimizing}-{4: relocate no-relocate relocate-no-patchoat}-
+#    {5: trace or no-trace}-{6: gcstress gcverify cms}-{7: forcecopy checkjni jni}-
+#    {8: no-image image}-{9: test name}{10: 32 or 64}
 define define-test-art-run-test
   run_test_options := $(addprefix --runtime-option ,$(DALVIKVM_FLAGS))
   prereq_rule :=
@@ -246,7 +275,12 @@
       test_groups += ART_RUN_TEST_$$(uc_host_or_target)_NO_PREBUILD_RULES
       run_test_options += --no-prebuild
     else
-      $$(error found $(2) expected $(PREBUILD_TYPES))
+      ifeq ($(2),no-dex2oat)
+        test_groups += ART_RUN_TEST_$$(uc_host_or_target)_NO_DEX2OAT_RULES
+        run_test_options += --no-prebuild --no-dex2oat
+      else
+        $$(error found $(2) expected $(PREBUILD_TYPES))
+      endif
     endif
   endif
   ifeq ($(3),optimizing)
@@ -272,7 +306,12 @@
       test_groups += ART_RUN_TEST_$$(uc_host_or_target)_NO_RELOCATE_RULES
       run_test_options += --no-relocate
     else
-      $$(error found $(4) expected $(RELOCATE_TYPES))
+      ifeq ($(4),relocate-no-patchoat)
+        test_groups += ART_RUN_TEST_$$(uc_host_or_target)_RELOCATE_NO_PATCHOAT_RULES
+        run_test_options += --relocate --no-patchoat
+      else
+        $$(error found $(4) expected $(RELOCATE_TYPES))
+      endif
     endif
   endif
   ifeq ($(5),trace)
@@ -318,19 +357,29 @@
       endif
     endif
   endif
-  # $(8) is the test name
-  test_groups += ART_RUN_TEST_$$(uc_host_or_target)_$(call name-to-var,$(8))_RULES
-  ifeq ($(9),64)
+  ifeq ($(8),no-image)
+    test_groups += ART_RUN_TEST_$$(uc_host_or_target)_NO_IMAGE_RULES
+    run_test_options += --no-image
+  else
+    ifeq ($(8),image)
+      test_groups += ART_RUN_TEST_$$(uc_host_or_target)_IMAGE_RULES
+    else
+      $$(error found $(8) expected $(IMAGE_TYPES))
+    endif
+  endif
+  # $(9) is the test name
+  test_groups += ART_RUN_TEST_$$(uc_host_or_target)_$(call name-to-var,$(9))_RULES
+  ifeq ($(10),64)
     test_groups += ART_RUN_TEST_$$(uc_host_or_target)_64_RULES
     run_test_options += --64
   else
-    ifeq ($(9),32)
+    ifeq ($(10),32)
       test_groups += ART_RUN_TEST_$$(uc_host_or_target)_32_RULES
     else
-      $$(error found $(9) expected $(ALL_ADDRESS_SIZES))
+      $$(error found $(10) expected $(ALL_ADDRESS_SIZES))
     endif
   endif
-  run_test_rule_name := test-art-$(1)-run-test-$(2)-$(3)-$(4)-$(5)-$(6)-$(7)-$(8)$(9)
+  run_test_rule_name := test-art-$(1)-run-test-$(2)-$(3)-$(4)-$(5)-$(6)-$(7)-$(8)-$(9)$(10)
   run_test_options := --output-path $(ART_HOST_TEST_DIR)/run-test-output/$$(run_test_rule_name) \
       $$(run_test_options)
 $$(run_test_rule_name): PRIVATE_RUN_TEST_OPTIONS := $$(run_test_options)
@@ -338,7 +387,7 @@
 $$(run_test_rule_name): $(DX) $(HOST_OUT_EXECUTABLES)/jasmin $$(prereq_rule)
 	$(hide) $$(call ART_TEST_SKIP,$$@) && \
 	  DX=$(abspath $(DX)) JASMIN=$(abspath $(HOST_OUT_EXECUTABLES)/jasmin) \
-	    art/test/run-test $$(PRIVATE_RUN_TEST_OPTIONS) $(8) \
+	    art/test/run-test $$(PRIVATE_RUN_TEST_OPTIONS) $(9) \
 	      && $$(call ART_TEST_PASSED,$$@) || $$(call ART_TEST_FAILED,$$@)
 	$$(hide) (echo $(MAKECMDGOALS) | grep -q $$@ && \
 	  echo "run-test run as top-level target, removing test directory $(ART_HOST_TEST_DIR)" && \
@@ -358,6 +407,9 @@
 ifeq ($(ART_TEST_RUN_TEST_NO_PREBUILD),true)
   test_prebuild_types += no-prebuild
 endif
+ifeq ($(ART_TEST_RUN_TEST_NO_DEX2OAT),true)
+  test_prebuild_types += no-dex2oat
+endif
 test_compiler_types :=
 ifeq ($(ART_TEST_DEFAULT_COMPILER),true)
   test_compiler_types += default
@@ -372,6 +424,9 @@
 ifeq ($(ART_TEST_RUN_TEST_NO_RELOCATE),true)
   test_relocate_types += no-relocate
 endif
+ifeq ($(ART_TEST_RUN_TEST_RELOCATE_NO_PATCHOAT),true)
+  test_relocate_types := relocate-no-patchoat
+endif
 test_trace_types := no-trace
 ifeq ($(ART_TEST_TRACE),true)
   test_trace_types += trace
@@ -387,6 +442,10 @@
 ifeq ($(ART_TEST_JNI_FORCECOPY),true)
   test_jni_types += forcecopy
 endif
+test_image_types := image
+ifeq ($(ART_TEST_RUN_TEST_NO_IMAGE),true)
+  test_image_types += no-image
+endif
 
 ADDRESS_SIZES_TARGET := $(ART_PHONY_TEST_TARGET_SUFFIX) $(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
 ADDRESS_SIZES_HOST := $(ART_PHONY_TEST_HOST_SUFFIX) $(2ND_ART_PHONY_TEST_HOST_SUFFIX)
@@ -400,8 +459,9 @@
             $(foreach trace, $(test_trace_types), \
               $(foreach gc, $(test_gc_types), \
                 $(foreach jni, $(test_jni_types), \
-                  $(eval $(call define-test-art-run-test,$(target),$(prebuild),$(compiler),$(relocate),$(trace),$(gc),$(jni),$(test),$(address_size))) \
-                )))))))))
+                  $(foreach image, $(test_image_types), \
+                    $(eval $(call define-test-art-run-test,$(target),$(prebuild),$(compiler),$(relocate),$(trace),$(gc),$(jni),$(image),$(test),$(address_size))) \
+                ))))))))))
 define-test-art-run-test :=
 test_prebuild_types :=
 test_compiler_types :=
@@ -409,6 +469,7 @@
 test_trace_types :=
 test_gc_types :=
 test_jni_types :=
+test_image_types :=
 ART_TEST_HOST_RUN_TEST_DEPENDENCIES :=
 ADDRESS_SIZES_TARGET :=
 ADDRESS_SIZES_HOST :=
@@ -445,6 +506,9 @@
   $(foreach jni, $(JNI_TYPES), $(eval \
     $(call define-test-art-run-test-group,test-art-$(target)-run-test-$(jni),$(ART_RUN_TEST_$(call name-to-var,$(target))_$(call name-to-var,$(jni))_RULES)))))
 $(foreach target, $(TARGET_TYPES), \
+  $(foreach image, $(IMAGE_TYPES), $(eval \
+    $(call define-test-art-run-test-group,test-art-$(target)-run-test-$(image),$(ART_RUN_TEST_$(call name-to-var,$(target))_$(call name-to-var,$(image))_RULES)))))
+$(foreach target, $(TARGET_TYPES), \
   $(foreach test, $(TEST_ART_RUN_TESTS), $(eval \
     $(call define-test-art-run-test-group,test-art-$(target)-run-test-$(test),$(ART_RUN_TEST_$(call name-to-var,$(target))_$(call name-to-var,$(test))_RULES)))))
 $(foreach target, $(TARGET_TYPES), \
@@ -472,6 +536,9 @@
   $(foreach jni, $(JNI_TYPES), \
     $(eval ART_RUN_TEST_$(call name-to-var,$(target))_$(call name-to-var,$(jni))_RULES :=)))
 $(foreach target, $(TARGET_TYPES), \
+  $(foreach image, $(IMAGE_TYPES), \
+    $(eval ART_RUN_TEST_$(call name-to-var,$(target))_$(call name-to-var,$(image))_RULES :=)))
+$(foreach target, $(TARGET_TYPES), \
   $(foreach test, $(TEST_ART_RUN_TESTS), \
     $(eval ART_RUN_TEST_$(call name-to-var,$(target))_$(call name-to-var,$(test))_RULES :=)))
 $(foreach target, $(TARGET_TYPES), \
@@ -485,4 +552,5 @@
 TRACE_TYPES :=
 GC_TYPES :=
 JNI_TYPES :=
+IMAGE_TYPES :=
 ALL_ADDRESS_SIZES :=
diff --git a/test/etc/host-run-test-jar b/test/etc/host-run-test-jar
index ce85eb0..bce34f6 100755
--- a/test/etc/host-run-test-jar
+++ b/test/etc/host-run-test-jar
@@ -23,6 +23,10 @@
 FLAGS=""
 COMPILER_FLAGS=""
 BUILD_BOOT_OPT=""
+PATCHOAT=""
+DEX2OAT=""
+FALSE_BIN="/bin/false"
+HAVE_IMAGE="y"
 exe="${ANDROID_HOST_OUT}/bin/dalvikvm32"
 main="Main"
 
@@ -33,6 +37,12 @@
     elif [ "x$1" = "x--prebuild" ]; then
         PREBUILD="y"
         shift
+    elif [ "x$1" = "x--no-dex2oat" ]; then
+        DEX2OAT="-Xcompiler:${FALSE_BIN}"
+        shift
+    elif [ "x$1" = "x--no-patchoat" ]; then
+        PATCHOAT="-Xpatchoat:${FALSE_BIN}"
+        shift
     elif [ "x$1" = "x--lib" ]; then
         shift
         if [ "x$1" = "x" ]; then
@@ -44,6 +54,9 @@
             LIB=${LIB/%so/dylib}
         fi
         shift
+    elif [ "x$1" = "x--no-image" ]; then
+        HAVE_IMAGE="n"
+        shift
     elif [ "x$1" = "x--boot" ]; then
         shift
         option="$1"
@@ -157,6 +170,13 @@
     COMPILER_FLAGS="${COMPILER_FLAGS} --compiler-filter=interpret-only"
 fi
 
+if [ "$HAVE_IMAGE" = "n" ]; then
+    # Set image to a place were there isn't one and then set the bootclasspath
+    # so we can create it.
+    BOOT_OPT="-Ximage:/system/framework/boot.art"
+    BOOT_OPT="${BOOT_OPT} -Xbootclasspath:$ANDROID_HOST_OUT/../common/obj/JAVA_LIBRARIES/core-libart-hostdex_intermediates/javalib.jar"
+fi
+
 if [ "$RELOCATE" = "y" ]; then
   FLAGS="${FLAGS} -Xrelocate"
   COMPILER_FLAGS="${COMPILER_FLAGS} --runtime-arg -Xnorelocate --include-patch-information"
@@ -178,7 +198,7 @@
 fi
 
 JNI_OPTS="-Xjnigreflimit:512 -Xcheck:jni"
-cmdline="$INVOKE_WITH $gdb $exe $gdbargs -XXlib:$LIB $JNI_OPTS $FLAGS $INT_OPTS $DEBUGGER_OPTS $BOOT_OPT -cp $DEX_LOCATION/$TEST_NAME.jar $main"
+cmdline="$INVOKE_WITH $gdb $exe $gdbargs -XXlib:$LIB $PATCHOAT $DEX2OAT $JNI_OPTS $FLAGS $INT_OPTS $DEBUGGER_OPTS $BOOT_OPT -cp $DEX_LOCATION/$TEST_NAME.jar $main"
 if [ "$DEV_MODE" = "y" ]; then
   if [ "$PREBUILD" = "y" ]; then
     echo "$mkdir_cmd && $prebuild_cmd && $cmdline"
@@ -190,4 +210,7 @@
 fi
 
 cd $ANDROID_BUILD_TOP
-$mkdir_cmd && $prebuild_cmd && LD_PRELOAD=libsigchain.so $cmdline "$@"
+# If we are execing /bin/false we might not be on the same ISA as libsigchain.so
+# ld.so will helpfully warn us of this. Unfortunately this messes up our error
+# checking so we will just filter out the error with a grep.
+$mkdir_cmd && $prebuild_cmd && LD_PRELOAD=libsigchain.so $cmdline "$@" 2>&1 | grep -v -E "^ERROR: ld\.so: object '.+\.so' from LD_PRELOAD cannot be preloaded: ignored\.$"
diff --git a/test/etc/push-and-run-prebuilt-test-jar b/test/etc/push-and-run-prebuilt-test-jar
index ad23edf..c1d407d 100755
--- a/test/etc/push-and-run-prebuilt-test-jar
+++ b/test/etc/push-and-run-prebuilt-test-jar
@@ -26,6 +26,10 @@
 TARGET_SUFFIX="32"
 GDB_TARGET_SUFFIX=""
 COMPILE_FLAGS=""
+FALSE_BIN="/system/bin/false"
+PATCHOAT=""
+DEX2OAT=""
+HAVE_IMAGE="y"
 
 while true; do
     if [ "x$1" = "x--quiet" ]; then
@@ -55,12 +59,21 @@
         BOOT_OPT="$1"
         BUILD_BOOT_OPT="--boot-image=${1#-Ximage:}"
         shift
+    elif [ "x$1" = "x--no-dex2oat" ]; then
+        DEX2OAT="-Xcompiler:${FALSE_BIN}"
+        shift
+    elif [ "x$1" = "x--no-patchoat" ]; then
+        PATCHOAT="-Xpatchoat:${FALSE_BIN}"
+        shift
     elif [ "x$1" = "x--relocate" ]; then
         RELOCATE="y"
         shift
     elif [ "x$1" = "x--no-relocate" ]; then
         RELOCATE="n"
         shift
+    elif [ "x$1" = "x--no-image" ]; then
+        HAVE_IMAGE="n"
+        shift
     elif [ "x$1" = "x--debug" ]; then
         DEBUGGER="y"
         shift
@@ -136,6 +149,11 @@
 
 msg "------------------------------"
 
+if [ "$HAVE_IMAGE" = "n" ]; then
+    BOOT_OPT="-Ximage:/system/non-existant/boot.art"
+    BOOT_OPT="${BOOT_OPT} -Xbootclasspath:/system/framework/core-libart.jar"
+fi
+
 ARCH=$(adb shell ls -F /data/dalvik-cache | grep -Ewo "${ARCHITECTURES_PATTERN}")
 if [ x"$ARCH" = "x" ]; then
   echo "Unable to determine architecture"
@@ -194,7 +212,7 @@
 cmdline="cd $DEX_LOCATION && export ANDROID_DATA=$DEX_LOCATION && export DEX_LOCATION=$DEX_LOCATION && \
     mkdir -p $DEX_LOCATION/dalvik-cache/$ARCH/ && \
     $INVOKE_WITH /system/bin/dex2oatd $COMPILE_FLAGS $BUILD_BOOT_OPT $BUILD_RELOCATE_OPT  --runtime-arg -classpath --runtime-arg $DEX_LOCATION/$TEST_NAME.jar --dex-file=$DEX_LOCATION/$TEST_NAME.jar --oat-file=$DEX_LOCATION/dalvik-cache/$ARCH/$(echo $DEX_LOCATION/$TEST_NAME.jar/classes.dex | cut -d/ -f 2- | sed "s:/:@:g") --instruction-set=$ARCH && \
-    $INVOKE_WITH $gdb /system/bin/dalvikvm$TARGET_SUFFIX $FLAGS $gdbargs -XXlib:$LIB $ZYGOTE $JNI_OPTS $RELOCATE_OPT $INT_OPTS $DEBUGGER_OPTS $BOOT_OPT -cp $DEX_LOCATION/$TEST_NAME.jar Main $@"
+    $INVOKE_WITH $gdb /system/bin/dalvikvm$TARGET_SUFFIX $FLAGS $gdbargs -XXlib:$LIB $PATCHOAT $DEX2OAT $ZYGOTE $JNI_OPTS $RELOCATE_OPT $INT_OPTS $DEBUGGER_OPTS $BOOT_OPT -cp $DEX_LOCATION/$TEST_NAME.jar Main $@"
 cmdfile=$(tempfile -p "cmd-" -s "-$TEST_NAME")
 echo "$cmdline" > $cmdfile
 
diff --git a/test/etc/push-and-run-test-jar b/test/etc/push-and-run-test-jar
index 06075c2..9e63bed 100755
--- a/test/etc/push-and-run-test-jar
+++ b/test/etc/push-and-run-test-jar
@@ -22,6 +22,10 @@
 FLAGS=""
 TARGET_SUFFIX="32"
 GDB_TARGET_SUFFIX=""
+FALSE_BIN="/system/bin/false"
+PATCHOAT=""
+DEX2OAT=""
+HAVE_IMAGE="y"
 
 while true; do
     if [ "x$1" = "x--quiet" ]; then
@@ -40,6 +44,15 @@
         option="$1"
         FLAGS="${FLAGS} -Xcompiler-option $option"
         shift
+    elif [ "x$1" = "x--no-image" ]; then
+        HAVE_IMAGE="n"
+        shift
+    elif [ "x$1" = "x--no-dex2oat" ]; then
+        DEX2OAT="-Xcompiler:${FALSE_BIN}"
+        shift
+    elif [ "x$1" = "x--no-patchoat" ]; then
+        PATCHOAT="-Xpatchoat:${FALSE_BIN}"
+        shift
     elif [ "x$1" = "x--runtime-option" ]; then
         shift
         option="$1"
@@ -129,6 +142,11 @@
 
 msg "------------------------------"
 
+if [ "$HAVE_IMAGE" = "n" ]; then
+    BOOT_OPT="-Ximage:/system/non-existant/boot.art"
+    BOOT_OPT="${BOOT_OPT} -Xbootclasspath:/system/framework/core-libart.jar"
+fi
+
 if [ "$QUIET" = "n" ]; then
   adb shell rm -r $DEX_LOCATION
   adb shell mkdir -p $DEX_LOCATION
@@ -172,7 +190,7 @@
 fi
 
 cmdline="cd $DEX_LOCATION && export ANDROID_DATA=$DEX_LOCATION && export DEX_LOCATION=$DEX_LOCATION && \
-    $INVOKE_WITH $gdb /system/bin/dalvikvm$TARGET_SUFFIX $FLAGS $gdbargs -XXlib:$LIB $ZYGOTE $JNI_OPTS $RELOCATE_OPT $INT_OPTS $DEBUGGER_OPTS $BOOT_OPT -cp $DEX_LOCATION/$TEST_NAME.jar Main"
+    $INVOKE_WITH $gdb /system/bin/dalvikvm$TARGET_SUFFIX $FLAGS $gdbargs -XXlib:$LIB $PATCHOAT $DEX2OAT $ZYGOTE $JNI_OPTS $RELOCATE_OPT $INT_OPTS $DEBUGGER_OPTS $BOOT_OPT -cp $DEX_LOCATION/$TEST_NAME.jar Main"
 if [ "$DEV_MODE" = "y" ]; then
   echo $cmdline "$@"
 fi
diff --git a/test/run-all-tests b/test/run-all-tests
index 98f1208..318a0de 100755
--- a/test/run-all-tests
+++ b/test/run-all-tests
@@ -101,6 +101,12 @@
     elif [ "x$1" = "x--prebuild" ]; then
         run_args="${run_args} --prebuild"
         shift;
+    elif [ "x$1" = "x--no-dex2oat" ]; then
+        run_args="${run_args} --no-dex2oat"
+        shift;
+    elif [ "x$1" = "x--no-patchoat" ]; then
+        run_args="${run_args} --no-patchoat"
+        shift;
     elif [ "x$1" = "x--always-clean" ]; then
         run_args="${run_args} --always-clean"
     elif expr "x$1" : "x--" >/dev/null 2>&1; then
@@ -123,6 +129,7 @@
         echo "    --debug --dev --host --interpreter --jvm --no-optimize"
         echo "    --no-verify -O --update --valgrind --zygote --64 --relocate"
         echo "    --prebuild --always-clean --gcstress --gcverify --trace"
+        echo "    --no-patchoat --no-dex2oat"
         echo "  Specific Runtime Options:"
         echo "    --seq                Run tests one-by-one, avoiding failures caused by busy CPU"
     ) 1>&2
diff --git a/test/run-test b/test/run-test
index 6fac03b..2b4a41d 100755
--- a/test/run-test
+++ b/test/run-test
@@ -81,6 +81,9 @@
 gc_verify="false"
 gc_stress="false"
 always_clean="no"
+have_dex2oat="yes"
+have_patchoat="yes"
+have_image="yes"
 
 while true; do
     if [ "x$1" = "x--host" ]; then
@@ -99,6 +102,15 @@
         lib="libdvm.so"
         runtime="dalvik"
         shift
+    elif [ "x$1" = "x--no-dex2oat" ]; then
+        have_dex2oat="no"
+        shift
+    elif [ "x$1" = "x--no-patchoat" ]; then
+        have_patchoat="no"
+        shift
+    elif [ "x$1" = "x--no-image" ]; then
+        have_image="no"
+        shift
     elif [ "x$1" = "x--relocate" ]; then
         relocate="yes"
         shift
@@ -261,6 +273,14 @@
     fi
 fi
 
+if [ "$have_patchoat" = "no" ]; then
+  run_args="${run_args} --no-patchoat"
+fi
+
+if [ "$have_dex2oat" = "no" ]; then
+  run_args="${run_args} --no-dex2oat"
+fi
+
 if [ ! "$runtime" = "jvm" ]; then
   run_args="${run_args} --lib $lib"
 fi
@@ -296,6 +316,10 @@
     fi
 fi
 
+if [ "$have_image" = "no" ]; then
+    run_args="${run_args} --no-image"
+fi
+
 if [ "$dev_mode" = "yes" -a "$update_mode" = "yes" ]; then
     echo "--dev and --update are mutually exclusive" 1>&2
     usage="yes"
@@ -347,6 +371,8 @@
         echo "    --zygote             Spawn the process from the Zygote." \
              "If used, then the"
         echo "                         other runtime options are ignored."
+        echo "    --no-dex2oat         Run as though dex2oat was failing."
+        echo "    --no-patchoat        Run as though patchoat was failing."
         echo "    --prebuild           Run dex2oat on the files before starting test. (default)"
         echo "    --no-prebuild        Do not run dex2oat on the files before starting"
         echo "                         the test."