Implement nightly jfuzz test runner
New script runs multiple instances of run_jfuzz_test.py and has
predefined arguments suitable for nightly runs.
Test: ./run_jfuzz_test_nightly.py
Change-Id: I8c0060d72c69bbdf88571a9272f2d3fef74697eb
diff --git a/tools/jfuzz/README.md b/tools/jfuzz/README.md
index 3eb41cf..c107db1 100644
--- a/tools/jfuzz/README.md
+++ b/tools/jfuzz/README.md
@@ -62,6 +62,18 @@
--report_script : path to script called for each divergence
--jfuzz_arg : argument for jfuzz
+How to start JFuzz nightly testing
+==================================
+
+ run_jfuzz_test_nightly.py
+ [--num_proc NUM_PROC]
+
+where
+
+ --num_proc : number of run_jfuzz_test.py instances to run (8 by default)
+
+Remaining arguments are passed to run\_jfuzz_test.py.
+
How to start J/DexFuzz testing (multi-layered)
==============================================
diff --git a/tools/jfuzz/run_jfuzz_test_nightly.py b/tools/jfuzz/run_jfuzz_test_nightly.py
new file mode 100755
index 0000000..cd338fb
--- /dev/null
+++ b/tools/jfuzz/run_jfuzz_test_nightly.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3.4
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import os
+import subprocess
+import sys
+
+from tempfile import TemporaryFile
+
+# Default arguments for run_jfuzz_test.py.
+DEFAULT_ARGS = ['--num_tests=20000']
+
+# run_jfuzz_test.py success string.
+SUCCESS_STRING = 'success (no divergences)'
+
+# Constant returned by string find() method when search fails.
+NOT_FOUND = -1
+
+def main(argv):
+ cwd = os.path.dirname(os.path.realpath(__file__))
+ cmd = [cwd + '/run_jfuzz_test.py'] + DEFAULT_ARGS
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--num_proc', default=8,
+ type=int, help='number of processes to run')
+ # Unknown arguments are passed to run_jfuzz_test.py.
+ (args, unknown_args) = parser.parse_known_args()
+ output_files = [TemporaryFile('wb+') for _ in range(args.num_proc)]
+ processes = []
+ for output_file in output_files:
+ processes.append(subprocess.Popen(cmd + unknown_args, stdout=output_file,
+ stderr=subprocess.STDOUT))
+ try:
+ # Wait for processes to terminate.
+ for proc in processes:
+ proc.wait()
+ except KeyboardInterrupt:
+ for proc in processes:
+ proc.kill()
+ # Output results.
+ for i, output_file in enumerate(output_files):
+ output_file.seek(0)
+ output_str = output_file.read().decode('ascii')
+ output_file.close()
+ print('Tester', i)
+ if output_str.find(SUCCESS_STRING) == NOT_FOUND:
+ print(output_str)
+ else:
+ print(SUCCESS_STRING)
+
+if __name__ == '__main__':
+ main(sys.argv)