46 double delta, difference;
52 double max = (std::fabs (x1) > std::fabs (x2)) ? x1 : x2;
53 (void)std::frexp (max, &exponent);
59 delta = std::ldexp (epsilon, exponent);
62 if (difference > delta || difference < -delta)
72 std::string _limit, std::string _message,
73 std::string _file, int32_t _line);
83 os <<
" test=\"" << failure.
cond
84 <<
"\" actual=\"" << failure.
actual
85 <<
"\" limit=\"" << failure.
limit
86 <<
"\" in=\"" << failure.
file
87 <<
":" << failure.
line
108 std::string limit, std::string message,
109 std::string file, int32_t line);
116 int Run (
int argc,
char *argv[]);
128 std::list<TestCase *>::const_iterator end,
129 bool printTestType)
const;
131 void PrintHelp (
const char *programName)
const;
132 std::list<TestCase *>
FilterTests (std::string testName,
150 std::string _limit, std::string _message,
151 std::string _file, int32_t _line)
152 : cond (_cond), actual (_actual), limit (_limit),
153 message (_message), file (_file), line (_line)
155 NS_LOG_FUNCTION (
this << _cond << _actual << _limit << _message << _file << _line);
158 : childrenFailed (false)
182 for (std::vector<TestCase *>::const_iterator i =
m_children.begin (); i !=
m_children.end (); ++i)
199 std::string::size_type slash, antislash;
200 slash = testCase->
m_name.find (
"/");
201 antislash = testCase->
m_name.find (
"\\");
202 if (slash != std::string::npos || antislash != std::string::npos)
204 std::string fullname = testCase->
m_name;
208 fullname = current->
m_name +
"/" + fullname;
211 if (slash != std::string::npos)
213 NS_FATAL_ERROR (
"Invalid test name: cannot contain slashes: \"" << fullname <<
"\"");
215 if (antislash != std::string::npos)
217 NS_FATAL_ERROR (
"Invalid test name: cannot contain antislashes: \"" << fullname <<
"\"");
237 for (std::vector<TestCase *>::const_iterator i =
m_children.begin (); i !=
m_children.end (); ++i)
266 std::string limit, std::string message,
267 std::string file, int32_t line)
269 NS_LOG_FUNCTION (
this << cond << actual << limit << message << file << line);
271 message, file, line));
299 while (current != 0 && current->
m_dataDir ==
"")
305 NS_FATAL_ERROR (
"No one called SetDataDir prior to calling this function");
322 std::list<std::string> names;
326 names.push_front (current->
m_name);
389 m_assertOnFailure (false),
390 m_continueOnFailure (true),
448 bool haveVersion =
false;
449 bool haveLicense =
false;
457 for (std::list<std::string>::const_iterator i = files.begin (); i != files.end (); ++i)
463 else if (*i ==
"LICENSE")
469 return haveVersion && haveLicense;
478 while (!elements.empty ())
485 elements.pop_back ();
487 NS_FATAL_ERROR (
"Could not find source directory from self=" <<
self);
499 typedef std::map <char, std::string> specials_map;
500 specials_map specials;
501 specials[
'<'] =
"<";
502 specials[
'>'] =
">";
503 specials[
'&'] =
"&";
504 specials[
'"'] =
"'";
505 specials[
'\''] =
""";
508 std::size_t length = xml.length ();
510 for (
size_t i = 0; i < length; ++i)
512 char character = xml[i];
514 specials_map::const_iterator it = specials.find (character);
516 if (it == specials.end ())
518 result.push_back (character);
522 result += it->second;
540 for (
int i = 0; i < val.
level; i++)
557 const double MS_PER_SEC = 1000.;
562 std::streamsize oldPrecision = (*os).precision (3);
565 std::string statusString = test->
IsFailed ()?
"FAIL":
"PASS";
568 *os <<
Indent (level) <<
"<Test>" << std::endl;
570 <<
"</Name>" << std::endl;
571 *os <<
Indent (level+1) <<
"<Result>" << statusString <<
"</Result>" << std::endl;
572 *os <<
Indent (level+1) <<
"<Time real=\"" << real <<
"\" user=\"" << user
573 <<
"\" system=\"" << system <<
"\"/>" << std::endl;
577 *os <<
Indent (level+2) <<
"<FailureDetails>" << std::endl
578 <<
Indent (level+3) <<
"<Condition>"
580 <<
Indent (level+3) <<
"<Actual>"
582 <<
Indent (level+3) <<
"<Limit>"
584 <<
Indent (level+3) <<
"<Message>"
586 <<
Indent (level+3) <<
"<File>"
588 <<
Indent (level+3) <<
"<Line>" << failure.
line <<
"</Line>" << std::endl
589 <<
Indent (level+2) <<
"</FailureDetails>" << std::endl;
591 for (uint32_t i = 0; i < test->
m_children.size (); i++)
596 *os <<
Indent (level) <<
"</Test>" << std::endl;
600 *os <<
Indent (level) << statusString <<
" " << test->
GetName ()
601 <<
" " << real <<
" s" << std::endl;
608 for (uint32_t i = 0; i < test->
m_children.size (); i++)
616 (*os).unsetf(std::ios_base::floatfield);
617 (*os).precision (oldPrecision);
624 std::cout <<
"Usage: " << program_name <<
" [OPTIONS]" << std::endl
626 <<
"Options: " << std::endl
627 <<
" --help : print these options" << std::endl
628 <<
" --print-test-name-list : print the list of names of tests available" << std::endl
629 <<
" --list : an alias for --print-test-name-list" << std::endl
630 <<
" --print-test-types : print the type of tests along with their names" << std::endl
631 <<
" --print-test-type-list : print the list of types of tests available" << std::endl
632 <<
" --print-temp-dir : print name of temporary directory before running " << std::endl
633 <<
" the tests" << std::endl
634 <<
" --test-type=TYPE : process only tests of type TYPE" << std::endl
635 <<
" --test-name=NAME : process only test whose name matches NAME" << std::endl
636 <<
" --suite=NAME : an alias (here for compatibility reasons only) " << std::endl
637 <<
" for --test-name=NAME" << std::endl
638 <<
" --assert-on-failure : when a test fails, crash immediately (useful" << std::endl
639 <<
" when running under a debugger" << std::endl
640 <<
" --stop-on-failure : when a test fails, stop immediately" << std::endl
641 <<
" --fullness=FULLNESS : choose the duration of tests to run: QUICK, " << std::endl
642 <<
" EXTENSIVE, or TAKES_FOREVER, where EXTENSIVE " << std::endl
643 <<
" includes QUICK and TAKES_FOREVER includes " << std::endl
644 <<
" QUICK and EXTENSIVE (only QUICK tests are " << std::endl
645 <<
" run by default)" << std::endl
646 <<
" --verbose : print details of test execution" << std::endl
647 <<
" --xml : format test run output as xml" << std::endl
648 <<
" --tempdir=DIR : set temp dir for tests to store output files" << std::endl
649 <<
" --datadir=DIR : set data dir for tests to read reference files" << std::endl
650 <<
" --out=FILE : send test result to FILE instead of standard "
651 <<
"output" << std::endl
652 <<
" --append=FILE : append test result to FILE instead of standard "
653 <<
"output" << std::endl
659 std::list<TestCase *>::const_iterator end,
660 bool printTestType)
const
663 std::map<TestSuite::Type, std::string> label;
672 for (std::list<TestCase *>::const_iterator i = begin; i != end; ++i)
680 std::cout << test->
GetName () << std::endl;
688 std::cout <<
" bvt: Build Verification Tests (to see if build completed successfully)" << std::endl;
689 std::cout <<
" core: Run all TestSuite-based tests (exclude examples)" << std::endl;
690 std::cout <<
" example: Examples (to see if example programs run successfully)" << std::endl;
691 std::cout <<
" performance: Performance Tests (check to see if the system is as fast as expected)" << std::endl;
692 std::cout <<
" system: System Tests (spans modules to check integration of modules)" << std::endl;
693 std::cout <<
" unit: Unit Tests (within modules to check basic functionality)" << std::endl;
697 std::list<TestCase *>
703 std::list<TestCase *> tests;
704 for (uint32_t i = 0; i <
m_suites.size (); ++i)
712 if (testName !=
"" && test->
GetName () != testName)
719 std::vector<TestCase *>::iterator j;
720 for (j = test->m_children.begin (); j != test->m_children.end ();)
726 if (testCase->
m_duration > maximumTestDuration)
732 j = test->m_children.erase (j);
743 tests.push_back (test);
753 std::string testName =
"";
754 std::string testTypeString =
"";
755 std::string out =
"";
756 std::string fullness =
"";
759 bool printTempDir =
false;
760 bool printTestTypeList =
false;
761 bool printTestNameList =
false;
762 bool printTestTypeAndName =
false;
764 char *progname = argv[0];
772 if (strcmp(arg,
"--assert-on-failure") == 0)
776 else if (strcmp (arg,
"--stop-on-failure") == 0)
780 else if (strcmp (arg,
"--verbose") == 0)
784 else if (strcmp (arg,
"--print-temp-dir") == 0)
788 else if (strcmp (arg,
"--update-data") == 0)
792 else if (strcmp (arg,
"--help") == 0)
797 else if (strcmp (arg,
"--print-test-name-list") == 0 ||
798 strcmp(arg,
"--list") == 0)
800 printTestNameList =
true;
802 else if (strcmp (arg,
"--print-test-types") == 0)
804 printTestTypeAndName =
true;
806 else if (strcmp (arg,
"--print-test-type-list") == 0)
808 printTestTypeList =
true;
810 else if (strcmp(arg,
"--append") == 0)
814 else if (strcmp(arg,
"--xml") == 0)
818 else if (strncmp(arg,
"--test-type=", strlen(
"--test-type=")) == 0)
820 testTypeString = arg + strlen(
"--test-type=");
822 else if (strncmp(arg,
"--test-name=", strlen(
"--test-name=")) == 0)
824 testName = arg + strlen(
"--test-name=");
826 else if (strncmp(arg,
"--suite=", strlen(
"--suite=")) == 0)
828 testName = arg + strlen(
"--suite=");
830 else if (strncmp(arg,
"--tempdir=", strlen(
"--tempdir=")) == 0)
834 else if (strncmp(arg,
"--out=", strlen(
"--out=")) == 0)
836 out = arg + strlen(
"--out=");
838 else if (strncmp(arg,
"--fullness=", strlen(
"--fullness=")) == 0)
840 fullness = arg + strlen(
"--fullness=");
843 if (fullness ==
"EXTENSIVE")
847 else if (fullness ==
"TAKES_FOREVER")
865 if (testTypeString ==
"")
869 else if (testTypeString ==
"bvt")
873 else if (testTypeString ==
"core")
877 else if (testTypeString ==
"example")
881 else if (testTypeString ==
"unit")
885 else if (testTypeString ==
"system")
889 else if (testTypeString ==
"performance")
895 std::cout <<
"Invalid test type specified: " << testTypeString << std::endl;
900 std::list<TestCase *> tests =
FilterTests (testName, testType, maximumTestDuration);
910 if (printTestNameList)
915 if (printTestTypeList)
926 ofs =
new std::ofstream();
927 std::ios_base::openmode mode = std::ios_base::out;
930 mode |= std::ios_base::app;
934 mode |= std::ios_base::trunc;
936 ofs->open (out.c_str (), mode);
946 if (tests.size () == 0)
948 std::cerr <<
"Error: no tests match the requested string" << std::endl;
951 for (std::list<TestCase *>::const_iterator i = tests.begin (); i != tests.end (); ++i)
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
bool MustAssertOnFailure(void) const
void PrintHelp(const char *programName) const
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
TestCaseFailure(std::string _cond, std::string _actual, std::string _limit, std::string _message, std::string _file, int32_t _line)
void AddTestSuite(TestSuite *testSuite)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
bool IsFailed(void) const
#define NS_FATAL_ERROR(msg)
Fatal error handling.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition of the testing macros and declaration of the testing classes.
enum TestDuration m_duration
TestCase duration.
This test suite implements a Unit Test.
void PrintReport(TestCase *test, std::ostream *os, bool xml, int level)
void PrintTestNameList(std::list< TestCase * >::const_iterator begin, std::list< TestCase * >::const_iterator end, bool printTestType) const
TestSuite(std::string name, Type type=UNIT)
Constuct a new test suite.
std::list< std::string > Split(std::string path)
Split a file system path into directories according to the local path separator.
TestDuration
How long the test takes to execute.
This test suite implements an Example Test.
virtual void DoRun(void)
Implementation to actually run this TestCase.
std::list< TestCase * > FilterTests(std::string testName, enum TestSuite::Type testType, enum TestCase::TestDuration maximumTestDuration)
System-independent file and directory function declarations.
std::string GetTempDir(void) const
Measure elapsed wall clock time in milliseconds.
std::string Join(std::list< std::string >::const_iterator begin, std::list< std::string >::const_iterator end)
Join a list of file system path directories into a single file system path.
TestCase * m_parent
Pointer to my parent TestCase.
TestRunnerImpl * m_runner
Pointer to the TestRunner.
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition of assertion macros NS_ASSERT() and NS_ASSERT_MSG().
std::string MakeTemporaryDirectoryName(void)
Get the name of a temporary directory.
std::list< std::string > ReadFiles(std::string path)
Get the list of files located in a file system directory.
std::string GetTopLevelSourceDir(void) const
bool TestDoubleIsEqual(const double x1, const double x2, const double epsilon)
Compare two double precision floating point numbers and declare them equal if they are within some ep...
void Start(void)
Start a measure.
bool MustUpdateData(void) const
TestSuite::Type m_type
Type of this TestSuite.
bool MustAssertOnFailure(void) const
TestCase(std::string name)
void ReportTestFailure(std::string cond, std::string actual, std::string limit, std::string message, std::string file, int32_t line)
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
bool MustContinueOnFailure(void) const
virtual ~TestCase()
Destructor.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::string CreateDataDirFilename(std::string filename)
This test suite implements a Performance Test.
virtual void DoRun(void)=0
Implementation to actually run this TestCase.
struct Result * m_result
Results data.
bool IsStatusFailure(void) const
TestCase * GetParent() const
void ReportTestFailure(std::string cond, std::string actual, std::string limit, std::string message, std::string file, int32_t line)
Log the failure of this TestCase.
void Run(TestRunnerImpl *runner)
Actually run this TestCase.
bool IsStatusSuccess(void) const
void MakeDirectories(std::string path)
Create all the directories leading to path.
int64_t GetElapsedUser(void) const
This test suite implements a System Test.
std::string FindSelfDirectory(void)
Get the file system path to the current executable.
std::string CreateTempDirFilename(std::string filename)
std::string Append(std::string left, std::string right)
Join two file system path elements.
This test suite implements a Build Verification Test.
int64_t GetElapsedReal(void) const
std::string ReplaceXmlSpecialCharacters(std::string xml) const
void SetDataDir(std::string directory)
std::vector< TestSuite * > TestSuiteVector
static TestRunnerImpl * Instance(void)
std::vector< TestCase * > m_children
Vector of my children.
int64_t GetElapsedSystem(void) const
std::string GetName(void) const
bool IsTopLevelSourceDir(std::string path) const
TestSuite::Type GetTestType(void)
get the kind of test this test suite implements
void PrintTestTypeList(void) const
std::vector< TestCaseFailure > failure
void StartTestCase(std::string name)
int64_t End(void)
Stop measuring the time since Start() was called.
static int Run(int argc, char *argv[])
Run the requested suite of tests.
int Run(int argc, char *argv[])
std::string m_name
TestCase name.
void test(void)
Example use of ns3::SystemThread.
std::string m_dataDir
My data directory.
bool MustContinueOnFailure(void) const
NS_ABORT_x macro definitions.