Add a true divergence mode to run_jfuzz_test.py

Adds a --true_divergence switch which prevents tool from bisecting
TIMEOUT vs ERROR and TIMEOUT vs SUCCESS return code divergences.

Test: ./run_jfuzz_test.py
Change-Id: I53dd1c2b6934aafcc178fcc5dffd0b10d7a7fc5f
diff --git a/tools/jfuzz/README.md b/tools/jfuzz/README.md
index 3eb41cf..a58f1d7 100644
--- a/tools/jfuzz/README.md
+++ b/tools/jfuzz/README.md
@@ -47,20 +47,22 @@
                           [--mode1=MODE] [--mode2=MODE]
                           [--report_script=SCRIPT]
                           [--jfuzz_arg=ARG]
+                          [--true_divergence]
 
 where
 
-    --num_tests     : number of tests to run (10000 by default)
-    --device        : target device serial number (passed to adb -s)
-    --mode1         : m1
-    --mode2         : m2, with m1 != m2, and values one of
+    --num_tests       : number of tests to run (10000 by default)
+    --device          : target device serial number (passed to adb -s)
+    --mode1           : m1
+    --mode2           : m2, with m1 != m2, and values one of
       ri   = reference implementation on host (default for m1)
       hint = Art interpreter on host
       hopt = Art optimizing on host (default for m2)
       tint = Art interpreter on target
       topt = Art optimizing on target
-    --report_script : path to script called for each divergence
-    --jfuzz_arg     : argument for jfuzz
+    --report_script   : path to script called for each divergence
+    --jfuzz_arg       : argument for jfuzz
+    --true_divergence : don't bisect timeout divergences
 
 How to start J/DexFuzz testing (multi-layered)
 ==============================================
diff --git a/tools/jfuzz/run_jfuzz_test.py b/tools/jfuzz/run_jfuzz_test.py
index 05e8daf..54f9bb4 100755
--- a/tools/jfuzz/run_jfuzz_test.py
+++ b/tools/jfuzz/run_jfuzz_test.py
@@ -306,7 +306,7 @@
   """Tester that runs JFuzz many times and report divergences."""
 
   def  __init__(self, num_tests, device, mode1, mode2, jfuzz_args,
-                report_script):
+                report_script, true_divergence_only):
     """Constructor for the tester.
 
     Args:
@@ -316,6 +316,7 @@
       mode2: string, execution mode for second runner
       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
     """
     self._num_tests = num_tests
     self._device = device
@@ -323,6 +324,7 @@
     self._runner2 = GetExecutionModeRunner(device, mode2)
     self._jfuzz_args = jfuzz_args
     self._report_script = report_script
+    self._true_divergence_only = true_divergence_only
     self._save_dir = None
     self._results_dir = None
     self._jfuzz_dir = None
@@ -449,7 +451,8 @@
     for f in glob('*.txt') + ['Test.java']:
       shutil.copy(f, ddir)
     # Maybe run bisection bug search.
-    if retc1 in BISECTABLE_RET_CODES and retc2 in BISECTABLE_RET_CODES:
+    if (retc1 in BISECTABLE_RET_CODES and retc2 in BISECTABLE_RET_CODES and
+        not (self._true_divergence_only and RetCode.TIMEOUT in (retc1, retc2))):
       self.MaybeBisectDivergence(retc1, retc2, is_output_divergence)
     # Call reporting script.
     if self._report_script:
@@ -546,12 +549,15 @@
                                               'divergence')
   parser.add_argument('--jfuzz_arg', default=[], dest='jfuzz_args',
                       action='append', help='argument for jfuzz')
+  parser.add_argument('--true_divergence', default=False, action='store_true',
+                      help='don\'t bisect timeout divergences')
   args = parser.parse_args()
   if args.mode1 == args.mode2:
     raise FatalError('Identical execution modes given')
   # Run the JFuzz tester.
   with JFuzzTester(args.num_tests, args.device, args.mode1, args.mode2,
-                   args.jfuzz_args, args.report_script) as fuzzer:
+                   args.jfuzz_args, args.report_script,
+                   args.true_divergence) as fuzzer:
     fuzzer.Run()
 
 if __name__ == '__main__':