#!/usr/bin/env python # ===--- Benchmark_QuickCheck.in -----------------------------------------===// # # This source file is part of the Swift.org open source project # # Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors # Licensed under Apache License v2.0 with Runtime Library Exception # # See https://swift.org/LICENSE.txt for license information # See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors # # ===---------------------------------------------------------------------===// import json import os import subprocess import sys sys.path.append("@PATH_TO_DRIVER_LIBRARY@") import perf_test_driver # noqa (E402 module level import not at top of file) # This is a hacked up XFAIL list. It should really be a json file, but it will # work for now. Add in the exact name of the pass to XFAIL. XFAIL_LIST = [ ] class QuickCheckResult(perf_test_driver.Result): def __init__(self, name, success): assert(isinstance(success, bool)) did_fail = not success perf_test_driver.Result.__init__(self, name, did_fail, "", XFAIL_LIST) def print_data(self, max_test_len): fmt = '{:<%d}{:<10}' % (max_test_len + 5) print(fmt.format(self.get_name(), self.get_result())) class QuickCheckBenchmarkDriver(perf_test_driver.BenchmarkDriver): def __init__(self, binary, xfail_list, num_iters, opt_levels): perf_test_driver.BenchmarkDriver.__init__( self, binary, xfail_list, enable_parallel=True, opt_levels=opt_levels) self.num_iters = num_iters def print_data_header(self, max_test_len): fmt = '{:<%d}{:<10}' % (max_test_len + 5) print(fmt.format('Name', 'Result')) # Propagate any data from this class that is needed for individual # tests. The reason this is needed is to avoid issues with attempting to # access a value in a different process. def prepare_input(self, name): return {'num_samples': 1, 'num_iters': self.num_iters} def run_test_inner(self, data, num_iters): p = subprocess.Popen([ data['path'], "--num-samples={}".format(data['num_samples']), "--num-iters={}".format(num_iters), data['test_name']], stdout=subprocess.PIPE, stderr=subprocess.PIPE) error_out = p.communicate()[1].split("\n") result = p.returncode if result is None: raise RuntimeError("Expected one line of output") if result != 0: raise RuntimeError("Process segfaulted") return error_out def run_test(self, data, num_iters): try: args = [data, num_iters] result = perf_test_driver.run_with_timeout(self.run_test_inner, args) except Exception, e: sys.stderr.write("Child Process Failed! (%s,%s). Error: %s\n" % ( data['path'], data['test_name'], e)) sys.stderr.flush() return None return True def process_input(self, data): test_name = '({},{})'.format(data['opt'], data['test_name']) print("Running {}...".format(test_name)) sys.stdout.flush() if self.run_test(data, data['num_iters']) is None: return QuickCheckResult(test_name, success=False) return QuickCheckResult(test_name, success=True) SWIFT_BIN_DIR = os.path.dirname(os.path.abspath(__file__)) def parse_args(): import argparse parser = argparse.ArgumentParser() parser.add_argument( '--filter', type=str, default=None, help='Filter out any test that does not match the given regex') parser.add_argument('--num-iters', type=int, default=2) default_opt_levels = perf_test_driver.BenchmarkDriver_OptLevels parser.add_argument('--opt-level', choices=default_opt_levels) return parser.parse_args() if __name__ == "__main__": args = parse_args() opt_levels = perf_test_driver.BenchmarkDriver_OptLevels if args.opt_level is not None: opt_levels = [args.opt_level] l = QuickCheckBenchmarkDriver(SWIFT_BIN_DIR, XFAIL_LIST, args.num_iters, opt_levels) if l.run(args.filter): sys.exit(0) else: sys.exit(-1)