Run unit tests as indenpendent WAF tasks
This commit is contained in:
@@ -16,7 +16,7 @@ def configure(conf):
|
||||
"library 'libxml-2.0 >= 2.7' not found")
|
||||
conf.sub_config('stats')
|
||||
|
||||
conf.write_config_header('ns3/contrib-config.h', project_root_relative=True)
|
||||
conf.write_config_header('ns3/contrib-config.h', top=True)
|
||||
|
||||
def build(bld):
|
||||
module = bld.create_ns3_module('contrib', ['simulator', 'common'])
|
||||
|
||||
@@ -55,6 +55,18 @@ TestManager::EnableVerbose (void)
|
||||
{
|
||||
Get ()->m_verbose = true;
|
||||
}
|
||||
|
||||
void
|
||||
TestManager::PrintTestNames (std::ostream &os)
|
||||
{
|
||||
for (TestsCI i = Get ()->m_tests.begin (); i != Get ()->m_tests.end (); i++)
|
||||
{
|
||||
std::string *testName = (*i).second;
|
||||
os << *testName << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::ostream &
|
||||
TestManager::Failure (void)
|
||||
{
|
||||
@@ -95,6 +107,47 @@ TestManager::RealRunTests (void)
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
bool
|
||||
TestManager::RunTest (std::string name)
|
||||
{
|
||||
return Get ()->RealRunTest (name);
|
||||
}
|
||||
bool
|
||||
TestManager::RealRunTest (std::string name)
|
||||
{
|
||||
TestsCI i;
|
||||
|
||||
for (i = m_tests.begin (); i != m_tests.end (); i++)
|
||||
{
|
||||
std::string *testName = (*i).second;
|
||||
if (*testName == name)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == m_tests.end ())
|
||||
{
|
||||
std::cerr << "Test with name " << name << " not found." << std::endl;
|
||||
}
|
||||
|
||||
if (!(*i).first->RunTests ())
|
||||
{
|
||||
if (m_verbose)
|
||||
{
|
||||
std::cerr << "FAIL " << name << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_verbose)
|
||||
{
|
||||
std::cerr << "PASS "<< name << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Test::Test (char const *name)
|
||||
{
|
||||
TestManager::Add (this, name);
|
||||
|
||||
@@ -89,12 +89,17 @@ public:
|
||||
*/
|
||||
static bool RunTests (void);
|
||||
|
||||
static bool RunTest (std::string name);
|
||||
|
||||
static void PrintTestNames (std::ostream &os);
|
||||
|
||||
private:
|
||||
friend class Test;
|
||||
static void Add (Test *test, char const *name);
|
||||
static std::ostream &Failure (void);
|
||||
static TestManager *Get (void);
|
||||
bool RealRunTests (void);
|
||||
bool RealRunTest (std::string name);
|
||||
|
||||
TestManager ();
|
||||
~TestManager ();
|
||||
|
||||
@@ -41,7 +41,7 @@ int main ()
|
||||
conf.env['ENABLE_THREADING'],
|
||||
"<pthread.h> include not detected")
|
||||
|
||||
conf.write_config_header('ns3/core-config.h', project_root_relative=True)
|
||||
conf.write_config_header('ns3/core-config.h', top=True)
|
||||
|
||||
def build(bld):
|
||||
core = bld.create_ns3_module('core')
|
||||
|
||||
@@ -31,7 +31,7 @@ def configure(conf):
|
||||
|
||||
conf.check(header_name='sys/inttypes.h', define_name='HAVE_SYS_INT_TYPES_H')
|
||||
|
||||
conf.write_config_header('ns3/simulator-config.h', project_root_relative=True)
|
||||
conf.write_config_header('ns3/simulator-config.h', top=True)
|
||||
|
||||
if not conf.check(lib='rt', uselib='RT', define_name='HAVE_RT'):
|
||||
conf.report_optional_feature("RealTime", "Real Time Simulator",
|
||||
|
||||
@@ -25,13 +25,42 @@
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
if (argc > 1)
|
||||
{
|
||||
if (std::string (argv[1]) == "--ListTests")
|
||||
{
|
||||
#ifdef RUN_SELF_TESTS
|
||||
ns3::PacketMetadata::Enable ();
|
||||
ns3::TestManager::EnableVerbose ();
|
||||
bool success = ns3::TestManager::RunTests ();
|
||||
if (!success)
|
||||
return 1;
|
||||
ns3::TestManager::PrintTestNames (std::cout);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// run the test named by argv[1]
|
||||
#ifdef RUN_SELF_TESTS
|
||||
bool success = ns3::TestManager::RunTest (argv[1]);
|
||||
if (!success)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
std::cerr << "Unit tests not enabled" << std::endl;
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// run all tests
|
||||
#ifdef RUN_SELF_TESTS
|
||||
ns3::PacketMetadata::Enable ();
|
||||
ns3::TestManager::EnableVerbose ();
|
||||
bool success = ns3::TestManager::RunTests ();
|
||||
if (!success)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif /* RUN_SELF_TESTS */
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
187
wscript
187
wscript
@@ -146,6 +146,9 @@ def set_options(opt):
|
||||
opt.add_option('--regression',
|
||||
help=("Enable regression testing; only used for the 'check' target"),
|
||||
default=False, dest='regression', action="store_true")
|
||||
opt.add_option('--check',
|
||||
help=("Enable unit testing"),
|
||||
default=False, dest='check', action="store_true")
|
||||
opt.add_option('--regression-generate',
|
||||
help=("Generate new regression test traces."),
|
||||
default=False, dest='regression_generate', action="store_true")
|
||||
@@ -523,6 +526,8 @@ def build(bld):
|
||||
" (--with-regression-traces configure option)")
|
||||
regression.run_regression(bld, regression_traces)
|
||||
|
||||
if Options.options.check:
|
||||
_run_check(bld)
|
||||
|
||||
|
||||
def shutdown(ctx):
|
||||
@@ -561,35 +566,163 @@ def shutdown(ctx):
|
||||
|
||||
check_context = Build.BuildContext
|
||||
def check(bld):
|
||||
"run the NS-3 unit tests"
|
||||
Scripting.build(bld)
|
||||
## generate the trace sources list docs
|
||||
env = wutils.bld.env
|
||||
proc_env = wutils.get_proc_env()
|
||||
try:
|
||||
program_obj = wutils.find_program('print-introspected-doxygen', env)
|
||||
except ValueError: # could happen if print-introspected-doxygen is
|
||||
# not built because of waf configure
|
||||
# --enable-modules=xxx
|
||||
pass
|
||||
else:
|
||||
prog = program_obj.path.find_or_declare(ccroot.get_target_name(program_obj)).abspath(env)
|
||||
out = open(os.path.join('doc', 'introspected-doxygen.h'), 'w')
|
||||
if subprocess.Popen([prog], stdout=out, env=proc_env).wait():
|
||||
raise SystemExit(1)
|
||||
out.close()
|
||||
|
||||
print "-- Running NS-3 C++ core unit tests..."
|
||||
wutils.run_program('run-tests', env, wutils.get_command_template(env))
|
||||
|
||||
if env['ENABLE_PYTHON_BINDINGS']:
|
||||
print "-- Running NS-3 Python bindings unit tests..."
|
||||
wutils.run_argv([env['PYTHON'], os.path.join("utils", "python-unit-tests.py")],
|
||||
env, proc_env, force_no_valgrind=True)
|
||||
else:
|
||||
print "-- Skipping NS-3 Python bindings unit tests: Python bindings not enabled."
|
||||
"""run the NS-3 unit tests (deprecated in favour of --check option)"""
|
||||
raise Utils.WafError("Please run `./waf --check' instead.")
|
||||
|
||||
|
||||
class print_introspected_doxygen_task(Task.TaskBase):
|
||||
after = 'cc cxx cc_link cxx_link'
|
||||
color = 'BLUE'
|
||||
|
||||
def __init__(self, bld):
|
||||
self.bld = bld
|
||||
super(print_introspected_doxygen_task, self).__init__(generator=self)
|
||||
|
||||
def __str__(self):
|
||||
return 'print-introspected-doxygen\n'
|
||||
|
||||
def runnable_status(self):
|
||||
return Task.RUN_ME
|
||||
|
||||
def run(self):
|
||||
## generate the trace sources list docs
|
||||
env = wutils.bld.env
|
||||
proc_env = wutils.get_proc_env()
|
||||
try:
|
||||
program_obj = wutils.find_program('print-introspected-doxygen', env)
|
||||
except ValueError: # could happen if print-introspected-doxygen is
|
||||
# not built because of waf configure
|
||||
# --enable-modules=xxx
|
||||
pass
|
||||
else:
|
||||
prog = program_obj.path.find_or_declare(ccroot.get_target_name(program_obj)).abspath(env)
|
||||
out = open(os.path.join('..', 'doc', 'introspected-doxygen.h'), 'w')
|
||||
if subprocess.Popen([prog], stdout=out, env=proc_env).wait():
|
||||
raise SystemExit(1)
|
||||
out.close()
|
||||
|
||||
class run_python_unit_tests_task(Task.TaskBase):
|
||||
after = 'cc cxx cc_link cxx_link'
|
||||
color = 'BLUE'
|
||||
|
||||
def __init__(self, bld):
|
||||
self.bld = bld
|
||||
super(run_python_unit_tests_task, self).__init__(generator=self)
|
||||
|
||||
def __str__(self):
|
||||
return 'run-python-unit-tests\n'
|
||||
|
||||
def runnable_status(self):
|
||||
return Task.RUN_ME
|
||||
|
||||
def run(self):
|
||||
proc_env = wutils.get_proc_env()
|
||||
wutils.run_argv([self.bld.env['PYTHON'], os.path.join("..", "utils", "python-unit-tests.py")],
|
||||
self.bld.env, proc_env, force_no_valgrind=True)
|
||||
|
||||
|
||||
class run_a_unit_test_task(Task.TaskBase):
|
||||
after = 'cc cxx cc_link cxx_link'
|
||||
color = 'BLUE'
|
||||
|
||||
def __init__(self, bld, name_of_test):
|
||||
self.bld = bld
|
||||
super(run_a_unit_test_task, self).__init__(generator=self)
|
||||
self.name_of_test = name_of_test
|
||||
try:
|
||||
program_obj = wutils.find_program("run-tests", self.bld.env)
|
||||
except ValueError, ex:
|
||||
raise Utils.WafError(str(ex))
|
||||
program_node = program_obj.path.find_or_declare(ccroot.get_target_name(program_obj))
|
||||
self.program_path = program_node.abspath(self.bld.env)
|
||||
|
||||
def __str__(self):
|
||||
return 'run-unit-test(%s)\n' % self.name_of_test
|
||||
|
||||
def runnable_status(self):
|
||||
return Task.RUN_ME
|
||||
|
||||
def run(self):
|
||||
#print repr([self.program_path, self.name_of_test])
|
||||
try:
|
||||
self.retval = wutils.run_argv([self.program_path, self.name_of_test], self.bld.env)
|
||||
except Utils.WafError:
|
||||
self.retval = 1
|
||||
#print "running test %s: exit with %i" % (self.name_of_test, retval)
|
||||
return 0
|
||||
|
||||
class get_list_of_unit_tests_task(Task.TaskBase):
|
||||
after = 'cc cxx cc_link cxx_link'
|
||||
color = 'BLUE'
|
||||
|
||||
def __init__(self, bld):
|
||||
self.bld = bld
|
||||
super(get_list_of_unit_tests_task, self).__init__(generator=self)
|
||||
self.tests = []
|
||||
|
||||
def __str__(self):
|
||||
return 'get-unit-tests-list\n'
|
||||
|
||||
def runnable_status(self):
|
||||
return Task.RUN_ME
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
program_obj = wutils.find_program("run-tests", self.bld.env)
|
||||
except ValueError, ex:
|
||||
raise Utils.WafError(str(ex))
|
||||
program_node = program_obj.path.find_or_declare(ccroot.get_target_name(program_obj))
|
||||
program_path = program_node.abspath(self.bld.env)
|
||||
proc = subprocess.Popen([program_path, "--ListTests"], stdout=subprocess.PIPE,
|
||||
env=wutils.get_proc_env())
|
||||
self.tests = [l.rstrip() for l in proc.stdout.readlines()]
|
||||
retval = proc.wait()
|
||||
if retval:
|
||||
return retval
|
||||
test_tasks = []
|
||||
for name_of_test in self.tests:
|
||||
test_tasks.append(run_a_unit_test_task(self.bld, name_of_test))
|
||||
collector = collect_unit_test_results_task(self.bld, list(test_tasks))
|
||||
collector.run_after = list(test_tasks)
|
||||
self.more_tasks = [collector] + test_tasks
|
||||
|
||||
|
||||
class collect_unit_test_results_task(Task.TaskBase):
|
||||
after = 'run_a_unit_test_task'
|
||||
color = 'BLUE'
|
||||
|
||||
def __init__(self, bld, test_tasks):
|
||||
self.bld = bld
|
||||
super(collect_unit_test_results_task, self).__init__(generator=self)
|
||||
self.test_tasks = test_tasks
|
||||
|
||||
def __str__(self):
|
||||
return 'collect-unit-tests-results\n'
|
||||
|
||||
def runnable_status(self):
|
||||
for t in self.run_after:
|
||||
if not t.hasrun:
|
||||
return Task.ASK_LATER
|
||||
return Task.RUN_ME
|
||||
|
||||
def run(self):
|
||||
failed = 0
|
||||
for task in self.test_tasks:
|
||||
if task.retval:
|
||||
failed += 1
|
||||
if failed:
|
||||
print "C++ UNIT TESTS: %i tests passed, %i failed." % (len(self.test_tasks) - failed, failed)
|
||||
return 1
|
||||
else:
|
||||
print "C++ UNIT TESTS: all %i tests passed." % (len(self.test_tasks),)
|
||||
return 0
|
||||
|
||||
|
||||
def _run_check(bld):
|
||||
task = get_list_of_unit_tests_task(bld)
|
||||
print_introspected_doxygen_task(bld)
|
||||
if bld.env['ENABLE_PYTHON_BINDINGS']:
|
||||
run_python_unit_tests_task(bld)
|
||||
|
||||
|
||||
def check_shell(bld):
|
||||
|
||||
Reference in New Issue
Block a user