Added choice of dexer to fuzzer scripts.

Rationale:
We know you have a choice when it comes to dexers.
Thank you for flying......

Bug: 70576364

Test: dexfuzz and jfuzz scripts

Change-Id: Id3d18cd76adb9b3099dbf039314ebeb855507b72
diff --git a/tools/jfuzz/README.md b/tools/jfuzz/README.md
index 4edfe1b..bee2396 100644
--- a/tools/jfuzz/README.md
+++ b/tools/jfuzz/README.md
@@ -50,7 +50,7 @@
                           [--report_script=SCRIPT]
                           [--jfuzz_arg=ARG]
                           [--true_divergence]
-                          [--use_dx]
+                          [--dexer=DEXER]
 
 where
 
@@ -66,7 +66,7 @@
     --report_script   : path to script called for each divergence
     --jfuzz_arg       : argument for jfuzz
     --true_divergence : don't bisect timeout divergences
-    --use_dx          : use dx (rather than jack)
+    --dexer=DEXER     : use either dx, d8, or jack to obtain dex files
 
 How to start JFuzz nightly testing
 ==================================
@@ -87,14 +87,14 @@
                           [--num_tests=NUM_TESTS]
                           [--num_inputs=NUM_INPUTS]
                           [--device=DEVICE]
-                          [--use_dx]
+                          [--dexer=DEXER]
 
 where
 
-    --num_tests : number of tests to run (10000 by default)
-    --num_inputs: number of JFuzz programs to generate
-    --device    : target device serial number (passed to adb -s)
-    --use_dx    : use dx (rather than jack)
+    --num_tests   : number of tests to run (10000 by default)
+    --num_inputs  : number of JFuzz programs to generate
+    --device      : target device serial number (passed to adb -s)
+    --dexer=DEXER : use either dx, d8, or jack to obtain dex files
 
 Background
 ==========
diff --git a/tools/jfuzz/run_dex_fuzz_test.py b/tools/jfuzz/run_dex_fuzz_test.py
index ca0aec0..fdff9c0 100755
--- a/tools/jfuzz/run_dex_fuzz_test.py
+++ b/tools/jfuzz/run_dex_fuzz_test.py
@@ -41,14 +41,14 @@
 class DexFuzzTester(object):
   """Tester that feeds JFuzz programs into DexFuzz testing."""
 
-  def  __init__(self, num_tests, num_inputs, device, use_dx):
+  def  __init__(self, num_tests, num_inputs, device, dexer):
     """Constructor for the tester.
 
     Args:
       num_tests: int, number of tests to run
       num_inputs: int, number of JFuzz programs to generate
       device: string, target device serial number (or None)
-      use_dx: boolean, if True use dx rather than jack
+      dexer: string, defines dexer
     """
     self._num_tests = num_tests
     self._num_inputs = num_inputs
@@ -58,7 +58,7 @@
     self._dexfuzz_dir = None
     self._inputs_dir = None
     self._dexfuzz_env = None
-    self._use_dx = use_dx
+    self._dexer = dexer
 
   def __enter__(self):
     """On entry, enters new temp directory after saving current directory.
@@ -109,13 +109,14 @@
     Raises:
       FatalError: error when compilation fails
     """
-    if self._use_dx:
+    if self._dexer == 'dx' or self._dexer == 'd8':
       if RunCommand(['javac', 'Test.java'],
                     out=None, err='jerr.txt', timeout=30) != RetCode.SUCCESS:
         print('Unexpected error while running javac')
         raise FatalError('Unexpected error while running javac')
       cfiles = glob('*.class')
