diff options
author | Derick Huth <derickhuth@gmail.com> | 2015-09-24 11:34:04 -0600 |
---|---|---|
committer | Derick Huth <derickhuth@gmail.com> | 2015-09-24 11:34:04 -0600 |
commit | 99c062c028c7f4e94fb38cde50772cfd3ea5ad3b (patch) | |
tree | 2d86a6d5a9b7dadd88ee83f9fc0f576a4ce1d451 /test-chill/testchill | |
parent | c285135eb903c31cd221f90f03e288a6b67770cd (diff) | |
download | chill-99c062c028c7f4e94fb38cde50772cfd3ea5ad3b.tar.gz chill-99c062c028c7f4e94fb38cde50772cfd3ea5ad3b.tar.bz2 chill-99c062c028c7f4e94fb38cde50772cfd3ea5ad3b.zip |
v0.2.1
Diffstat (limited to 'test-chill/testchill')
-rw-r--r-- | test-chill/testchill/__init__.py | 0 | ||||
-rw-r--r-- | test-chill/testchill/__main__.py | 368 | ||||
-rw-r--r-- | test-chill/testchill/_cpp_validate_env.py | 654 | ||||
-rw-r--r-- | test-chill/testchill/_extract.py | 98 | ||||
-rw-r--r-- | test-chill/testchill/chill.py | 326 | ||||
-rw-r--r-- | test-chill/testchill/cpp_validate.py | 165 | ||||
-rw-r--r-- | test-chill/testchill/cpp_validate/grammar.txt | 124 | ||||
-rw-r--r-- | test-chill/testchill/cpp_validate/src/validate.cpp | 29 | ||||
-rw-r--r-- | test-chill/testchill/gcov.py | 224 | ||||
-rw-r--r-- | test-chill/testchill/omega.py | 29 | ||||
-rw-r--r-- | test-chill/testchill/test.py | 381 | ||||
-rw-r--r-- | test-chill/testchill/util.py | 185 |
12 files changed, 0 insertions, 2583 deletions
diff --git a/test-chill/testchill/__init__.py b/test-chill/testchill/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/test-chill/testchill/__init__.py +++ /dev/null diff --git a/test-chill/testchill/__main__.py b/test-chill/testchill/__main__.py deleted file mode 100644 index 86415c3..0000000 --- a/test-chill/testchill/__main__.py +++ /dev/null @@ -1,368 +0,0 @@ -#TODO: setup and cleanup mechanism - -import argparse -import logging -import os -import pickle -import sys -import textwrap - -from . import chill -from . import gcov -from . import test -from . import util - - - -def make_local(argsns, arg_parser): - """ - Make the local test case list. A convinience function for testing a local copy of chill. - @params argsns Command line arguments - @params arg_parser The ArgumentParser object - """ - util.mkdir_p(os.path.join(os.getcwd(), '.staging'), temp=True) - argsns.wd = os.path.join(os.getcwd(), '.staging/wd') - argsns.bin_dir = os.path.join(os.getcwd(), '.staging/bin') - argsns.chill_tc_dir = os.path.join(os.getcwd(), 'test-cases') # formally from the commandline - argsns.chill_dir = os.path.abspath(argsns.chill_dir) - argsns.chill_build_coverage = argsns.coverage_set is not None #TODO: make arg passed to local. - argsns.chill_test_coverage = argsns.coverage_set is not None - - util.mkdir_p(argsns.wd) - util.mkdir_p(argsns.bin_dir) - util.shell('cp', [os.path.join(argsns.chill_dir, 'examples/cuda-chill/cudaize.lua'), argsns.wd]) - util.shell('cp', [os.path.join(argsns.chill_dir, 'examples/cuda-chill/cudaize.py'), argsns.wd]) - - for config in chill.ChillConfig.configs(argsns.chill_dir, argsns.bin_dir): - build_testcase = chill.BuildChillTestCase(config, options={'coverage': argsns.chill_build_coverage}, coverage_set=argsns.coverage_set) - yield build_testcase - batch_file = os.path.join(argsns.chill_tc_dir, config.name + '.tclist') - for tc in make_batch_testcaselist(argsns, arg_parser, batch_file): - yield tc - -#def make_repo(argsns, arg_parser): - """ - Make the repo test case list. A convinience function for testing chill from the repsitory. - @params argsns Command line arguments - @params arg_parser The ArgumentParser object - """ -# util.mkdir_p(os.path.join(os.getcwd(), '.staging'), temp=True) -# argsns.bin_dir = os.path.join(os.getcwd(), '.staging/bin') -# argsns.repo_dir = os.path.join(os.getcwd(), '.staging/repo') -# argsns.chill_tc_dir = os.path.join(os.getcwd(), 'test-cases') # formally from the commandline -# argsns.wd = os.path.join(os.getcwd(), '.staging/wd') -# -# util.mkdir_p(argsns.bin_dir) -# util.mkdir_p(argsns.repo_dir) -# util.mkdir_p(argsns.wd) -# -# #TODO: Should these be hard coded? -# repo_root = 'shell.cs.utah.edu/uusoc/facility/res/hallresearch/svn_repo/resRepo/projects' -# for version in ['release', 'dev']: -# new_args = util.copy(argsns) -# if version == 'dev': -# chill_repo = 'svn+ssh://{}@{}/chill/branches/cuda-chill-rose'.format(new_args.svnuser, repo_root) -# chill_repo_name = 'chill' -# omega_repo = 'svn+ssh://{}@{}/omega/branches/cuda-omega-rose'.format(new_args.svnuser, repo_root) -# omega_repo_name = 'omega' -# elif version == 'release': -# chill_repo = 'svn+ssh://{}@{}/chill/release'.format(new_args.svnuser, repo_root) -# chill_repo_name = 'chill-release' -# omega_repo = 'svn+ssh://{}@{}/omega/release'.format(new_args.svnuser, repo_root) -# omega_repo_name = 'omega-release' -# new_args.omega_dir = os.path.join(new_args.repo_dir, omega_repo_name) -# new_args.chill_dir = os.path.join(new_args.repo_dir, chill_repo_name) -# util.shell('svn', ['export', '--force', omega_repo, new_args.omega_dir]) -# util.shell('svn', ['export', '--force', chill_repo, new_args.chill_dir]) -# util.shell('cp', [os.path.join(new_args.chill_dir, 'examples/cuda-chill/cudaize.lua'), new_args.wd]) -# if version == 'dev': -# util.shell('cp', [os.path.join(new_args.chill_dir, 'examples/cuda-chill/cudaize.py'), new_args.wd]) -# # do omega: (just build it for now) -# yield omega.BuildOmegaTestCase(new_args.omega_dir ,version) -# # do chill -# for config in chill.ChillConfig.configs(new_args.omega_dir, new_args.chill_dir, new_args.bin_dir, version=version): -# yield chill.BuildChillTestCase(config, coverage_set=argsns.coverage_set) -# batch_file = os.path.join(argsns.chill_tc_dir, config.name() + '.tclist') -# if os.path.exists(batch_file): -# for tc in make_batch_testcaselist(new_args, arg_parser, batch_file): -# yield tc - -def make_runchill_testcase(argsns): - """ - Make a RunChillTestCase from the given argument namespace - @param argsns Command line arguments - """ - assert (argsns.chill_dir != None) or (argsns.bin_dir != None) - - ### Required parameters ### - wd = os.path.abspath(argsns.wd) - chill_script = os.path.abspath(argsns.chill_script) - chill_src = os.path.abspath(argsns.chill_src) - coverage_set = argsns.coverage_set - - ### Options to pass to the chill test case ### - options = dict() - options['compile-src'] = argsns.chill_test_compile_src - options['run-script'] = argsns.chill_test_run_script - options['compile-gensrc'] = argsns.chill_test_compile_gensrc - options['check-run-script-stdout'] = argsns.chill_test_check_run_script - options['coverage'] = argsns.chill_test_coverage - - ### choose interface language from script extension if none is given ### - if argsns.chill_script_lang is None: - argsns.chill_script_lang = chill.ChillConfig.ext_to_script_lang(chill_script.split('.')[-1]) - - config = chill.ChillConfig( - chill_dir = os.path.abspath(argsns.chill_dir) if argsns.chill_dir != None else None, - bin_dir = os.path.abspath(argsns.bin_dir) if argsns.bin_dir != None else None, - build_cuda = argsns.build_cuda, - script_lang = argsns.chill_script_lang) - - return chill.RunChillTestCase(config, chill_script, chill_src, wd=wd, options=options, coverage_set=coverage_set) - -def make_buildchill_testcase(argsns): - """ - Make a BuilChillTestCase from the given argument namespace - @param argsns Command line arguments - """ - assert argsns.chill_dir != None - - coverage_set = argsns.coverage_set - - options = dict() - options['coverage'] = argsns.chill_build_coverage - - config = chill.ChillConfig( - chill_dir = os.path.abspath(argsns.chill_dir) if argsns.chill_dir != None else None, - bin_dir = os.path.abspath(argsns.bin_dir) if argsns.bin_dir != None else None, - build_cuda = argsns.build_cuda, - script_lang = argsns.chill_script_lang) - - return chill.BuildChillTestCase(config, options=options, coverage_set=coverage_set) - -def make_batch_testcaselist(argsns, arg_parser, batch_file=None): - """ - Make a list of test cases from a file. - @param argsns The parent argument namespace - @param arg_parser The argument parser. Used to parse lines from the batch file. - @param batch_file The batch file name - """ - if batch_file is None: - batch_file = argsns.batch_file - with open(batch_file, 'r') as f: - for txt_line in f.readlines(): - if len(txt_line.strip()) == 0: continue # skip empty lines - if txt_line.strip().startswith('#'): continue # skip comment lines - args = util.applyenv(txt_line.strip()) # replace environment variables with thier values - args = args.split() # split by whitespace - for tc in args_to_tclist(args, arg_parser, argsns): - yield tc - -@util.callonce -def add_local_args(arg_parser): - """ - Command line arguments for the local command - @param arg_parser The local ArgumentParser object - """ - arg_parser.add_argument('chill_dir', metavar='chill-home', default='../') - #arg_parser.add_argument('-v', '--chill-branch', dest='chill_version', default='dev', choices=['release','dev']) - # - Testing should consider all interface languages. Will uncomment if testing takes too long - # arg_parser.add_argument('-i', '--interface-lang', nargs=1, action='append', dest='chill_script_lang_list', choices=['script','lua','python']) - # arg_parser.add_argument('-t', '--testcase-dir', dest='chill_tc_dir', default=os.path.join(os.getcwd(), 'test-cases/')) - arg_parser.set_defaults(wd=os.path.join(os.getcwd(), '.staging/wd')) - arg_parser.set_defaults(bin_dir=os.path.join(os.getcwd(), '.staging/bin')) - -@util.callonce -def add_repo_args(arg_parser): - """ - Command line arguments for the repo command - @param arg_parser The local ArgumentParser object - """ - arg_parser.add_argument('svnuser', metavar='svn-user-name') - -def add_boolean_option(arg_parser, name, dest, default=True, help_on=None, help_off=None): - """ - Add a boolean option. - @param parg_parser The ArgumentParser object - @param name The name of the parameter - @param dest The dest parameter passed to the ArgumentParser - @param default The default value - @param help_on The help parameter for the true option - @param help_off The help parameter for the false option - """ - group = arg_parser.add_mutually_exclusive_group() - group.add_argument('--' + name, action='store_true', dest=dest, default=default, help=help_on) - group.add_argument('--no-' + name, action='store_false', dest=dest, default=default, help=help_off) - -def add_chill_common_args(arg_parser): - """ - Common chill command line arguments. - @param arg_parser The ArgumentParser object - """ - cuda_group = arg_parser.add_mutually_exclusive_group() - cuda_group.add_argument('-u', '--target-cuda', action='store_const', const=True, dest='build_cuda', default=False, help='Test cuda-chill. (Default is chill)') - cuda_group.add_argument('-c', '--target-c', action='store_const', const=False, dest='build_cuda', default=False, help='Test chill. (Default is chill)') - arg_parser.add_argument('-i', '--interface-lang', dest='chill_script_lang', choices=['script','lua','python'], default=None, help='Chill interface language. If an interface language is not specified, it will be determined by the script file name.') - -@util.callonce -def add_chill_run_args(arg_parser): - """ - Command line arguments specific to running a chill test case - @param arg_parser The ArgumentParser object - """ - arg_parser.add_argument('chill_script', help='Chill script file.', metavar='chill-script') - arg_parser.add_argument('chill_src', help='Chill source file.', metavar='chill-src') - add_boolean_option(arg_parser, 'compile-src', dest='chill_test_compile_src', default=True, help_on='Compile source file.', help_off='Do not compile source file.') - add_boolean_option(arg_parser, 'run-script', dest='chill_test_run_script', default=True, help_on='Run chill script.', help_off='Do not run chill script.') - add_boolean_option(arg_parser, 'compile-gensrc', dest='chill_test_compile_gensrc', default=True, help_on='Compile generated source file', help_off='Do not compile generated source file.') - add_boolean_option(arg_parser, 'check-run-script', dest='chill_test_check_run_script', default=False, help_on='Diff stdout from chill script against a benchmark.') - add_boolean_option(arg_parser, 'test-coverage', 'chill_test_coverage', default=False, help_on='Run chill and record code coverage (default).', help_off='Run chill normally without recording code coverage.') - -@util.callonce -def add_chill_build_args(arg_parser): - """ - Command line arguments specific to building chill and testing the build process - @params arg_parser The ArgumentParser object - """ - add_boolean_option(arg_parser, 'build-coverage', 'chill_build_coverage', default=False, help_on='Build chill for code coverage flags (default).', help_off='Build chill normally without code coverage flags.') - -@util.callonce -def add_local_command(command_group): - """ - Add local to the subcommand group - @param command_group the subparser group object - """ - local_arg_parser = command_group.add_parser('local') - add_local_args(local_arg_parser) - local_arg_parser.set_defaults(func=lambda a, ap: make_local(a, ap)) - -@util.callonce -def add_repo_command(command_group): - """ - Add repo to the subcommand group - @param command_group the subparser group object - """ - repo_arg_parser = command_group.add_parser('repo') - add_repo_args(repo_arg_parser) - repo_arg_parser.set_defaults(func=lambda a, ap: make_repo(a, ap)) - -@util.callonce -def add_chill_command(command_group): - """ - Add chill-testcase to the subcommand group - @param command_group The subparser group object - """ - chill_arg_parser = command_group.add_parser('chill-testcase') - add_chill_run_args(chill_arg_parser) - add_chill_common_args(chill_arg_parser) - chill_arg_parser.set_defaults(func=lambda a, ap: [make_runchill_testcase(a)]) - -@util.callonce -def add_buildchill_command(command_group): - """ - Add build-chill-testcase to the subcommand group - @param command_group The subparser group object - """ - buildchill_arg_parser = command_group.add_parser('build-chill-testcase') - add_chill_common_args(buildchill_arg_parser) - add_chill_build_args(buildchill_arg_parser) - buildchill_arg_parser.set_defaults(func=lambda a, ap: [make_buildchill_testcase(a)]) - -@util.callonce -def add_batch_args(arg_parser): - """ - Command line arguments for the batch file command - @param arg_parser The ArgumentParser object - """ - arg_parser.add_argument('batch_file', help='Batch file', metavar='batch-filename') - -@util.callonce -def add_batch_command(command_group): - """ - Add batch command to the subcommand group - @param command_group The subparser group object - """ - batch_arg_parser = command_group.add_parser('batch') - add_batch_args(batch_arg_parser) - batch_arg_parser.set_defaults(func=make_batch_testcaselist) - -@util.callonce -def add_commands(arg_parser): - """ - Add the subcommand group - @param arg_parser The ArgumentParser object - """ - command_group = arg_parser.add_subparsers(title='commands') - add_local_command(command_group) - #add_repo_command(command_group) - add_chill_command(command_group) - add_buildchill_command(command_group) - add_batch_command(command_group) - -@util.callonce -def add_global_args(arg_parser): - """ - Add arguments that are used for most subcommands - @param arg_parser The ArgumentParser object - """ - arg_parser.add_argument('-w', '--working-dir', dest='wd', default=os.getcwd(), help='The working directory. (Defaults to the current directory)', metavar='working-directory') - arg_parser.add_argument('-R', '--rose-home', dest='rose_dir', default=os.getenv('ROSEHOME'), help='Rose home directory. (Defaults to ROSEHOME)', metavar='rose-home') - arg_parser.add_argument('-C', '--chill-home', dest='chill_dir', default=os.path.join(os.getcwd(), '..'), help='Chill home directory. (Defaults to CHILLHOME)', metavar='chill-home') - arg_parser.add_argument('-b', '--binary-dir', dest='bin_dir', default=os.path.join(os.getcwd(), '..'), help='Binary directory.', metavar='bin-dir') - -@util.callonce -def make_argparser(): - """ - Create the argument parser. - """ - arg_parser = argparse.ArgumentParser( - prog='python -m testchill', - description=textwrap.dedent('''\ - - To test a local working copy of chill (from the development branch): - -------------------------------------------------------------------- - - Run `python -m testchill local` - - '''), - epilog='EPILOG', - formatter_class=argparse.RawDescriptionHelpFormatter) - - add_global_args(arg_parser) - add_commands(arg_parser) - - # ... - - return arg_parser - -def args_to_tclist(args=sys.argv[1:], arg_parser=make_argparser(), argsns=None, **kwargs): - """ - Parse one line and return a list of test cases. - @params args Raw arguments to be passed to the ArgumentParser object (defaults to sys.args[1:]) - @params arg_parser The ArgumentParser object (defaults to an ArgumentParser returned by make_argparser()) - @params argsns The top level argument namespace (defaults to None) - """ - if not argsns is None: # if an argsns is given, - argsns = util.copy(argsns, exclude=['func']) # make a shallow copy, (excluding func) - argsns = arg_parser.parse_args(args, namespace=argsns) - for k,v in kwargs.items(): - setattr(argsns, k, v) - return list(argsns.func(argsns, arg_parser)) - -@util.callonce -def main(): - coverage = gcov.GcovSet() - results = list(test.run(args_to_tclist(coverage_set=coverage))) - test.pretty_print_results(results) - util.rmtemp() - - with open('coverage.pickle', 'wb') as f: - pickle.dump(coverage, f, 2) - with open('testresults.pickle', 'wb') as f: - pickle.dump(results, f, 2) - - if any(s.failed() or s.errored() for s in results): - sys.exit(1) - -if __name__ == '__main__': - main() - diff --git a/test-chill/testchill/_cpp_validate_env.py b/test-chill/testchill/_cpp_validate_env.py deleted file mode 100644 index 9ef5a71..0000000 --- a/test-chill/testchill/_cpp_validate_env.py +++ /dev/null @@ -1,654 +0,0 @@ -import ast as _pyast -import collections as _pycollections -import functools as _pyfunctools -import itertools as _pyitertools -import random as _pyrandom -import struct as _pystruct -import types as _pytypes - -from . import util as _chill_util - -_pylambdatype = _pycollections.namedtuple('LambdaType', ['paramtypes','exprtype']) -_pyarraytype = _pycollections.namedtuple('ArrayType', ['dimensions','basetype']) - -_runtime_globals = dict({ - '_pyitertools':_pyitertools, - '_pyrandom':_pyrandom - }) - -def _evalexpr(expr, target_type, bindings): - glbls = dict(bindings) - glbls.update(_runtime_globals) - if target_type is None: - pytype = None - else: - pytype = target_type.getpytype() - expr = _pyast.Expression(expr.compile_expr(pytype)) - expr = _pyast.fix_missing_locations(expr) - return eval(compile(expr, '<string>', 'eval'), glbls) - -def _addbindings(expr, binding_frame): - if hasattr(expr, 'binding_stack'): - expr.binding_stack = [binding_frame] + expr.binding_stack - return expr - - -class _TreeNode(object): - def print_tree(self, stream=None, indent=0): - strname = type(self).__name__ - stream.write(strname + ':\n') - indent += 2 - for k,v in vars(self).items(): - if isinstance(v, _TreeNode): - stream.write(('{}{}:'.format(' '*indent, k))) - v.print_tree(stream, indent + len(k)) - elif isinstance(v, list): - stream.write(('{}{}: [\n'.format(' '*indent, k))) - for itm in v: - if isinstance(itm, _TreeNode): - stream.write(' '*indent) - itm.print_tree(stream, indent + len(k) + 1) - else: - stream.write('{}{}\n'.format(' '*(indent + 1), str(itm))) - else: - stream.write(('{}{}: {}\n'.format(' '*indent, k, str(v)))) - -class _CppType(_TreeNode): - def __init__(self): - pass - - def __repr__(self): - return "{}".format(str(self)) - - def statictype(self, bindings): - return self - - def formatdata(self, data): - raise NotImplementedError - - def get_cdecl_stmt(self, param_name): - raise NotImplementedError - - def get_cread_stmt(self, param_name, istream_name, dims): - raise NotImplementedError - - def get_cwrite_stmt(self, param_name, ostream_name, dims): - raise NotImplementedError - - def getfreevars(self, glbls): - raise NotImplementedError - - -class _CppPrimitiveType(_CppType): - _bycppname = { - 'char': ('char', 'c', 1, False, False, True, False), - 'signed char': ('signed char', 'b', 1, True, False, False, False), - 'unsigned char': ('unsigned char', 'B', 1, True, False, False, False), - 'short': ('short', 'h', 2, True, False, False, True), - 'unsigned short': ('unsigned short', 'H', 2, True, False, False, False), - 'int': ('int', 'i', 4, True, False, False, True), - 'unsigned int': ('unsigned int', 'I', 4, True, False, False, False), - 'long': ('long', 'l', 4, True, False, False, True), - 'unsigned long': ('unsigned long', 'L', 4, True, False, False, False), - 'long long': ('long long', 'q', 8, True, False, False, True), - 'unsigned long long': ('unsigned long long', 'Q', 8, True, False, False, False), - 'float': ('float', 'f', 4, False, True, False, True), - 'double': ('double', 'd', 8, False, True, False, True) - } - def __init__(self, cppname, structfmt, size, isint, isfloat, ischar, issigned): - _CppType.__init__(self) - self.cppname = cppname - self.size = size - self.size_expr = 'sizeof(' + cppname + ')' - self.structfmt = structfmt - self.isint = isint - self.isfloat = isfloat - self.ischar = ischar - self.issigned = issigned - - @staticmethod - def get_from_cppname(cppname): - return _CppPrimitiveType(*_CppPrimitiveType._bycppname[cppname]) - - def getfreevars(self, glbls): - return set() - - def getpytype(self): - if self.ischar: - return str - elif self.isint: - return int - elif self.isfloat: - return float - - def __str__(self): - return self.cppname - - def formatdata(self, data): - return [1], _pystruct.pack(self.structfmt, data) - - def get_cdecl_stmt(self, param_name): - return '{} {};'.format(self.cppname, param_name) - - def get_cread_stmt(self, param_name, istream_name, dims): - return '{}.read((const char*)&{}, {});'.format(istream_name, param_name, self.size_expr) - - def get_cwrite_stmt(self, param_name, ostream_name, dims): - return '{}.write((const char*)&{}, {});'.format(ostream_name, param_name, self.size_expr) - - -class _CppVoidType(_CppType): - def __init__(self): - self.cppname = 'void' - - def getfreevars(self, glbls): - return set() - - def getpytype(self): - return type(None) - - def __str__(self): - return 'void' - - -class _CppArrayType(_CppType): - def __init__(self, basetype, dims=[None]): - _CppType.__init__(self) - self.basetype = basetype - self.dimensions = dims - - def getfreevars(self, glbls): - freevars = self.basetype.getfreevars(glbls) - for fv in iter(d.getfreevars(glbls) for d in self.dimensions if hasattr(d, 'getfreevars')): - freevars = freevars | fv - return freevars - - def getpytype(self): - return _pyarraytype(self.dimensions, self.basetype.getpytype()) - - def __str__(self): - return '{}[{}]'.format(str(self.basetype), ']['.join(map(str,self.dimensions))) - - def statictype(self, bindings): - dim_list = list() - for dim in self.dimensions: - if dim is None: - dim_list.append(None) - else: - dim_list.append(_evalexpr(dim, _CppPrimitiveType.get_from_cppname('int'), bindings)) - return _CppArrayType(self.basetype.statictype(bindings), dim_list) - - def _formatdata_array(self, unit_length, data): - read_length = 0 - if _chill_util.python_version_major == 2: - read_data = '' - else: - read_data = bytes() - while read_length < len(data): - for i in range(unit_length): - _, b = self.basetype.formatdata(data[read_length+i]) - read_data += b - read_length += unit_length - return read_data - - def formatdata(self, data): - prod = lambda l: _pyfunctools.reduce(lambda a,v: a*v, l, 1) - if self.dimensions[0] is None: - return self.dimensions, self._formatdata_array(prod(self.dimensions[1:]), data) - else: - return self.dimensions, self._formatdata_array(prod(self.dimensions), data) - - def get_cdecl_stmt(self, param_name): - return '{} {}[{}];'.format(str(self.basetype), param_name, ']['.join(map(str,self.dimensions))) - - def get_cread_stmt(self, param_name, istream_name, dims): - length = _pyfunctools.reduce(lambda a,v: a*v, self.dimensions) - #TODO: use dims - if isinstance(self.basetype, _CppPrimitiveType): - size_expr = '{}*{}'.format(length, self.basetype.size_expr) - return '{}.read((char*){}, {});'.format(istream_name, param_name, size_expr) - else: - raise NotImplementedError - - def get_cwrite_stmt(self, param_name, ostream_name, dims): - length = _pyfunctools.reduce(lambda a,v: a*v, self.dimensions) - #TODO: use dims - if isinstance(self.basetype, _CppPrimitiveType): - size_expr = '{}*{}'.format(length, self.basetype.size_expr) - return '{}.write((char*){}, {});'.format(ostream_name, param_name, size_expr) - else: - raise NotImplementedError - - -class _CppPointerType(_CppType): - def __init__(self, basetype): - _CppType.__init__(self) - self.basetype = basetype - - def getfreevars(self, glbls): - return self.basetype.getfreevars(glbls) - - def getpytype(self): - return self.basetype.getpytype() - - def __str__(self): - return '{}*'.format(str(self.basetype)) - - def statictype(self, bindings): - return _CppPointerType(self.basetype.statictype(bindings)) - - def formatdata(self, data): - if isinstance(data, list): - if _chill_util.python_version_major == 2: - read_data = '' - else: - read_data = bytes() - for data_item in data: - next_dims, b = self.basetype.formatdata(data_item) - read_data += b - return [len(data)] + next_dims, read_data - else: - dims, fmt_data = self.basetype.formatdata(data) - return [1] + dims, fmt_data - - -class _CppReferenceType(_CppType): - def __init__(self, basetype): - _CppType.__init__(self) - self.basetype = basetype - - def getfreevars(self, glbls): - return self.basetype.getfreevars(glbls) - - def getpytype(self): - return self.basetype.getpytype() - - def __str__(self): - return '{}&'.format(str(self.basetype)) - - def statictype(self, bindings): - return _CppReferenceType(self.basetype.statictype(bindings)) - - def formatdata(self, data): - dims, fmt_data = self.basetype.formatdata(data) - return dims, fmt_data - - -class _Parameter(_TreeNode): - def __init__(self, name, cpptype, direction, init_expr=None): - self.name = name - self.direction = direction - self.cpptype = cpptype - self.init_expr = init_expr - self._generated = None - - @staticmethod - def order_by_freevars(param_list, glbls=set()): - defined_names = set() - parameter_names = set(p.name for p in param_list) - param_queue = _pycollections.deque(param_list) - while len(param_queue): - param = param_queue.popleft() - freevars = (parameter_names & param.getfreevars(glbls)) - defined_names - if not len(freevars): - defined_names.add(param.name) - yield param - else: - param_queue.append(param) - - def getfreevars(self, glbls=set()): - freevars = set() - if self.init_expr is not None: - freevars = freevars | self.init_expr.getfreevars(glbls) - freevars = freevars | self.cpptype.getfreevars(glbls) - return freevars - - def generatedata(self, bindings=dict()): - if self._generated is None: - if self.init_expr is None: - py_data = None - else: - py_data = _evalexpr(self.init_expr, self.cpptype, bindings) - static_type = self.cpptype.statictype(bindings) - dims, data = static_type.formatdata(py_data) - self._generated = (self.name, static_type, dims, data) - return self.name, static_type, dims, data - else: - return self._generated - - -class _Procedure(_TreeNode): - def __init__(self, name, rtype, parameters): - self.name = name - self.rtype = rtype - self.parameters = parameters - self.binding_stack = [] - self._bindings = None - self._params_orderd = None - self._invoke_str = '{}({});'.format(self.name, ','.join([p.name for p in parameters])) - - def _order_params(self): - if not self._params_orderd: - self._params_orderd = list(_Parameter.order_by_freevars(self.parameters)) - - def _compute_bindings(self, global_bindings): - local_bindings = dict(global_bindings) - if self._bindings is None: - new_bindings = dict() - for binding_frame in self.binding_stack: - for name, (ctype, expr) in binding_frame.items(): - value = _evalexpr(expr, ctype, local_bindings) - new_bindings[name] = value - local_bindings[name] = value - self._bindings = new_bindings - local_bindings.update(self._bindings) - return local_bindings - - def generatedata(self, direction_list, global_bindings=None): - self._order_params() - if global_bindings is None: - global_bindings = dict() - bindings = self._compute_bindings(global_bindings) - for param in (p for p in self._params_orderd if p.direction in direction_list): - p_name, p_statictype, p_dims, p_data = param.generatedata(bindings) - #TODO: add binding - yield p_name, p_statictype, p_dims, p_data - - def generatedecls(self, bindings): - for p_name, p_statictype, p_dims, p_data in self.generatedata(['in','out','inout'], bindings): - yield p_statictype.get_cdecl_stmt(p_name) - #for p_name, p_statictype, p_dims, p_data in self.generatedata('out', bindings): - # yield p_statictype.get_cdecl_stmt(p_name) - - def generatereads(self, direction_list, stream, bindings): - for p_name, p_statictype, p_dims, p_data in self.generatedata(direction_list, bindings): - yield p_statictype.get_cread_stmt(p_name, stream, p_dims) - - def generatewrites(self, stream, bindings): - for p_name, p_statictype, p_dims, p_data in self.generatedata(['inout', 'out'], bindings): - yield p_statictype.get_cwrite_stmt(p_name, stream, p_dims) - - def getinvokestr(self): - return self._invoke_str - - -class _Expr(_TreeNode): - def __init__(self): - pass - - def getfreevars(self, glbls): - raise NotImplementedError - - def compile_to_lambda(self, glbls, target_type): - args = _pyast.arguments(list(_pyast.Name(n, _pyast.Param()) for n in self.getfreevars(self, glbls)), None, None, []) - expr = _pyast.Expression(_pyast.Lambda(args, self.compile_expr(target_type))) - expr = _pyast.fix_missing_locations(expr) - return eval(compile(expr, '<string>', 'eval')) - - def compile_expr(self, target_type): - raise NotImplementedError - - -class _ConstantExpr(_Expr): - def __init__(self, value): - self.value = value - - def compile_expr(self, target_type): - if target_type is None: - return _pyast.parse(self.value, '<string>', 'eval').body - elif target_type == chr: - return _pyast.Str(chr(self.value)) - elif target_type == int: - return _pyast.Num(int(self.value)) - elif target_type == str: - return _pyast.Str(str(self.value)) - elif target_type == float: - return _pyast.Num(float(self.value)) - - def getfreevars(self, glbls): - return set() - - def __str__(self): - return self.value - - -class _NameExpr(_Expr): - def __init__(self, name): - self.name = name - - def compile_expr(self, target_type): - return _pyast.Name(self.name, _pyast.Load()) - - def getfreevars(self, glbls): - if self.name not in glbls: - return set([self.name]) - else: - return set() - - def __str__(self): - return self.name - - -class _AttributeExpr(_Expr): - def __init__(self, expr, name): - self.expr = expr - self.name = name - - def compile_expr(self, target_type): - return _pyast.Attribute( - self.expr.compile_expr(None), - self.name, - _pyast.Load()) - - def getfreevars(self, glbls): - return self.expr.getfreevars(glbls) - - def __str__(self): - return '{}.{}'.format(str(self.expr), self.name) - - -class _BinExpr(_Expr): - _optypes = { - '+': _pyast.Add, - '-': _pyast.Sub, - '*': _pyast.Mult, - '**': _pyast.Pow, - '/': _pyast.Div - } - def __init__(self, left, op, right): - self.left = left - self.right = right - self.op = op - - def compile_expr(self, target_type): - return _pyast.BinOp( - self.left.compile_expr(target_type), - _BinExpr._optypes[self.op](), - self.right.compile_expr(target_type)) - - def getfreevars(self, glbls): - return self.left.getfreevars(glbls) | self.right.getfreevars(glbls) - - def __str__(self): - return '({}{}{})'.format(str(self.left),self.op,str(self.right)) - - -class _UnaryExpr(_Expr): - _optypes = { - '-': _pyast.USub - } - def __init__(self, op, expr): - self.op = op - self.expr = expr - - def compile_expr(self, target_type): - return _pyast.UnaryOp( - _UnaryExpr._optypes[self.op](), - self.expr.compile_expr(target_type)) - - def getfreevars(self, glbls): - return self.expr.getfreevars(glbls) - - def __str__(self): - return '({}{})'.format(self.op, str(self.expr)) - - -class _LambdaExpr(_Expr): - def __init__(self, params, expr): - self.params = params - self.expr = expr - - def compile_expr(self, target_type): - if target_type is None: - exprtype = None - else: - assert hasattr(target_type, 'paramtypes') - assert hasattr(target_type, 'exprtype') - exprtype = target_type.exprtype - if _chill_util.python_version_major == 2: - return _pyast.Lambda( - _pyast.arguments([_pyast.Name(p, _pyast.Param()) for p in self.params], None, None, []), - self.expr.compile_expr(exprtype)) - else: - return _pyast.Lambda( - _pyast.arguments([_pyast.arg(p, None) for p in self.params], None, None, [], None, None, [], []), - self.expr.compile_expr(exprtype)) - - def getfreevars(self, glbls): - new_glbls = set(glbls) - new_glbls = new_glbls | set(self.params) - return self.expr.getfreevars(new_glbls) - - def __str__(self): - return 'lambda {}:{}'.format(','.join(map(str,self.params)), str(self.expr)) - - -class _InvokeExpr(_Expr): - def __init__(self, func, parameters): - self.func = func - self.parameters = parameters - - def compile_expr(self, target_type): - if target_type is None: - lt = None - else: - lt = _pylambdatype([None for p in self.parameters], target_type) - return _pyast.Call( - self.func.compile_expr(lt), - [p.compile_expr(None) for p in self.parameters], - [], - None, - None) - - def getfreevars(self, glbls): - return set( - self.func.getfreevars(glbls) | - _pyfunctools.reduce(lambda a,v: a | v.getfreevars(glbls), self.parameters, set())) - - def __str__(self): - return '{}({})'.format(str(self.func),','.join(map(str,self.parameters))) - - -class _Generator(_Expr): - def __init__(self): - _Expr.__init__(self) - - -class _MatrixGenerator(_Generator): - def __init__(self, dims, genexpr): - self.dimensions = dims - self.genexpr = genexpr - - def _compile_dims(self, target_type): - if hasattr(target_type, 'dimensions'): - dim_exprs = list() - assert len(target_type.dimensions) == len(self.dimensions) - for i, d in enumerate(target_type.dimensions): - if d is None: - d = self.dimensions[i] - dim_exprs += [d.compile_expr(int)] - else: - dim_exprs = [d.compile_expr(int) for d in self.dimensions] - return _pyast.List(dim_exprs, _pyast.Load()) - - def _lambda_type(self, target_type): - if hasattr(target_type, 'dimensions'): - return _pylambdatype([int for d in target_type.dimensions], target_type.basetype) - else: - return _pylambdatype([int for d in self.dimensions], target_type) - - def compile_expr(self, target_type): - assert target_type is not None - dims = self._compile_dims(target_type) - ltype = self._lambda_type(target_type) - - #def array(func,dims): - # return [func(*d) for d in itertools.product(*(map(range,dims))] - elt_expr = _pyast.Call(self.genexpr.compile_expr(ltype), [], [], _pyast.Name('_d', _pyast.Load()), None) # func(*d) - # elt_expr = _pyast.Call(_pyast.Name('tuple', _pyast.Load()), [_pyast.Name('_d', _pyast.Load()), elt_expr], [], None, None) # tuple(d, func(*d)) - pdt_expr = _pyast.Attribute(_pyast.Name('_pyitertools', _pyast.Load()), 'product', _pyast.Load()) # itertools.product - itr_expr = _pyast.Call(_pyast.Name('map', _pyast.Load()), [_pyast.Name('range', _pyast.Load()), dims], [], None, None) # map(range,dims) - itr_expr = _pyast.Call(pdt_expr, [], [], itr_expr, None) # itertools.product(*(map(range,dims))) - return _pyast.ListComp( - elt_expr, - [_pyast.comprehension(_pyast.Name('_d', _pyast.Store()), itr_expr, [])]) - - def getfreevars(self, glbls): - return set( - self.genexpr.getfreevars(glbls) | - _pyfunctools.reduce(lambda a,v: a | v.getfreevars(glbls), filter(lambda x: x is not None, self.dimensions), set())) - - def __str__(self): - return 'matrix([{}],{})'.format(','.join(map(str,self.dimensions)),str(self.genexpr)) - - -class _RandomExpr(_Expr): - def __init__(self, minexpr, maxexpr): - self.minexpr = minexpr - self.maxexpr = maxexpr - self.expr = _BinExpr( - _BinExpr( - _InvokeExpr(_AttributeExpr(_NameExpr('_pyrandom'),'random'),[]), - '*', - _BinExpr(maxexpr, '-', minexpr)), - '+', - minexpr) - - def getfreevars(self, glbls): - return self.minexpr.getfreevars(glbls) | self.maxexpr.getfreevars(glbls) - - def compile_expr(self, target_type): - if target_type == int: - return _pyast.Call(_pyast.Name('int', _pyast.Load()),[self.expr.compile_expr(float)],[],None,None) - elif target_type == float: - return self.expr.compile_expr(target_type) - elif target_type is None: - return self.expr.compile_expr(None) - assert False - - def __str__(self): - return 'random({},{})'.format(str(self.minexpr),str(self.maxexpr)) - - -### What to import from * ### -addbindings = _addbindings - -CppType = _CppType -CppPrimitiveType = _CppPrimitiveType -CppVoidType = _CppVoidType -CppArrayType = _CppArrayType -CppPointerType = _CppPointerType - -ConstantExpr = _ConstantExpr -NameExpr = _NameExpr -AttributeExpr = _AttributeExpr -BinExpr = _BinExpr -UnaryExpr = _UnaryExpr -LambdaExpr = _LambdaExpr -InvokeExpr = _InvokeExpr -MatrixGenerator = _MatrixGenerator -RandomExpr = _RandomExpr - -Procedure = _Procedure -Parameter = _Parameter - diff --git a/test-chill/testchill/_extract.py b/test-chill/testchill/_extract.py deleted file mode 100644 index f6984ac..0000000 --- a/test-chill/testchill/_extract.py +++ /dev/null @@ -1,98 +0,0 @@ -import collections -import os -import os.path -import itertools -import re - -from . import util - -if util.python_version_major == 2: - from HTMLParser import HTMLParser -else: - from html.parser import HTMLParser - -class _TagExtractor(HTMLParser): - _comment_style_expr = { - 'c': [('/(/)+',r'[\n]'),(r'/\*',r'\*/')], - 'cc': [('/(/)+',r'[\n]'),(r'/\*',r'\*/')], - 'cpp': [('/(/)+',r'[\n]'),(r'/\*',r'\*/')], - 'h': [('/(/)+',r'[\n]'),(r'/\*',r'\*/')], - 'hh': [('/(/)+',r'[\n]'),(r'/\*',r'\*/')], - 'hpp': [('/(/)+',r'[\n]'),(r'/\*',r'\*/')], - 'py': [('#+',r'[\n]'),('\'\'\'',),('"""',)], - 'script': [('#+',r'[\n]')], - 'lua': [(r'--\[\[',r'\]\]--')] - } - - def __init__(self, tagname): - HTMLParser.__init__(self) - self.tagname = tagname - self._readin = False - self._value = '' - - def handle_starttag(self, tag, attrs): - if tag == self.tagname: - self._readin = True - self._attrs = dict(attrs) - - def handle_endtag(self, tag): - if tag == self.tagname: - self._readin = False - self._tag_list.append((self._value, self._attrs)) - self._value = '' - - def handle_data(self, txt): - if self._readin: - self._value += txt - - @classmethod - def _parse(cls, tagname, txt): - reader = cls(tagname) - reader._readin = False - reader._value = '' - reader._tag_list = [] - reader.feed(txt) - return reader._tag_list - - @classmethod - def _get_commentstyles(cls, ext): - for comment_style in cls._comment_style_expr[ext]: - if len(comment_style) == 1: - start_expr = comment_style[0] - end_expr = comment_style[0] - elif len(comment_style) == 2: - start_expr = comment_style[0] - end_expr = comment_style[1] - yield start_expr, end_expr - - @classmethod - def _commented(cls, txt, ext): - comment_spans = list() - for start_expr, end_expr in cls._get_commentstyles(ext): - pos = 0 - while pos < len(txt): - start_match = re.search(start_expr, txt[pos:]) - if start_match: - start_pos = pos + start_match.end() - end_match = re.search(end_expr, txt[start_pos:]) - if end_match: - end_pos = start_pos + end_match.start() - pos = start_pos + end_match.end() - else: - end_pos = len(txt) - pos = end_pos - comment_spans.append((start_pos, end_pos)) - else: - break - for span in sorted(comment_spans, key=lambda s: s[0]): - yield txt[span[0]:span[1]] - - @classmethod - def extract_tag(cls, tagname, filename, wd=os.getcwd()): - with open(os.path.join(wd, filename), 'r') as f: - txt = f.read() - ext = filename.split('.')[-1] - return cls._parse(tagname, '\n'.join(cls._commented(txt, ext))) - -extract_tag = _TagExtractor.extract_tag - diff --git a/test-chill/testchill/chill.py b/test-chill/testchill/chill.py deleted file mode 100644 index b6d39cf..0000000 --- a/test-chill/testchill/chill.py +++ /dev/null @@ -1,326 +0,0 @@ -#TODO: Re-Document -#TODO: highlight test implementation hooks - -import os -import os.path - -from . import gcov -from . import test -from . import util -from . import cpp_validate - - -class ChillConfig(object): - def __init__(self, chill_dir=None, bin_dir=None, build_cuda=False, script_lang=None): - self.build_cuda = build_cuda - self.script_lang = script_lang - self.chill_dir = chill_dir - self.bin_dir = bin_dir - if self.script_lang is None: - self.script_lang = self.default_script_lang() - - def default_script_lang(self): - return 'python' - - def _buildfunc(self, cc, link=True): - if not link: - compile_args = ['-c -Wuninitialized'] - elif link and cc == 'nvcc': - compile_args = ['-L/usr/local/cuda/lib64/lib', '-lcuda', '-lcudart', '-lstdc++', '-lrt', '-Wuninitialized'] - else: - compile_args = ['-lstdc++', '-lrt', '-Wuninitialized'] - - def build(src, dest, args=[], defines={}, wd=None): - if wd is None: - wd = os.path.dirname(src) - args += ['-D{}={}'.format(k,v) for k, v in defines.items()] - dest = os.path.join(wd, dest) - stdout = util.shell(cc, args + [src, '-o', dest] + compile_args, wd=wd) - return dest, stdout - return build - - def compile_src_func(self): - return self._buildfunc('gcc', False) - - def compile_gensrc_func(self): - if self.build_cuda: - return self._buildfunc('nvcc', False) - else: - return self._buildfunc('gcc', False) - - def build_src_func(self): - return self._buildfunc('gcc') - - def build_gensrc_func(self): - if self.build_cuda: - return self._buildfunc('nvcc') - else: - return self._buildfunc('gcc') - - @property - def config_args(self): - args = [] - if self.build_cuda: - args += ['--enable-cuda'] - if self.script_lang is not None: - args += ['--with-' + self.script_lang] - return args - - @property - def buildname(self): - if self.build_cuda: - return 'cudachill' - else: - return 'chill' - - @property - def name(self): - if self.buildname == 'cudachill': - return 'cuda-chill-' + self.script_lang - else: - return 'chill-' + self.script_lang - - @staticmethod - def ext_to_script_lang(ext): - return {'script':'script', 'lua':'lua', 'py':'python'}[ext] - - @staticmethod - def configs(chill_dir, bin_dir, build_cuda=None, script_lang=None): - all_configs = [ - (False, 'script'), - (False, 'lua'), - (False, 'python'), - (True, 'lua'), - (True, 'python')] - - pred_list = [lambda x: True] - if not build_cuda is None: - pred_list += [lambda x: x[0] == build_cuda] - if not script_lang is None: - pred_list += [lambda x: x[1] == script_lang] - - cond = lambda x: all(p(x) for p in pred_list) - - return iter(ChillConfig(chill_dir, bin_dir, *conf) for conf in filter(cond, all_configs)) - - -# - - # -# - Test case for building chill - # -# - - # -class BuildChillTestCase(test.TestCase): - """ - Test case for building chill. - """ - - default_options = { - 'coverage': False # compile for coverage - } - - def __init__(self, config, options={}, coverage_set=None): - """ - @param config chill configuration object - @param options options for building chill and testing the build process - @param coverage_set GcovSet object to record coverage - """ - assert isinstance(config, ChillConfig) - if config.script_lang == None: - config.script_lang = config.default_script_lang() - self.config = config - super(BuildChillTestCase,self).__init__(self.config.name) - self._set_options(options, coverage_set) - - def _set_options(self, options, coverage_set): - self.options = dict(BuildChillTestCase.default_options) - self.options.update(options) - - if self.options['coverage']: - coverage_set.addprogram(self.config.name, self.config.chill_dir) - - def setUp(self): - """ - Called before run, outside of the context of a test case - """ - # clean up any coverage files from a previous build - util.shell('rm', ['-f', '*.gcno'], wd=self.config.chill_dir) - util.shell('rm', ['-f', '*.gcov'], wd=self.config.chill_dir) - util.shell('rm', ['-f', '*.gcda'], wd=self.config.chill_dir) - - util.shell('make clean', wd=self.config.chill_dir) - - def run(self): - """ - Build chill - """ - util.shell('make', ['distclean'], wd=self.config.chill_dir) - util.shell('./configure', self.config.config_args, wd=self.config.chill_dir) - util.shell('make', [], wd=self.config.chill_dir) - - #util.shell('make', ['clean'], wd=self.config.chill_dir) - #util.shell('make', ['veryclean'], wd=self.config.chill_dir) - #util.shell('make', [depend_target] + [self.build_args], env=self.build_env, wd=self.config.chill_dir) - #util.shell('make', [target] + [self.build_args], env=self.build_env, wd=self.config.chill_dir) - return self.make_pass() - - def tearDown(self): - """ - Called after run, outside of the context of a test case. - If a binary directory is specified, rename and move the executable there, otherwise, just rename it. - """ - if self.test_result.passed(): - if self.config.bin_dir: - util.shell('mv', [os.path.join(self.config.chill_dir, self.config.buildname), os.path.join(self.config.bin_dir, self.config.name)]) - elif not self.config.buildname == self.config.name: - util.shell('mv', [os.path.join(self.config.chill_dir, self.config.buildname), os.path.join(self.config.chill_dir, self.config.name)]) - - -# - - # -# - Test case for running chill - # -# - - # -class RunChillTestCase(test.SequencialTestCase): - """ - Test case for running and testing chill. - """ - - default_options={ - 'compile-src':True, # Compile original source file - 'run-script':True, # Run chill script - 'compile-gensrc':True, # Compile generated source file - 'check-run-script-stdout':False, # Diff stdout from run_script() against an expected value (from a .stdout file) - 'coverage':False, # Record coverage - - 'fail-compile-src':False, # Expect compile_src to fail (TODO: not implemented) - 'fail-run-script':False, # Expect run_script to fail (TODO: not implemented) - } - - def __init__(self, config, chill_script, chill_src, wd=None, options={}, coverage_set=None): - """ - @param config Chill configuration object - @param chill_script The path to the chill script. - @param chill_src The path to the source file that the script uses. - @param wd The working directory. Where the script will be executed, compiled, and tested. - @param options Additional testing options. - @param coverage_set GcovSet object to record coverage - """ - if config.script_lang == None: - config.script_lang = ChillConfig.ext_to_script_lang(chill_script.split('.')[-1]) - - assert isinstance(config, ChillConfig) - - super(RunChillTestCase,self).__init__(config.name + ':' + os.path.basename(chill_script)) - - self.config = config - self.wd = wd if (wd != None) else os.getcwd() - - self.chill_src_path = os.path.abspath(chill_src) - self.chill_script_path = os.path.abspath(chill_script) - self.chill_bin = os.path.join(self.config.bin_dir, self.config.name) - self.chill_src = os.path.basename(self.chill_src_path) - self.chill_script = os.path.basename(self.chill_script_path) - self.chill_gensrc = self._get_gensrc(self.chill_src) - self.chill_gensrc_path = os.path.join(self.wd, self.chill_gensrc) - - self.compile_src_func = self.config.compile_src_func() - self.compile_gensrc_func = self.config.compile_gensrc_func() - self.build_src_func = self.config.build_src_func() - self.build_gensrc_func = self.config.build_gensrc_func() - - self._set_options(options, coverage_set) - - def _set_options(self, options, coverage_set=None): - self.options = dict(RunChillTestCase.default_options) - self.options.update(options) - - self.out = dict() - self.expected = dict() - - if self.options['compile-src']: - self.add_subtest('compile-src', self.compile_src) - if self.options['run-script']: - self.add_subtest('run-script', self.run_script) - if self.options['compile-gensrc']: - self.add_subtest('compile-generated-src', self.compile_gensrc) - self.add_subtest('check-run-script-validate', self.check_run_script_validate) - if self.options['check-run-script-stdout']: - self.add_subtest('check-run-script-stdout', self.check_run_script_stdout) - with open('.'.join(self.chill_script_path.split('.')[0:-1] + ['stdout']), 'r') as f: - self.expected['run_script.stdout'] = f.read() - self.coverage_set = coverage_set - - def _get_gensrc(self, src): - """ - The name of the generated source file. - """ - if not self.config.build_cuda: - return 'rose_' + src - else: - return 'rose_' + '.'.join(src.split('.')[0:-1]) + '.cu' - - def setUp(self): - """ - Called before any tests are performed. Moves source and script files into the working directory - and removes any gcov data files - """ - util.shell('cp', [self.chill_src_path, self.chill_src], wd=self.wd) - util.shell('cp', [self.chill_script_path, self.chill_script], wd=self.wd) - #TODO: check for chill binary - - def tearDown(self): - """ - Called when the test is complete - """ - util.shell('rm', ['-f', self.chill_src], wd=self.wd) - util.shell('rm', ['-f', self.chill_script], wd=self.wd) - util.shell('rm', ['-f', self.chill_gensrc], wd=self.wd) - if self.options['coverage'] and self.coverage_set is not None: - self.coverage_set.addcoverage(self.config.name, self.name) - - # - - # - # - Chill Tests - # - # - - # - - def compile_src(self, tc): - """ - Attempts to compile the source file before any transformation is performed. Fails if gcc fails. - """ - #self.out['compile_src.stdout'] = util.shell('gcc', ['-c', self.chill_src], wd=self.wd) - _, self.out['compile_src.stdout'] = self.compile_src_func(self.chill_src, util.mktemp(), wd=self.wd) - return tc.make_pass() - - def run_script(self, tc): - """ - Attempts to run the script file. Fails if chill exits with a non-zero result. - """ - # look for cudaize.lua for cuda-chill - if self.config.build_cuda and not os.path.exists(os.path.join(self.wd, 'cudaize.lua')): - return test.TestResult.make_error(test.FailedTestResult, tc, reason='cudaize.lua was missing from the working directory.') - self.out['run_script.stdout'] = util.shell(self.chill_bin, [self.chill_script], wd=self.wd) - return tc.make_pass() - - def compile_gensrc(self, tc): - """ - Attempts to compile the generated source file. Fails if gcc fails. - """ - #self.out['compile_gensrc.stdout'] = util.shell('gcc', ['-c', self.chill_gensrc], wd=self.wd) - _, self.out['compile_gensrc.stdout'] = self.compile_gensrc_func(self.chill_gensrc_path, util.mktemp(), wd=self.wd) - return tc.make_pass() - - def check_run_script_validate(self, tc): - """ - Generate test data and run both the original source and generated source against it. - Fail if any test procedure generates different output. - """ - for name, (is_valid, is_faster) in cpp_validate.run_from_src(self.chill_src, self.chill_gensrc, self.build_src_func, self.build_gensrc_func, wd=self.wd): - self.out['check_run_script_validate.{}'.format(name)] = (is_valid, is_faster) - if not is_valid: - return tc.make_fail('test procedure {} returned invalid results.'.format(name)) - return tc.make_pass() - - def check_run_script_stdout(self, tc): - """ - Diff stdout from run_script against an expected stdout - """ - isdiff, diff = util.isdiff(self.out['run_script.stdout'], self.expected['run_script.stdout']) - if isdiff: - return test.TestResult.make_fail(test.FailedTestResult, tc, reason='Diff:\n' + diff) - return tc.make_pass() - diff --git a/test-chill/testchill/cpp_validate.py b/test-chill/testchill/cpp_validate.py deleted file mode 100644 index 5f19a12..0000000 --- a/test-chill/testchill/cpp_validate.py +++ /dev/null @@ -1,165 +0,0 @@ -import collections -import os -import pickle -import re - -from . import util - -_script_parser = None -def _get_script_parser(): - """ - Retrieve the test code generator language parser. - """ - global _script_parser - if _script_parser is None: - with open('testchill/cpp_validate/parser.pickle','rb') as f: - _script_parser = pickle.load(f) - return _script_parser - -def _parse_testproc_python(txt, glbls=None): - """ - Parse text as a python testchill._cpp_validate_env.Procedure object" - @param txt Python code to be parsed. - @param glbls A python global dict. - """ - if glbls is None: - glbls = dict() - exec('import testchill._cpp_validate_env\nfrom testchill._cpp_validate_env import *', None, glbls) - return eval(txt, glbls) - -def _parse_testproc_script(txt, glbls=None): - """ - Parse text as test code generator language. - @param txt Code to be parsed. - @param glbls A python global dict. - """ - parser = _get_script_parser() - proc = list(parser.parse(util.textstream(txt)))[0] - if glbls is None: - from . import _cpp_validate_env - glbls = dict() - return _cpp_validate_env.addbindings(proc, glbls) - else: - return proc - -def _parse_testproc_iter(srcfile, wd=os.getcwd()): - """ - Parse all test procedures from a file. - @param srcfile File path to parse. - @param wd Working directory. - """ - default_attrs = {'lang':'script', 'define':'dict()'} - for txt, parsed_attrs in util.extract_tag('test', srcfile, wd): - attrs = collections.defaultdict(lambda: None) - attrs.update(default_attrs) - attrs.update(parsed_attrs) - if attrs['lang'] == 'python': - yield _parse_testproc_python(txt), attrs - if attrs['lang'] == 'script': - yield _parse_testproc_script(txt), attrs - -#def _compile_gpp(src, dest): -# """ -# Compile a signle C++ source file into an executable object. -# @param src Source file path. -# @param dest Object file path. -# """ -# util.shell('g++', ['-o', dest, src, '-lrt']) - -def _test_time(control_time, test_time): - """ - Determine if test ran faster than control. - @param control_time Time taken by control. - @param test_time Time taken by test. - """ - return control_time > test_time - -def _test_validate(control_dataout_path, test_dataout_path): - """ - Determine if control and test computed the same values. - @param control_dataout_path Path to the file writen by control. - @param test_dataout_path Path to the file writen by test. - """ - with open(control_dataout_path, 'rb') as controlfile: - with open(test_dataout_path, 'rb') as testfile: - return controlfile.read() == testfile.read() - -def _run_test_validate_time(control_obj_path, test_obj_path, datain_path): - control_dataout_path = util.mktemp() - test_dataout_path = util.mktemp() - control_time, = eval(util.shell(os.path.abspath(control_obj_path), [datain_path, control_dataout_path])) - test_time, = eval(util.shell(os.path.abspath(test_obj_path), [datain_path, test_dataout_path])) - return _test_validate(control_dataout_path, test_dataout_path), _test_time(control_time, test_time) - -#def _run_test_validate_time(control_obj_path, test_obj_path, datain_path, wd): - #control_obj_path = '.'.join(control_src_path.split('.')[:-1]) - #test_obj_path = '.'.join(test_src_path.split('.')[:-1]) - - - - #util.set_tempfile(control_obj_path) - #util.set_tempfile(test_obj_path) - #_compile_gpp(control_src_path, control_obj_path) - #_compile_gpp(test_src_path, test_obj_path) - - #test_validate, test_time = _run_test_validate_time(control_obj_path, test_obj_path, datain_path) - #return test_validate, test_time - -def _generate_initial_data(test_proc, srcfile, defines, wd=os.getcwd()): - filename = os.path.join(wd, os.path.basename(srcfile)) + '.data' - with open(filename, 'wb') as f: - for p_name, p_type, p_dims, p_data in test_proc.generatedata(['in', 'inout'], defines): - f.write(p_data) - for p_name, p_type, p_dims, p_data in test_proc.generatedata(['out'], defines): - f.write(p_data) - return filename - -def _format_insertion_dict(test_proc, src_path, defines): - with open(src_path, 'r') as src_file: - return { - 'defines' : '\n'.join(['#define {} {}'.format(k,v) for k,v in defines.items()]), - 'test-proc' : src_file.read(), - 'declarations' : '\n'.join(test_proc.generatedecls(defines)), - 'read-in' : '\n'.join(test_proc.generatereads(['in','inout'], 'datafile_initialize', defines)), - 'read-out' : '\n'.join(test_proc.generatereads(['out'], 'datafile_initialize', defines)), - 'run' : test_proc.getinvokestr(), - 'write-out' : '\n'.join(test_proc.generatewrites('datafile_out', defines)), - } - -def _write_generated_code(test_proc, src_path, defines, dest_filename, wd): - insertion_dict = _format_insertion_dict(test_proc, src_path, defines) - dest_file_path = os.path.join(wd, dest_filename) - with open('testchill/cpp_validate/src/validate.cpp', 'r') as template_file: - with open(dest_file_path, 'w') as destfile: - template_text = template_file.read() - desttext = template_text - for match in re.finditer(r'(?P<indent>[ \t]*)//# (?P<name>[^\s]+)', template_text): - destlines = insertion_dict[match.group('name')].splitlines() - indent = match.group('indent') - match_text = match.group() - repl_text = '\n'.join([indent + line for line in destlines]) - desttext = desttext.replace(match_text, repl_text) - destfile.write(desttext) - return dest_file_path - -def run_from_src(control_src, test_src, build_control_func, build_test_func, wd=os.getcwd()): - control_src_path = os.path.join(wd, control_src) - test_src_path = os.path.join(wd, test_src) - gen_control_obj_path = os.path.join(wd, 'control_obj') - gen_test_obj_path = os.path.join(wd, 'test_obj') - for test_proc, attrs in _parse_testproc_iter(control_src, wd): - defines = eval(attrs['define']) - datafile = _generate_initial_data(test_proc, control_src_path, defines, wd=wd) - gen_control_src = _write_generated_code(test_proc, control_src_path, defines, 'gen_control.cc', wd) - gen_test_src = _write_generated_code(test_proc, test_src_path, defines, 'gen_test.cc', wd) - gen_control_obj, _ = build_control_func(gen_control_src, gen_control_obj_path) - gen_test_obj, _ = build_test_func(gen_test_src, gen_test_obj_path) - util.set_tempfile(gen_control_obj) - util.set_tempfile(gen_test_obj) - yield attrs['name'], _run_test_validate_time(gen_control_obj, gen_test_obj, datafile) - -def parse_defines_iter(src, wd=os.getcwd()): - for txt, attrs in util.extract_tag('test', src, wd): - if 'define' in attrs.keys(): - yield eval(attrs['define']) - diff --git a/test-chill/testchill/cpp_validate/grammar.txt b/test-chill/testchill/cpp_validate/grammar.txt deleted file mode 100644 index fdb8c00..0000000 --- a/test-chill/testchill/cpp_validate/grammar.txt +++ /dev/null @@ -1,124 +0,0 @@ -terminals: - Identifier '[a-zA-Z_][a-zA-Z_0-9]*' - NumericLiteral '[0-9]+(\.[0-9]+)?' - Comment '\#([^\x0a])*' - WS '\s+' -ignore: WS, <NL>, Comment -rules: -<proc-unit> ::= - <with-stmt>:w => w - <proc>:p => p -<with-stmt> ::= - 'with' '{' <with-decl-list-opt>:decls '}' <proc-unit>:p => addbindings(p, dict(decls)) -<with-decl-list-opt> ::= - eps => [] - <with-decl-list>:l => l -<with-decl-list> ::= - <with-decl-list>:l ',' <with-decl>:decl => l + [decl] - <with-decl>:decl => [decl] -<with-decl> ::= - Identifier:name ':' <expr>:e => (name, (None, e)) - <c-type>:ctype Identifier:name ':' <expr>:e => (name, (ctype, e)) - -<proc> ::= - 'procedure' <c-type>:rtype Identifier:name '(' <param-list-opt>:plist ')' - => Procedure(name, rtype, plist) -<c-type> ::= - <c-type>:bt '*' => CppPointerType(bt) - <c-type>:bt <c-array-dim-list>:dims => CppArrayType(bt, dims) - 'void' => CppVoidType() - 'char' => CppPrimitiveType.get_from_cppname('char') - 'signed' 'char' => CppPrimitiveType.get_from_cppname('signed char') - 'unsigned' 'char' => CppPrimitiveType.get_from_cppname('unsigned char') - 'short' => CppPrimitiveType.get_from_cppname('short') - 'unsigned' 'short' => CppPrimitiveType.get_from_cppname('unsigned short') - 'int' => CppPrimitiveType.get_from_cppname('int') - 'unsigned' 'int' => CppPrimitiveType.get_from_cppname('unsigned int') - 'long' => CppPrimitiveType.get_from_cppname('long') - 'unsigned' 'long' => CppPrimitiveType.get_from_cppname('unsigned long') - 'long' 'long' => CppPrimitiveType.get_from_cppname('long long') - 'unsigned' 'long' 'long' => CppPrimitiveType.get_from_cppname('unsigned long long') - 'float' => CppPrimitiveType.get_from_cppname('float') - 'double' => CppPrimitiveType.get_from_cppname('double') -<c-array-dim-list> ::= - <c-array-dim-list>:dlist '[' <expr>:e ']' => dlist + [e] - <c-array-dim-list>:dlist '[' ']' => dlist + [None] - '[' ']' => [None] - '[' <expr>:e ']' => [e] -<param-list-opt> ::= - eps => [] - <param-list>:l => l -<param-list> ::= - <param-list>:l ',' <param>:p => l + [p] - <param>:p => [p] -<param> ::= - <direction>:d <c-type>:t Identifier:name '=' <expr>:e => Parameter(name, t, d, e) - <direction>:d <c-type>:t Identifier:name => Parameter(name, t, d, None) -<direction> ::= - 'in' => 'in' - 'out' => 'out' - 'in' 'out' => 'inout' - 'out' 'in' => 'inout' - eps => 'inout' - - -<expr> ::= - <add-expr>:e => e - 'lambda' <id-list-opt>:params ':' <expr>:e => LambdaExpr(params, e) - 'matrix' '(' <dim-list-expr>:d ',' <expr>:e ')' => MatrixGenerator(d, e) - 'matrix' <named-dim-list-expr>:dims <expr>:e => MatrixGenerator([d[1] for d in dims], LambdaExpr([d[0] for d in dims], e)) -<add-expr> ::= - <add-expr>:l '+' <mul-expr>:r => BinExpr(l, '+', r) - <add-expr>:l '-' <mul-expr>:r => BinExpr(l, '-', r) - <mul-expr>:e => e -<mul-expr> ::= - <mul-expr>:l '*' <prefix-expr>:r => BinExpr(l, '*', r) - <mul-expr>:l '/' <prefix-expr>:r => BinExpr(l, '/', r) - <prefix-expr>:e => e -<prefix-expr> ::= - '-' <prefix-expr>:e => UnaryExpr('-', e) - <postfix-expr>:e => e -<postfix-expr> ::= - <pow-expr>:e => e -<pow-expr> ::= - <term-expr>:l '**' <pow-expr>:r => BinExpr(l, '**', r) - <term-expr>:e => e -<term-expr> ::= - '(' <expr>:e ')' => e - '[' <expr-list-opt>:l ']' => l - Identifier:name => NameExpr(name) - NumericLiteral:num => ConstantExpr(num) - 'random' '(' <expr>:mn ',' <expr>:mx ')' => RandomExpr(mn, mx) - <term-expr>:f '(' <expr-list-opt>:l ')' => InvokeExpr(f, l) - <term-expr>:n '.' Identifier:attr => AttributeExpr(n, attr) -<expr-list-opt> ::= - eps => [] - <expr-list>:l => l -<expr-list> ::= - <expr-list>:l ',' <expr>:e => l + [e] - <expr>:e => [e] -<dim-list-expr> ::= - '[' <dim-expr-list>:l ']' => l -<dim-expr-list> ::= - <dim-expr-list>:l ',' <dim-expr>:e => l + [e] - <dim-expr>:e => [e] -<dim-expr> ::= - eps => None - '*' => None - <expr>:e => e -<id-list-opt> ::= - eps => [] - <id-list>:l => l -<id-list> ::= - <id-list>:l ',' Identifier:ident => l + [ident] - Identifier:ident => [ident] -<named-dim-list-expr> ::= - '[' <named-dim-expr-list>:l ']' => l -<named-dim-expr-list> ::= - <named-dim-expr-list>:l ',' <named-dim-expr>:e => l + [e] - <named-dim-expr>:e => [e] -<named-dim-expr> ::= - Identifier:name => (name, None) - Identifier:name ':' <expr>:e => (name, e) - - diff --git a/test-chill/testchill/cpp_validate/src/validate.cpp b/test-chill/testchill/cpp_validate/src/validate.cpp deleted file mode 100644 index f09009d..0000000 --- a/test-chill/testchill/cpp_validate/src/validate.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include <time.h> -#include <fstream> -#include <cstdio> - -//# defines -//# test-proc - -int main(int argc, char** argv) { - //# declarations - timespec start_time; - timespec end_time; - - std::ifstream datafile_initialize(argv[1]); - //# read-in - //# read-out - datafile_initialize.close(); - - clock_gettime(CLOCK_REALTIME, &start_time); - //# run - clock_gettime(CLOCK_REALTIME, &end_time); - - std::ofstream datafile_out(argv[2]); - //# write-out - datafile_out.close(); - - double time_diff = (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec - start_time.tv_nsec)/1000000000.0; - std::printf("(%f,)", time_diff); - return 0; -} diff --git a/test-chill/testchill/gcov.py b/test-chill/testchill/gcov.py deleted file mode 100644 index 668c00e..0000000 --- a/test-chill/testchill/gcov.py +++ /dev/null @@ -1,224 +0,0 @@ -from __future__ import print_function -import functools -import itertools -import os -import os.path -import sys - -from . import util - -class GcovFile(object): - def __init__(self, src_file_name, cov_file_path, lines, properties): - """ - @param src_file_name Name of the source file. - @param cov_file_path Full path to the coverage file. - @param lines List of GcovLine objects. - @param properties Properties from the coverage file. - """ - self.src_file_name = src_file_name - self.cov_file_path = cov_file_path - self.lines = lines - self.properties = properties - - @staticmethod - def parse_file(gcov, fname, process=None): - """ - Parse a file into a GcovFile object. - @param gcov Gcov object that tis file is a part of. - @param gname File name. - @param process Process name - """ - util.shell('gcov', [fname], wd=gcov.srcdir) - cov_file_path = os.path.join(gcov.srcdir, fname + '.gcov') - src_file_name = fname - if os.path.exists(cov_file_path): - with open(cov_file_path, 'r') as f: - lines, properties = GcovFile.parse_lines(f.readlines(), process) - return GcovFile(src_file_name, cov_file_path, lines, properties) - else: - return None - - @staticmethod - def parse_lines(str_lines, process): - """ - Parse a string from a coverage file into a list of GcovLine objects. - @param str_lines Full text of a coverage file. - @param process Name of the process that executed the code. - """ - properties = dict() - lines = [] - for line in str_lines: - if line[-1] == '\n': - line = line[0:-1] - pline = line.split(':') - pline = list(map(str.strip, pline[0:2])) + pline[2:] - if pline[1] == '0': - properties[pline[2]] = pline[3].strip() - elif pline[0][0] == '-': - lines.append(GcovLine(int(pline[1]), dict(), ':'.join(pline[2:]))) - elif pline[0][0] == '#': - lines.append(GcovLine(int(pline[1]), {process : 0}, ':'.join(pline[2:]))) - else: - lines.append(GcovLine(int(pline[1]), {process : int(pline[0])}, ':'.join(pline[2:]))) - return lines, properties - - @staticmethod - def union(left, right): - """ - Merge two different coverages of the same file into a single coverage object. - """ - return left | right - - def __or__(self, right): - """ - Merge two different coverages of the same file into a single coverage object. - """ - new_file = self.clone() - new_file.merge(right) - return new_file - - def __ior__(self, right): - """ - Merge two different coverages of the same file into a single coverage object. - """ - self.merge(right) - return self - - def merge(self, other): - """ - Merge another coeverage into self. - """ - assert self.src_file_name == other.src_file_name - GcovLine.merge_lines(self.lines, other.lines) - self.properties.update(other.properties) - - def clone(self): - """ - Create a shallow clone. - """ - return GcovFile(self.src_file_name, self.cov_file_path, list(self.lines), dict(self.properties)) - - -class GcovLine(object): - def __init__(self, lineno, count_by_process, code): - """ - @param lineno Line number. - @param count_by_prcess A dictionary of execution counts by name of the process that executed them. - @param code Source code from this line. - """ - self.lineno = lineno - self.count_by_process = count_by_process - self.code = code - - @staticmethod - def merge_lines(lines, other_lines): - """ - Merge lines from other_line into lines. - """ - for line, other_line in zip(lines, other_lines): - assert line.lineno == other_line.lineno - assert line.code == other_line.code - line.count_by_process.update(other_line.count_by_process) - - def count(self): - """ - The total number of times this line was executed. - """ - runable_list = [l for l in self.count_by_process.values() if l is not None] - if len(runable_list) == 0: - return None - else: - return sum(runable_list) - - def __repr__(self): - return str((self.lineno, self.count_by_process, self.code)) - - -class Gcov(object): - def __init__(self, srcdir): - self.srcdir = srcdir - self.files = dict() - - @staticmethod - def parse(srcdir, process=None): - gcov = Gcov(srcdir) - gcov._append(filter(lambda f: f is not None, map(functools.partial(GcovFile.parse_file, gcov, process=process), - util.filterext(['cc','c','cpp','h','hh'], os.listdir(srcdir))))) - return gcov - - def _append(self, files): - for f in files: - if f.src_file_name in self.files: - self.files[f.src_file_name].merge(f) - else: - self.files[f.src_file_name] = f - - def __or__(self, right): - new_cov = self.clone() - new_cov.merge(right) - return new_cov - - def __ior__(self, right): - self.merge(right) - return self - - @staticmethod - def union(left, right): - return left | right - - def merge(self, other): - self._append(other.files.values()) - - def clone(self): - new_cov = Gcov(self.srcdir) - new_cov._append(iter(f.clone() for f in self.files.values())) - return new_cov - - -class GcovSet(object): - def __init__(self): - self.coverage_by_program = dict() - - def addprogram(self, prog_name, src_dir): - self.coverage_by_program[prog_name] = Gcov(src_dir) - - def addcoverage(self, prog_name, process_name): - cov = self.coverage_by_program[prog_name] - cov.merge(Gcov.parse(cov.srcdir, process_name)) - - #def unexecuted_lines(self): - # covlist = sorted(self.coverage_by_program.values(), key=lambda c: c.srcdir) - # for src, grp in itertools.groupby(covlist, lambda c: c.srcdir): - # files = functools.reduce(lambda a, c: a | c, grp).files.values() - # file_lines = iter((f.src_file_name, iter(l for l in f.lines if l.count() == 0)) for f in files) - # yield src, file_lines - # - #def pretty_print(self, outfile=sys.stdout, width=60, stats=['unexecuted', 'unexecuted.bysrc']): - # print('='*width, file=outfile) - # print(' CODE COVERAGE', file=outfile) - # - # if 'unexecuted' in stats: - # print('='*width, file=outfile) - # print(' unexecuted lines', file=outfile) - # if 'unexecuted.bysrc' in stats: - # for src, file_lines in self.unexecuted_lines(): - # print((src + ':'), file=outfile) - # print('-'*width, file=outfile) - # for src_file_name, lines in file_lines: - # print(' ' + src_file_name + ':', file=outfile) - # for line in lines: - # print("{}:{}".format(str(line.lineno).rjust(5), line.code), file=outfile) - # #print('='*width, file=outfile) - # #print(prog, file=outfile) - # #print('-'*width, file=outfile) - - def _get_coverage_by_file(self): - return functools.reduce(lambda a,b: a|b, self.coverage_by_program.values()).files - - def _get_filenames(self): - return self.coverage_by_file.keys() - - coverage_by_file = property(_get_coverage_by_file) - filenames = property(_get_filenames) - - diff --git a/test-chill/testchill/omega.py b/test-chill/testchill/omega.py deleted file mode 100644 index 962333a..0000000 --- a/test-chill/testchill/omega.py +++ /dev/null @@ -1,29 +0,0 @@ -from . import test -from . import util - - - -class BuildOmegaTestCase(test.TestCase): - def __init__(self, omega_dir, version='dev'): - super(BuildOmegaTestCase, self).__init__(BuildOmegaTestCase.getname(version)) - self.omega_dir = omega_dir - self.version = version - - @staticmethod - def getname(version): - if version == 'release': - return 'omega-release' - else: - return 'omega' - - def setUp(self): - util.shell('make clean', wd=self.omega_dir) - - def tearDown(self): - pass - - def run(self): - util.shell('make depend', wd=self.omega_dir) - util.shell('make', wd=self.omega_dir) - - diff --git a/test-chill/testchill/test.py b/test-chill/testchill/test.py deleted file mode 100644 index c38b98a..0000000 --- a/test-chill/testchill/test.py +++ /dev/null @@ -1,381 +0,0 @@ -from __future__ import print_function -#TODO: test dependencies -#TODO: expected failures -import itertools -import io -import logging -import pprint -import sys -import traceback - -from . import util - - -class TestResult(object): - """ - The base class for all test results. - """ - _pass = 'pass' - _error = 'error' - _fail = 'fail' - _skipped = 'skipped' - - def __init__(self, testcase, status): - self.testcase_name = testcase.name - self.status = status - testcase.setresult(self) - - @staticmethod - def make_pass(result_type, testcase, *args, **kwargs): - """ - Create and return a passing test result of type result_type. - @param result_type A class that extends TestResult - @param testcase The test case that generated the result - @param *args Additional positional arguments to be passed to result_type.__init__ - @param *kwargs Keyword arguments to be passed to result_type.__init__ - """ - return result_type(testcase, TestResult._pass, *args, **kwargs) - - @staticmethod - def make_error(result_type, testcase, *args, **kwargs): - """ - Create and return a errored test result of type result_type. - @param result_type A class that extends TestResult - @param testcase The test case that generated the result - @param *args Additional positional arguments to be passed to result_type.__init__ - @param *kwargs Keyword arguments to be passed to result_type.__init__ - """ - return result_type(testcase, TestResult._error, *args, **kwargs) - - @staticmethod - def make_fail(result_type, testcase, *args, **kwargs): - """ - Create and return a failed test result of type result_type. - @param result_type A class that extends TestResult - @param testcase The test case that generated the result - @param *args Additional positional arguments to be passed to result_type.__init__ - @param *kwargs Keyword arguments to be passed to result_type.__init__ - """ - return result_type(testcase, TestResult._fail, *args, **kwargs) - - @staticmethod - def make_skipped(result_type, testcase, *args, **kwargs): - """ - Create and return a skipped test result of type result_type. - @param result_type A class that extends TestResult - @param testcase The test case that generated the result - @param *args Additional positional arguments to be passed to result_type.__init__ - @param *kwargs Keyword arguments to be passed to result_type.__init__ - """ - return result_type(testcase, TestResult._skipped, *args, **kwargs) - - def passed(self): - """ Return true iff the testcase passed. """ - return self.status == TestResult._pass - - def errored(self): - """ Return true iff the testcase passed. """ - return self.status == TestResult._error - - def failed(self): - """ Return true iff the testcase passed. """ - return self.status == TestResult._fail - - def skipped(self): - """ Return true iff the testcase was skipped """ - return self.status == TestResult._skipped - - def pprint_dict(self): - """ - Return a dict that is ideal for passing to pprint. - """ - return {'testcase_name': self.testcase_name, 'status':self.status} - - def pretty_print(self, width=60, outfile=sys.stdout): - """ - Print result to a file in a human readable way. - """ - print('='*width, end='\n', file=outfile) - print("{}: {}".format(self.status, self.testcase_name), end='\n', file=outfile) - print('-'*width, end='\n', file=outfile) - print(self.pretty_message(), end='\n', file=outfile) - print('-'*width, end='\n', file=outfile) - - def pretty_message(self): - """ Return a message to be printed by pretty_print. Returns an empyt string if not overriden. """ - return '' - - - -class FailedTestResult(TestResult): - """ - A basic implementation of TestResult for failed tests. - """ - def __init__(self, testcase, status=TestResult._fail, reason=None): - super(FailedTestResult, self).__init__(testcase, status) - self.reason = reason - - def pprint_dict(self): - """ - Return a dict that is ideal for passing to pprint. - """ - ppdict = super(FailedTestResult, self).pprint_dict() - ppdict['reason'] = self.reason - return ppdict - - def pretty_message(self): - return self.reason - - -class CompoundTestResult(TestResult): - """ - A TestResult returned by running a sequencial test case - """ - def __init__(self, testcase, results): - super(CompoundTestResult, self).__init__(testcase, None) - self.sub_results = results - status_list = [r.status for r in results] - if TestResult._fail in status_list: - self.status = TestResult._fail - elif TestResult._error in status_list: - self.status = TestResult._error - elif TestResult._pass in status_list: - self.status = TestResult._pass - else: - self.status = TestResult._skipped - - def pprint_dict(self): - """ - Returns a dict that is ideal for passing to pprint. - """ - ppdict = super(CompoundTestResult, self).pprint_dict() - ppdict['sub_results'] = list(s.pprint_dict() for s in self.sub_results) - return ppdict - - def pretty_message(self): - return '\n'.join( - "{}: {}{}".format( - st.status, - st.testcase_name, - '\n' + st.pretty_message() if st.status in [TestResult._fail, TestResult._error] else '') - for st in self.sub_results) - - -class SubTestResult(TestResult): - """ - A TestResult for a subtest in a sequencial test case. - """ - def __init__(self, subtest_name, inner_result): - """ - @param subtest_name The name of the subtest. - @param inner_result The result returned from running the subtest. - """ - super(SubTestResult, self).__init__(inner_result.testcase, inner_result.status) - self.inner_result = inner_result - - def pprint_dict(self): - """ - Return a dict that is ideal for passing to pprint. - """ - ppdict = super(CompoundTestResult, self).pprint_dict() - ppdict['inner_result'] = self.inner_result.pprint_dict() - return ppdict - - -class UnhandledExceptionTestResult(TestResult): - """ - A TestResult returned for exceptions that the test case failed to handle. - """ - def __init__(self, testcase, status, exc_type, exc_value, exc_traceback): - super(UnhandledExceptionTestResult, self).__init__(testcase, status) - self.exception_type = exc_type - self.exception_value = exc_value - if not exc_traceback is None: - sio = util.StringIO() - traceback.print_exception(self.exception_type, self.exception_value, exc_traceback, file=sio) - self.exception_message = sio.getvalue() - else: - self.exception_message = "{}: {}".format(str(exc_type), str(exc_value)) - - def pprint_dict(self): - """ - Return a dict that is ideal for passing to pprint. - """ - ppdict = super(UnhandledExceptionTestResult, self).pprint_dict() - ppdict['exception_type'] = self.exception_type - ppdict['exception_value'] = self.exception_value - ppdict['exception_message'] = self.exception_message - return ppdict - - def pretty_message(self): - return self.exception_message - - -class TestCase(object): - """ - Base class for all test cases - """ - def __init__(self, name=None): - """ - @param name A unique test case name. - """ - self.name = name - - def setUp(self): - """ - Called imediately before a testcase is executed. - """ - pass - - def run(self): - """ - Run the test case, and return its result. - """ - raise NotImplementedError - - def tearDown(self): - """ - Called imediately after a testcase is executed. - """ - pass - - def catch(self, exc): - """ - Called when run raises an exception. If the test case - knows how to handle it, it should return it's own result or None. - Otherwise, return the original exception. - """ - return exc - - def setresult(self, test_result): - """ - Called after a test issues a result and before tearDown is called. - """ - self.test_result = test_result - - def make_pass(self, result_type=TestResult, *args, **kwargs): - """ - Make a passed result for this testcase. - """ - return TestResult.make_pass(result_type, self, *args, **kwargs) - - def make_fail(self, result_type=FailedTestResult, *args, **kwargs): - """ - Make a failed result for this testcase. - """ - return TestResult.make_fail(result_type, self, *args, **kwargs) - - -class SequencialTestCase(TestCase): - """ - A test case that executes a sequence of subtests until - one fails. - """ - def __init__(self, name): - super(SequencialTestCase, self).__init__(name) - self.tests = [] - - def add_subtest(self, subtest_name, subtest_func): - """ - Add a subtest. - """ - self.tests.append((subtest_name, subtest_func)) - - def run(self): - return CompoundTestResult(self, list(self._runall())) - - def _runall(self): - return _rungen([SubTestCase(name, func) for name, func in self.tests], failfast=True) - - -class SubTestCase(TestCase): - """ - A subtest of a sequncial test. - """ - def __init__(self, name, func): - super(SubTestCase, self).__init__(name) - self.run = lambda: func(self) - - -def run(tclist, failfast=False): - """ - Run all test cases in tclist and return a list of thier results. - """ - return list(_rungen(tclist, failfast)) - -def _rungen(tclist, failfast=False): - """ - A generator for running tests internally. - """ - for tc in tclist: - result = None - tc.setUp() - try: - result = _result(tc.run(), tc) - except Exception as ex: - result = _result(tc.catch(ex), tc) - tc.tearDown() - yield result - if failfast and (result.failed() or result.errored()): - break - -def _result(res, tc): - """ - Convert res to a TestResult object. - If res is a TestResult object, give it back. - If res is an Exception, return an UnandledExceptionTestResult. - If res is something else, discard it and return a passed TestResult. - """ - if isinstance(res, TestResult): - return res - elif isinstance(res, Exception): - logging.info('uncaught exception: {}'.format(str(res))) - return TestResult.make_error(UnhandledExceptionTestResult, tc, *(sys.exc_info())) - else: - return TestResult.make_pass(TestResult, tc) - -def pprint_results(result_iter, outfile=sys.stdout): - """ - Print pprint version of test results to a file-like object. - @param result_iter An iterator of results to print. - @param outfile An opened file-like object to print to (defaults to stdout). - """ - status_func = lambda r: r.status - result_iter = sorted(result_iter, key=status_func) - status_dict = dict(iter((k, list(map(lambda tc: tc.pprint_dict(), g))) for k, g in itertools.groupby(result_iter, status_func))) - pprint.pprint(status_dict, stream=outfile) - -def pretty_print_results( - result_iter, - count_by_status=True, exclude_passed=True, exclude_skipped=True, exclude_failed=False, - exclude_errored=False, sort_by_status=True, width=60, outfile=sys.stdout): - """ - Print iterator of TestResults in a human readable format to a file-like object. - @param result_iter An iterator of TestResult objects to print. - @param count_by_status Print the number of tests for each status (defaults to True). - @param exclude_passed Exclude passed test results from printing (defaults to True). - @param exclude_skipped Exclude skipped test results from printing (defaults to True). - @param exclude_failed Exclude failed test results from printing (defaults to False). - @param exclude_errored Exclude errored test results from printing (defaults to False). - @param sort_by_status Print test results in order of status: passed, errored, failed, then skipped (defaults to True). - @param width Printing width (defaults to 60). - @param outfile A file-like object to print to (defaults to stdout). - """ - result_list = list(result_iter) - status_func = lambda r: r.status - if sort_by_status: - #TODO: printing order - result_iter = sorted(result_iter, key=status_func) - - if count_by_status: - print('Passed: {}'.format(len([tr for tr in result_list if tr.passed()])), file=outfile) - print('Errors: {}'.format(len([tr for tr in result_list if tr.errored()])), file=outfile) - print('Failed: {}'.format(len([tr for tr in result_list if tr.failed()])), file=outfile) - print('Skipped: {}'.format(len([tr for tr in result_list if tr.skipped()])), file=outfile) - #TODO: something that doesn't expose TestResult._* - print_status = set(itertools.compress([TestResult._pass, TestResult._error, TestResult._fail, TestResult._skipped], - map(lambda n: not n, [exclude_passed, exclude_errored, exclude_failed, exclude_skipped]))) - for tr in (r for r in result_list if r.status in print_status): - tr.pretty_print(width=width, outfile=outfile) - - diff --git a/test-chill/testchill/util.py b/test-chill/testchill/util.py deleted file mode 100644 index 266a94d..0000000 --- a/test-chill/testchill/util.py +++ /dev/null @@ -1,185 +0,0 @@ -import difflib -import functools -import itertools -import logging -import os -import re -import sysconfig -import subprocess -import tempfile - - - -logging.basicConfig(filename='testchill.log', level=logging.DEBUG, filemode='w') -#logging.basicConfig(level=logging.INFO) - -python_version = sysconfig.get_python_version() -python_version_major = int(sysconfig.get_python_version().split('.')[0]) -python_version_minor = int(sysconfig.get_python_version().split('.')[1]) - -if python_version_major == 2: - from StringIO import StringIO -else: - from io import StringIO - -_temp_dirs = [] -_temp_files = [] - -### Errors ### -### Shell Util ### - -def shell(cmd, args=[], stdout=None, stderr=None, env={}, wd=os.getcwd()): - """ - Execute a shell command. - @params cmd The command name - @params args A list of command line arguments (defaults to []) - @params stdout A file like object or file number that reads input written to stdout. - stdout will be returned as a string if this is None or not given. - @params stderr A file like object or file number that reads input written to stderr. - @params env A dict of environment variables. Before the command is executed, these will be exported - @params wd The working directory. Before the command is executed, the working directory will be changed to wd. (wd defaults to the current working directory) - """ - fullcmd = ' '.join(['export {}={};'.format(k,str(v)) for k,v in env.items()] + ['cd {};'.format(wd)] + [cmd] + args) - logging.info('shell: '+fullcmd) - if stdout == None: - outp = subprocess.check_output(fullcmd, stderr=stderr, shell=True) - if python_version_major == 2: - return outp - elif python_version_major == 3: - return outp.decode() - else: - subprocess.check_call(fullcmd, stdout=stdout, stderr=stderr, shell=True) - -def mkdir_p(directory, temp=False, **kwargs): - """ - Make directory (equivelent to shell('mkdir', ['-p', directory])) - """ - if not os.path.exists(directory): - if temp and (directory not in _temp_dirs): - _temp_dirs.append(directory) - shell('mkdir', ['-p', directory], **kwargs) - -def set_tempfile(filename): - """ - Add a file to a list of temp files - @param filename The full path to a temparary file. - """ - _temp_files.append(filename) - -def withtmp(wtfunc, rdfunc): - """ - Perform some operation using a temporary file. - @param wtfunc A function that writes to the temparary file - @param rdfybc A function that reads from the temparary file - """ - with tempfile.TemporaryFile() as f: - wtfunc(f) - f.seek(0) - return rdfunc(f) - -def rmtemp(): - """ - Clean temp files and directories - """ - for temp_file in list(_temp_files): - if os.path.exists(temp_file): - shell('rm', [temp_file]) - _temp_files.remove(temp_file) - - for temp_dir in list(_temp_dirs): - if os.path.exists(temp_dir): - shell('rm', ['-rf', temp_dir]) - _temp_dirs.remove(temp_dir) - -def mktemp(mode=None): - """ - Create a temparary file. Returns a two-tuple with an open file object and the filename. - """ - fd, name = tempfile.mkstemp() - _temp_files.append(name) - if mode is None: - os.close(fd) - return name - else: - return os.fdopen(fd, mode), name - - -### Misc Util ### - -def copy(obj, exclude=[]): - """ - Make a shallow copy of a python object with __dict__, excluding any attribute in exclude - @param obj The object to copy - @param exclude A list of attributes to ignore - """ - nobj = type(obj)() - for k, v in vars(obj).items(): - if k in exclude: continue - setattr(nobj, k, v) - return nobj - -def applyenv(line): - """ - Apply bash style environment variables to a string - @param line The input string - """ - return re.sub(r'\$([a-zA-Z_][a-zA-Z_0-9]*)\b',lambda m: str(os.getenv(m.group(1), '')), line) - -def callonce(func): - """ - Assert that a function is only ever called once. - @param func Function to only be run once. - """ - pred_name = '__' + func.__module__.replace('.','__') + '_' + func.__name__ + '_called' - globals()[pred_name] = False - @functools.wraps(func) - def wrapper(*args, **kwargs): - if not globals()[pred_name]: - globals()[pred_name] = True - return func(*args, **kwargs) - else: - raise Exception('{} was invoked multiple times.'.format(func.__name___)) - return wrapper - -def isdiff(strone, strtwo): - """ - Diff two strings. Returns a two element tuple. The first is True if the the two files are different, and the - next is a textual representation of the diff. - @param strone First string. - @param strtwo Second string. - """ - diff = list(difflib.ndiff(strone.splitlines(), strtwo.splitlines())) - return len(list(line for line in diff if line[0] in ['-','+'])) != 0, '\n'.join(diff) - -def filterext(ext_list, filenames): - """ - Filter file names by extension. - @param ext_list A list of extensions. - @param filenames An iterable object of file names. - """ - return iter(s for s in filenames if any(s.strip().endswith(e) for e in ext_list)) - -def extract_tag(tagname, filename, wd=os.getcwd()): - """ - Extract commented out text in each html tag '<tagname>'. Returns a list of tuples for each tag. - Each tuple has two elements, the first is the text found in the tag, the second contains a dict - of attributes given in the tag. - @param tagname The name of the tag to search for. - @param filename A filename to search for comments in. - @param wd The working directory. - """ - from . import _extract - return _extract.extract_tag(tagname, filename, wd) - -def textstream(txt): - """ - Creates a stream from text. Intended to hide version differences between 2 and 3. - @param txt A string to use as the default data in a stream. - """ - if python_version_major == 2: - import StringIO - return StringIO.StringIO(txt) - elif python_version_major == 3: - import io - return io.StringIO(txt) - |