summaryrefslogtreecommitdiff
path: root/test-chill/testchill
diff options
context:
space:
mode:
Diffstat (limited to 'test-chill/testchill')
-rw-r--r--test-chill/testchill/__init__.py0
-rw-r--r--test-chill/testchill/__main__.py368
-rw-r--r--test-chill/testchill/_cpp_validate_env.py654
-rw-r--r--test-chill/testchill/_extract.py98
-rw-r--r--test-chill/testchill/chill.py326
-rw-r--r--test-chill/testchill/cpp_validate.py165
-rw-r--r--test-chill/testchill/cpp_validate/grammar.txt124
-rw-r--r--test-chill/testchill/cpp_validate/src/validate.cpp29
-rw-r--r--test-chill/testchill/gcov.py224
-rw-r--r--test-chill/testchill/omega.py29
-rw-r--r--test-chill/testchill/test.py381
-rw-r--r--test-chill/testchill/util.py185
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)
-