-      if RunCommand(['dx', '--dex', '--output=classes.dex'] + cfiles,
+      dx = 'dx' if self._dexer == 'dx' else 'd8-compat-dx'
+      if RunCommand([dx, '--dex', '--output=classes.dex'] + cfiles,
                     out=None, err='dxerr.txt', timeout=30) != RetCode.SUCCESS:
         print('Unexpected error while running dx')
         raise FatalError('Unexpected error while running dx')
@@ -124,7 +125,8 @@
         os.unlink(cfile)
       os.unlink('jerr.txt')
       os.unlink('dxerr.txt')
-    else:
+
+    elif self._dexer == 'jack':
       jack_args = ['-cp', GetJackClassPath(), '--output-dex', '.', 'Test.java']
       if RunCommand(['jack'] + jack_args, out=None, err='jackerr.txt',
                     timeout=30) != RetCode.SUCCESS:
@@ -132,6 +134,8 @@
         raise FatalError('Unexpected error while running Jack')
       # Cleanup on success (nothing to see).
       os.unlink('jackerr.txt')
+    else:
+      raise FatalError('Unknown dexer: ' + self._dexer)
 
   def GenerateJFuzzPrograms(self):
     """Generates JFuzz programs.
@@ -175,16 +179,16 @@
 def main():
   # Handle arguments.
   parser = argparse.ArgumentParser()
-  parser.add_argument('--num_tests', default=1000,
-                      type=int, help='number of tests to run')
-  parser.add_argument('--num_inputs', default=10,
-                      type=int, help='number of JFuzz program to generate')
-  parser.add_argument('--use_dx', default=False, action='store_true',
-                      help='use dx (rather than jack)')
+  parser.add_argument('--num_tests', default=1000, type=int,
+                      help='number of tests to run (default: 1000)')
+  parser.add_argument('--num_inputs', default=10, type=int,
+                      help='number of JFuzz program to generate (default: 10)')
+  parser.add_argument('--dexer', default='dx', type=str,
+                      help='defines dexer as dx, d8, or jack (default: dx)')
   parser.add_argument('--device', help='target device serial number')
   args = parser.parse_args()
   # Run the DexFuzz tester.
-  with DexFuzzTester(args.num_tests, args.num_inputs, args.device, args.use_dx) as fuzzer:
+  with DexFuzzTester(args.num_tests, args.num_inputs, args.device, args.dexer) as fuzzer:
     fuzzer.Run()
 
 if __name__ == '__main__':
diff --git a/tools/jfuzz/run_jfuzz_test.py b/tools/jfuzz/run_jfuzz_test.py
index dac1c79..b889940 100755
--- a/tools/jfuzz/run_jfuzz_test.py
+++ b/tools/jfuzz/run_jfuzz_test.py
@@ -43,11 +43,11 @@
 BISECTABLE_RET_CODES = (RetCode.SUCCESS, RetCode.ERROR, RetCode.TIMEOUT)
 
 
-def GetExecutionModeRunner(use_dx, device, mode):
+def GetExecutionModeRunner(dexer, device, mode):
   """Returns a runner for the given execution mode.
 
   Args:
-    use_dx: boolean, if True use dx rather than jack
+    dexer: string, defines dexer
     device: string, target device serial number (or None)
     mode: string, execution mode
   Returns:
@@ -58,13 +58,13 @@
   if mode == 'ri':
     return TestRunnerRIOnHost()
   if mode == 'hint':
-    return TestRunnerArtIntOnHost(use_dx)
+    return TestRunnerArtIntOnHost(dexer)
   if mode == 'hopt':
-    return TestRunnerArtOptOnHost(use_dx)
+    return TestRunnerArtOptOnHost(dexer)
   if mode == 'tint':
-    return TestRunnerArtIntOnTarget(use_dx, device)
+    return TestRunnerArtIntOnTarget(dexer, device)
   if mode == 'topt':
-    return TestRunnerArtOptOnTarget(use_dx, device)
+    return TestRunnerArtOptOnTarget(dexer, device)
   raise FatalError('Unknown execution mode')
 
 
@@ -117,27 +117,30 @@
 class TestRunnerWithHostCompilation(TestRunner):
   """Abstract test runner that supports compilation on host."""
 
-  def  __init__(self, use_dx):
+  def  __init__(self, dexer):
     """Constructor for the runner with host compilation.
 
     Args:
-      use_dx: boolean, if True use dx rather than jack
+      dexer: string, defines dexer
     """
     self._jack_args = ['-cp', GetJackClassPath(), '--output-dex', '.',
                        'Test.java']
-    self._use_dx = use_dx
+    self._dexer = dexer
 
   def CompileOnHost(self):
-    if self._use_dx:
+    if self._dexer == 'dx' or self._dexer == 'd8':
       if RunCommand(['javac', 'Test.java'],
                     out=None, err=None, timeout=30) == RetCode.SUCCESS:
-        retc = RunCommand(['dx', '--dex', '--output=classes.dex'] + glob('*.class'),
+        dx = 'dx' if self._dexer == 'dx' else 'd8-compat-dx'
+        retc = RunCommand([dx, '--dex', '--output=classes.dex'] + glob('*.class'),
                           out=None, err='dxerr.txt', timeout=30)
       else:
         retc = RetCode.NOTCOMPILED
-    else:
+    elif self._dexer == 'jack':
       retc = RunCommand(['jack'] + self._jack_args,
                         out=None, err='jackerr.txt', timeout=30)
+    else:
+      raise FatalError('Unknown dexer: ' + self._dexer)
     return retc
 
 
@@ -167,14 +170,14 @@
 class TestRunnerArtOnHost(TestRunnerWithHostCompilation):
   """Abstract test runner of Art on host."""
 
-  def  __init__(self, use_dx, extra_args=None):
+  def  __init__(self, dexer, extra_args=None):
     """Constructor for the Art on host tester.
 
     Args:
-      use_dx: boolean, if True use dx rather than jack
+      dexer: string, defines dexer
       extra_args: list of strings, extra arguments for dalvikvm
     """
-    super().__init__(use_dx)
+    super().__init__(dexer)
     self._art_cmd = ['/bin/bash', 'art', '-cp', 'classes.dex']
     if extra_args is not None:
       self._art_cmd += extra_args
@@ -191,13 +194,13 @@
 class TestRunnerArtIntOnHost(TestRunnerArtOnHost):
   """Concrete test runner of interpreter mode Art on host."""
 
-  def  __init__(self, use_dx):
+  def  __init__(self, dexer):
     """Constructor for the Art on host tester (interpreter).
 
     Args:
-      use_dx: boolean, if True use dx rather than jack
+      dexer: string, defines dexer
    """
-    super().__init__(use_dx, ['-Xint'])
+    super().__init__(dexer, ['-Xint'])
 
   @property
   def description(self):
@@ -214,13 +217,13 @@
 class TestRunnerArtOptOnHost(TestRunnerArtOnHost):
   """Concrete test runner of optimizing compiler mode Art on host."""
 
-  def  __init__(self, use_dx):
+  def  __init__(self, dexer):
     """Constructor for the Art on host tester (optimizing).
 
     Args:
-      use_dx: boolean, if True use dx rather than jack
+      dexer: string, defines dexer
    """
-    super().__init__(use_dx, None)
+    super().__init__(dexer, None)
 
   @property
   def description(self):
@@ -239,15 +242,15 @@
 class TestRunnerArtOnTarget(TestRunnerWithHostCompilation):
   """Abstract test runner of Art on target."""
 
-  def  __init__(self, use_dx, device, extra_args=None):
+  def  __init__(self, dexer, device, extra_args=None):
     """Constructor for the Art on target tester.
 
     Args:
-      use_dx: boolean, if True use dx rather than jack
+      dexer: string, defines dexer
       device: string, target device serial number (or None)
       extra_args: list of strings, extra arguments for dalvikvm
     """
-    super().__init__(use_dx)
+    super().__init__(dexer)
     self._test_env = DeviceTestEnv('jfuzz_', specific_device=device)
     self._dalvik_cmd = ['dalvikvm']
     if extra_args is not None:
@@ -281,14 +284,14 @@
 class TestRunnerArtIntOnTarget(TestRunnerArtOnTarget):
   """Concrete test runner of interpreter mode Art on target."""
 
-  def  __init__(self, use_dx, device):
+  def  __init__(self, dexer, device):
     """Constructor for the Art on target tester (interpreter).
 
     Args:
-      use_dx: boolean, if True use dx rather than jack
+      dexer: string, defines dexer
       device: string, target device serial number (or None)
     """
-    super().__init__(use_dx, device, ['-Xint'])
+    super().__init__(dexer, device, ['-Xint'])
 
   @property
   def description(self):
@@ -305,14 +308,14 @@
 class TestRunnerArtOptOnTarget(TestRunnerArtOnTarget):
   """Concrete test runner of optimizing compiler mode Art on target."""
 
-  def  __init__(self, use_dx, device):
+  def  __init__(self, dexer, device):
     """Constructor for the Art on target tester (optimizing).
 
     Args:
-      use_dx: boolean, if True use dx rather than jack
+      dexer: string, defines dexer
       device: string, target device serial number (or None)
     """
-    super().__init__(use_dx, device, None)
+    super().__init__(dexer, device, None)
 
   @property
   def description(self):
@@ -342,7 +345,7 @@
   """Tester that runs JFuzz many times and report divergences."""
 
   def  __init__(self, num_tests, device, mode1, mode2, jfuzz_args,
-                report_script, true_divergence_only, use_dx):
+                report_script, true_divergence_only, dexer):
     """Constructor for the tester.
 
     Args:
@@ -353,16 +356,16 @@
       jfuzz_args: list of strings, additional arguments for jfuzz
       report_script: string, path to script called for each divergence
       true_divergence_only: boolean, if True don't bisect timeout divergences
-      use_dx: boolean, if True use dx rather than jack
+      dexer: string, defines dexer
     """
     self._num_tests = num_tests
     self._device = device
-    self._runner1 = GetExecutionModeRunner(use_dx, device, mode1)
-    self._runner2 = GetExecutionModeRunner(use_dx, device, mode2)
+    self._runner1 = GetExecutionModeRunner(dexer, device, mode1)
+    self._runner2 = GetExecutionModeRunner(dexer, device, mode2)
     self._jfuzz_args = jfuzz_args
     self._report_script = report_script
     self._true_divergence_only = true_divergence_only
-    self._use_dx = use_dx
+    self._dexer = dexer
     self._save_dir = None
     self._results_dir = None
     self._jfuzz_dir = None
@@ -405,7 +408,7 @@
     print('Directory :', self._results_dir)
     print('Exec-mode1:', self._runner1.description)
     print('Exec-mode2:', self._runner2.description)
-    print('Compiler  :', 'dx' if self._use_dx else 'jack')
+    print('Dexer     :', self._dexer)
     print()
     self.ShowStats()
     for self._test in range(1, self._num_tests + 1):
@@ -525,8 +528,7 @@
                     for arg in jfuzz_cmd_str.strip().split(' -')][1:]
       wrapped_args = ['--jfuzz_arg={0}'.format(opt) for opt in jfuzz_args]
       repro_cmd_str = (os.path.basename(__file__) +
-                       ' --num_tests=1 ' +
-                       ('--use_dx ' if self._use_dx else '') +
+                       ' --num_tests=1 --dexer=' + self._dexer +
                        ' '.join(wrapped_args))
       comment = 'jfuzz {0}\nReproduce test:\n{1}\nReproduce divergence:\n{2}\n'.format(
           jfuzz_ver, jfuzz_cmd_str, repro_cmd_str)
