From: <sv...@ww...> - 2007-07-24 08:39:04
|
Author: mkrose Date: 2007-07-24 01:38:00 -0700 (Tue, 24 Jul 2007) New Revision: 2143 Modified: trunk/csp/tools/build/__init__.py trunk/csp/tools/build/registry.py trunk/csp/tools/build/rules.py trunk/csp/tools/build/util.py Log: Add better support for defining and running unittests from scons. Instead of build.SharedLibrary, test modules should be defined using build.Test. 'scons runtests' still works, but more selective test execution will be possible once the monolithic test modules are broken into smaller pieces. The exact scons syntax and test layout remains tbd, but something along the lines of 'scons csplib/util.runtests' will allow all of the csplib utility tests to be built and executed. Browse at: https://www.zerobar.net/viewcvs/viewcvs.cgi?view=rev&rev=2143 Modified: trunk/csp/tools/build/__init__.py =================================================================== --- trunk/csp/tools/build/__init__.py 2007-07-24 08:27:44 UTC (rev 2142) +++ trunk/csp/tools/build/__init__.py 2007-07-24 08:38:00 UTC (rev 2143) @@ -78,7 +78,7 @@ from csp.tools.build.setup import Environment from csp.tools.build.rules import \ - SourceGroup, Program, Generate, SharedLibrary, Command + SourceGroup, Program, Generate, SharedLibrary, Command, Test from csp.tools.build.autoconf import \ CheckSConsVersion, CheckPythonVersion, GetPythonInclude, GetPythonLibrary, GetGCCVersion Modified: trunk/csp/tools/build/registry.py =================================================================== --- trunk/csp/tools/build/registry.py 2007-07-24 08:27:44 UTC (rev 2142) +++ trunk/csp/tools/build/registry.py 2007-07-24 08:38:00 UTC (rev 2143) @@ -28,6 +28,7 @@ self._sources = {} self._libraries = {} self._tests = [] + self._dir_tests = {} def AddLibrary(self, name, lib): self._libraries[name] = lib @@ -92,27 +93,50 @@ config[name] = dict(lib._settings) autoconf.SaveConfig(env, config) - def _RunTests(self): - if not self._tests: return + def _SetupTests(self): os.environ.setdefault('CSPLOG_FILE', os.path.join(scons.File('#/.testlog').abspath)) try: import csp.csplib except ImportError: print 'ERROR: unnable to import csp.csplib' return - for test in self._tests: - csp.csplib.TestRegistry.loadTestModule(test[0].abspath) - csp.csplib.TestRegistry.runAll() + return csp.csplib.TestRegistry + def _RunTests(self, *args, **kw): + tests = kw['source'] + if not tests: return + tester = self._SetupTests() + for test in tests: + tester.loadTestModule(test.abspath) + tester.runAll() + + def _RunOneTest(self, *args, **kw): + tester = self._SetupTests() + modules = kw['source'] + for module in modules: + tester.loadTestModule(module.abspath) + tester.runAll() + def Build(self, env): self.Configure(env) for target in self._targets.values(): object = target.build() if target.isTest(): self._tests.append(object) - def runtests(*args, **kw): - self._RunTests() - env.Command('runtests', 'tests', runtests) + if target._path not in self._dir_tests: + self._dir_tests[target._path] = [] + self._dir_tests[target._path].append(object) + run_alias = os.path.join(target._path, target._name) + '.run' + env.Command(run_alias, object, util.SilentAction(self._RunOneTest)) + env.Command('runtests', self._tests, util.SilentAction(self._RunTests)) + for path, targets in self._dir_tests.items(): + env.Command(path + '.runtests', targets, util.SilentAction(self._RunTests)) + # sample aliases for running tests: + # $ scons runtests + # $ scons cspsim.runtests + # $ scons csplib.runtests + # $ scons cspsim/test_PhysicsModel.run + # $ scons csplib/data/test_Object.run BuildRegistry = _BuildRegistry() Modified: trunk/csp/tools/build/rules.py =================================================================== --- trunk/csp/tools/build/rules.py 2007-07-24 08:27:44 UTC (rev 2142) +++ trunk/csp/tools/build/rules.py 2007-07-24 08:38:00 UTC (rev 2143) @@ -102,7 +102,7 @@ class Target: - def __init__(self, env, name, sources=[], aliases=[], deps=[], always_build=0, softlink=0, doxygen=None, **kw): + def __init__(self, env, name, sources=[], aliases=[], deps=[], always_build=0, softlink=0, doxygen=None, is_test=0, **kw): self._env = env.Copy() self._name = name self._sources = [s for s in sources if s.startswith('@')] @@ -110,10 +110,15 @@ if pure or deps: SourceGroup(env, name, sources=pure, deps=deps) self._sources.append('@' + name) + self._path = env.Dir('.').srcnode().path self._target = os.path.join(env.Dir('.').path, name) # a bit ugly - if isinstance(aliases, str): aliases = [aliases] + if isinstance(aliases, str): + aliases = [aliases] + else: + aliases = aliases[:] + if is_test: aliases.append('tests') self._aliases = aliases - self._is_test = 'tests' in aliases + self._is_test = is_test or ('tests' in aliases) # the latter is for backward compatibility self._always_build = always_build self._softlink = softlink self._doxygen = None @@ -275,6 +280,12 @@ settings.merge(XRPATH=[os.path.abspath(target_dir)], LIBPATH=[target_dir], LIBS=[os.path.basename(self._target)]) +class Test(SharedLibrary): + def __init__(self, env, **kw): + kw['is_test'] = 1 + SharedLibrary.__init__(self, env, **kw) + + class Command(Target): def __init__(self, env, function, **kw): name = getattr(function, '__name__', None) Modified: trunk/csp/tools/build/util.py =================================================================== --- trunk/csp/tools/build/util.py 2007-07-24 08:27:44 UTC (rev 2142) +++ trunk/csp/tools/build/util.py 2007-07-24 08:38:00 UTC (rev 2143) @@ -59,6 +59,11 @@ return CommandAction(cmd, strfunction=s) +def SilentAction(callback): + def noprint(*args, **kw): pass + return Action(callback, noprint) + + def Extension(fn): return os.path.splitext(fn)[1] |