From 915f49ae9255372267aabe06e8c28c1fab8e43a5 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 15 Apr 2011 10:45:11 -0700 Subject: [PATCH] unittest: Make unit tests capable of using swig and python, convert stattest --- src/SConscript | 43 ++++++++----- src/unittest/SConscript | 6 +- src/unittest/stattest.cc | 116 ++++++++++------------------------- src/unittest/stattest.i | 36 +++++++++++ src/unittest/stattestmain.py | 19 ++++++ 5 files changed, 121 insertions(+), 99 deletions(-) create mode 100644 src/unittest/stattest.i create mode 100644 src/unittest/stattestmain.py diff --git a/src/SConscript b/src/SConscript index 52de673dc..7982eaeb4 100755 --- a/src/SConscript +++ b/src/SConscript @@ -233,15 +233,26 @@ class SwigSource(SourceFile): self.cc_source = Source(cc_file, swig=True, parent=self) self.py_source = PySource(package, py_file, parent=self) -unit_tests = [] -def UnitTest(target, sources): - '''Create a unit test, specify the target name and a source or - list of sources''' - if not isinstance(sources, (list, tuple)): - sources = [ sources ] +class UnitTest(object): + '''Create a UnitTest''' - sources = [ Source(src, skip_lib=True) for src in sources ] - unit_tests.append((target, sources)) + all = [] + def __init__(self, target, *sources): + '''Specify the target name and any sources. Sources that are + not SourceFiles are evalued with Source(). All files are + guarded with a guard of the same name as the UnitTest + target.''' + + srcs = [] + for src in sources: + if not isinstance(src, SourceFile): + src = Source(src, skip_lib=True) + src.guards[target] = True + srcs.append(src) + + self.sources = srcs + self.target = target + UnitTest.all.append(self) # Children should have access Export('Source') @@ -673,10 +684,11 @@ for swig in SwigSource.all: env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode, MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' '-o ${TARGETS[0]} $SOURCES', Transform("SWIG"))) - init_file = 'python/swig/init_%s.cc' % swig.module + cc_file = str(swig.tnode) + init_file = '%s/init_%s.cc' % (dirname(cc_file), basename(cc_file)) env.Command(init_file, Value(swig.module), MakeAction(makeEmbeddedSwigInit, Transform("EMBED SW"))) - Source(init_file) + Source(init_file, **swig.guards) # # Handle debug flags @@ -904,13 +916,16 @@ def makeEnv(label, objsfx, strip = False, **kwargs): static_lib = new_env.StaticLibrary(libname, static_objs) shared_lib = new_env.SharedLibrary(libname, shared_objs) - for target, sources in unit_tests: - objs = [ make_obj(s, static=True) for s in sources ] - new_env.Program("unittest/%s.%s" % (target, label), objs + static_objs) - # Now link a stub with main() and the static library. main_objs = [ make_obj(s, True) for s in Source.get(main=True) ] + for test in UnitTest.all: + flags = { test.target : True } + test_sources = Source.get(**flags) + test_objs = [ make_obj(s, static=True) for s in test_sources ] + testname = "unittest/%s.%s" % (test.target, label) + new_env.Program(testname, main_objs + test_objs + static_objs) + progname = exename if strip: progname += '.unstripped' diff --git a/src/unittest/SConscript b/src/unittest/SConscript index 09286dac3..606bffd05 100644 --- a/src/unittest/SConscript +++ b/src/unittest/SConscript @@ -47,8 +47,12 @@ UnitTest('rangetest', 'rangetest.cc') UnitTest('rangemaptest', 'rangemaptest.cc') UnitTest('rangemultimaptest', 'rangemultimaptest.cc') UnitTest('refcnttest', 'refcnttest.cc') -UnitTest('stattest', 'stattest.cc') UnitTest('strnumtest', 'strnumtest.cc') + +stattest_py = PySource('m5', 'stattestmain.py', skip_lib=True) +stattest_swig = SwigSource('m5.internal', 'stattest.i', skip_lib=True) +UnitTest('stattest', 'stattest.cc', stattest_py, stattest_swig) + UnitTest('symtest', 'symtest.cc') UnitTest('tokentest', 'tokentest.cc') UnitTest('tracetest', 'tracetest.cc') diff --git a/src/unittest/stattest.cc b/src/unittest/stattest.cc index e7654ae5b..c5e39888d 100644 --- a/src/unittest/stattest.cc +++ b/src/unittest/stattest.cc @@ -32,8 +32,6 @@ #include #include -#include "base/stats/mysql.hh" -#include "base/stats/text.hh" #include "base/cprintf.hh" #include "base/misc.hh" #include "base/statistics.hh" @@ -41,6 +39,13 @@ #include "sim/core.hh" #include "sim/stat_control.hh" +// override the default main() code for this unittest +const char *m5MainCommands[] = { + "import m5.stattestmain", + "m5.stattestmain.main()", + 0 // sentinel is required +}; + using namespace std; using namespace Stats; @@ -55,67 +60,8 @@ class TestClass { double operator()() { return 9.7; } }; -const char *progname = ""; - -void -usage() +struct StatTest { - panic("incorrect usage.\n" - "usage:\n" - "\t%s [-t [-c] [-d]]\n", progname); -} - -int -main(int argc, char *argv[]) -{ - bool descriptions = false; - bool text = false; - -#if USE_MYSQL - string mysql_name; - string mysql_db; - string mysql_host; - string mysql_user = "binkertn"; - string mysql_passwd; -#endif - - char c; - progname = argv[0]; - while ((c = getopt(argc, argv, "cD:dh:P:p:s:tu:")) != -1) { - switch (c) { - case 'd': - descriptions = true; - break; - case 't': - text = true; - break; -#if USE_MYSQL - case 'D': - mysql_db = optarg; - break; - case 'h': - mysql_host = optarg; - break; - case 'P': - mysql_passwd = optarg; - break; - case 's': - mysql_name = optarg; - break; - case 'u': - mysql_user = optarg; - break; -#endif - default: - usage(); - } - } - - if (!text && descriptions) - usage(); - - initSimStats(); - Scalar s1; Scalar s2; Average s3; @@ -153,6 +99,26 @@ main(int argc, char *argv[]) Formula f4; Formula f5; + void run(); + void init(); +}; + +StatTest __stattest; +void +stattest_init() +{ + __stattest.init(); +} + +void +stattest_run() +{ + __stattest.run(); +} + +void +StatTest::init() +{ cprintf("sizeof(Scalar) = %d\n", sizeof(Scalar)); cprintf("sizeof(Vector) = %d\n", sizeof(Vector)); cprintf("sizeof(Distribution) = %d\n", sizeof(Distribution)); @@ -386,10 +352,11 @@ main(int argc, char *argv[]) f4 += constant(10.0); f4 += s5[3]; f5 = constant(1); +} - enable(); - reset(); - +void +StatTest::run() +{ s16[1][0] = 1; s16[0][1] = 3; s16[0][0] = 2; @@ -656,23 +623,4 @@ main(int argc, char *argv[]) h11.sample(i); h12.sample(i); } - - prepare(); - - if (text) { - Text out(cout); - out.descriptions = descriptions; - out(); - } - -#if USE_MYSQL - if (!mysql_name.empty()) { - MySql out; - out.connect(mysql_host, mysql_db, mysql_user, mysql_passwd, "test", - mysql_name, "test"); - out(); - } -#endif - - return 0; } diff --git a/src/unittest/stattest.i b/src/unittest/stattest.i new file mode 100644 index 000000000..0cc9192ba --- /dev/null +++ b/src/unittest/stattest.i @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +%module(package="m5.internal") stattest + +%inline %{ +extern void stattest_init(); +extern void stattest_run(); +%} diff --git a/src/unittest/stattestmain.py b/src/unittest/stattestmain.py new file mode 100644 index 000000000..2c0a4a9aa --- /dev/null +++ b/src/unittest/stattestmain.py @@ -0,0 +1,19 @@ +def main(): + from m5.internal.stattest import stattest_init, stattest_run + import m5.stats + + stattest_init() + + # Initialize the global statistics + m5.stats.initSimStats() + m5.stats.initText("cout") + + # We're done registering statistics. Enable the stats package now. + m5.stats.enable() + + # Reset to put the stats in a consistent state. + m5.stats.reset() + + stattest_run() + + m5.stats.dump()