| #!/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 re |
| import shutil |
| import subprocess |
| import sys |
| |
| from glob import glob |
| |
| from tempfile import mkdtemp |
| from tempfile import TemporaryFile |
| |
| # run_jfuzz_test.py success/failure strings. |
| SUCCESS_STRING = 'success (no divergences)' |
| FAILURE_STRING = 'FAILURE (divergences)' |
| |
| # Constant returned by string find() method when search fails. |
| NOT_FOUND = -1 |
| |
| def main(argv): |
| # Set up. |
| cwd = os.path.dirname(os.path.realpath(__file__)) |
| cmd = [cwd + '/run_jfuzz_test.py'] |
| 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() |
| # Run processes. |
| cmd = cmd + unknown_args |
| print() |
| print('**\n**** Nightly JFuzz Testing\n**') |
| print() |
| print('**** Running ****\n\n', cmd, '\n') |
| output_files = [TemporaryFile('wb+') for _ in range(args.num_proc)] |
| processes = [] |
| for i, output_file in enumerate(output_files): |
| print('Tester', i) |
| processes.append(subprocess.Popen(cmd, 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. |
| print('\n**** Results ****\n') |
| output_dirs = [] |
| for i, output_file in enumerate(output_files): |
| output_file.seek(0) |
| output_str = output_file.read().decode('ascii') |
| output_file.close() |
| # Extract output directory. Example match: 'Directory : /tmp/tmp8ltpfjng'. |
| directory_match = re.search(r'Directory[^:]*: ([^\n]+)\n', output_str) |
| if directory_match: |
| output_dirs.append(directory_match.group(1)) |
| if output_str.find(SUCCESS_STRING) == NOT_FOUND: |
| print('Tester', i, FAILURE_STRING) |
| else: |
| print('Tester', i, SUCCESS_STRING) |
| # Gather divergences. |
| global_out_dir = mkdtemp('jfuzz_nightly') |
| divergence_nr = 0 |
| for out_dir in output_dirs: |
| for divergence_dir in glob(out_dir + '/divergence*/'): |
| divergence_nr += 1 |
| shutil.copytree(divergence_dir, |
| global_out_dir + '/divergence' + str(divergence_nr)) |
| if divergence_nr > 0: |
| print('\n!!!! Divergences !!!!', divergence_nr) |
| else: |
| print ('\nSuccess') |
| print('\nGlobal output directory:', global_out_dir) |
| print() |
| |
| if __name__ == '__main__': |
| main(sys.argv) |