@@ -592,21 +594,22 @@
 def main():
   # Handle arguments.
   parser = argparse.ArgumentParser()
-  parser.add_argument('--num_tests', default=10000,
-                      type=int, help='number of tests to run')
+  parser.add_argument('--num_tests', default=10000, type=int,
+                      help='number of tests to run')
   parser.add_argument('--device', help='target device serial number')
   parser.add_argument('--mode1', default='ri',
                       help='execution mode 1 (default: ri)')
   parser.add_argument('--mode2', default='hopt',
                       help='execution mode 2 (default: hopt)')
-  parser.add_argument('--report_script', help='script called for each'
-                                              ' divergence')
+  parser.add_argument('--report_script',
+                      help='script called for each divergence')
   parser.add_argument('--jfuzz_arg', default=[], dest='jfuzz_args',
-                      action='append', help='argument for jfuzz')
+                      action='append',
+                      help='argument for jfuzz')
   parser.add_argument('--true_divergence', default=False, action='store_true',
-                      help='don\'t bisect timeout divergences')
-  parser.add_argument('--use_dx', default=False, action='store_true',
-                      help='use dx (rather than jack)')
+                      help='do not bisect timeout divergences')
+  parser.add_argument('--dexer', default='dx', type=str,
+                      help='defines dexer as dx, d8, or jack (default: dx)')
   args = parser.parse_args()
   if args.mode1 == args.mode2:
     raise FatalError('Identical execution modes given')
@@ -614,7 +617,7 @@
   with JFuzzTester(args.num_tests,
                    args.device, args.mode1, args.mode2,
                    args.jfuzz_args, args.report_script,
-                   args.true_divergence, args.use_dx) as fuzzer:
+                   args.true_divergence, args.dexer) as fuzzer:
     fuzzer.Run()
 
 if __name__ == '__main__':