48 double delta, difference;
54 double max = (std::fabs (x1) > std::fabs (x2)) ? x1 : x2;
55 (void)std::frexp (
max, &exponent);
61 delta = std::ldexp (
epsilon, exponent);
64 if (difference > delta || difference < -delta)
88 std::string _limit, std::string _message,
89 std::string _file, int32_t _line);
106 os <<
" test=\"" << failure.
cond
107 <<
"\" actual=\"" << failure.
actual
108 <<
"\" limit=\"" << failure.
limit
109 <<
"\" in=\"" << failure.
file
110 <<
":" << failure.
line
173 int Run (
int argc,
char *argv[]);
220 std::list<TestCase *>::const_iterator end,
221 bool printTestType)
const;
228 void PrintHelp (
const char *programName)
const;
240 std::list<TestCase *>
FilterTests (std::string testName,
259 std::string _limit, std::string _message,
260 std::string _file, int32_t _line)
261 : cond (_cond), actual (_actual), limit (_limit),
262 message (_message),
file (_file), line (_line)
264 NS_LOG_FUNCTION (
this << _cond << _actual << _limit << _message << _file << _line);
267 : childrenFailed (false)
291 for (std::vector<TestCase *>::const_iterator i =
m_children.begin (); i !=
m_children.end (); ++i)
315 std::string badchars =
"\"/\\|?";
322 std::string::size_type badch = testCase->
m_name.find_first_of (badchars);
323 if (badch != std::string::npos)
331 << badchars <<
"': " << testCase->
m_name);
354 for (std::vector<TestCase *>::const_iterator i =
m_children.begin (); i !=
m_children.end (); ++i)
383 std::string limit, std::string message,
384 std::string
file, int32_t line)
388 message,
file, line));
416 while (current != 0 && current->
m_dataDir ==
"")
422 NS_FATAL_ERROR (
"No one called SetDataDir prior to calling this function");
439 std::list<std::string> names;
443 names.push_front (current->
m_name);
506 m_assertOnFailure (false),
507 m_continueOnFailure (true),
550 bool haveVersion =
false;
551 bool haveLicense =
false;
559 for (std::list<std::string>::const_iterator i = files.begin (); i != files.end (); ++i)
565 else if (*i ==
"LICENSE")
571 return haveVersion && haveLicense;
580 while (!elements.empty ())
587 elements.pop_back ();
589 NS_FATAL_ERROR (
"Could not find source directory from self=" <<
self);
602 typedef std::map <char, std::string> specials_map;
603 specials_map specials;
604 specials[
'<'] =
"<";
605 specials[
'>'] =
">";
606 specials[
'&'] =
"&";
607 specials[
'"'] =
"'";
608 specials[
'\''] =
""";
611 std::size_t length = xml.length ();
613 for (
size_t i = 0; i < length; ++i)
615 char character = xml[i];
617 specials_map::const_iterator it = specials.find (character);
619 if (it == specials.end ())
621 result.push_back (character);
655 for (
int i = 0; i < val.
level; i++)
666 if (test->m_result == 0)
672 const double MS_PER_SEC = 1000.;
673 double real = test->m_result->clock.GetElapsedReal () / MS_PER_SEC;
674 double user = test->m_result->clock.GetElapsedUser () / MS_PER_SEC;
675 double system = test->m_result->clock.GetElapsedSystem () / MS_PER_SEC;
677 std::streamsize oldPrecision = (*os).precision (3);
680 std::string statusString = test->IsFailed () ?
"FAIL" :
"PASS";
683 *os <<
Indent (level) <<
"<Test>" << std::endl;
685 <<
"</Name>" << std::endl;
686 *os <<
Indent (level + 1) <<
"<Result>" << statusString <<
"</Result>" << std::endl;
687 *os <<
Indent (level + 1) <<
"<Time real=\"" << real <<
"\" user=\"" << user
688 <<
"\" system=\"" << system <<
"\"/>" << std::endl;
689 for (uint32_t i = 0; i < test->m_result->failure.size (); i++)
692 *os <<
Indent (level + 2) <<
"<FailureDetails>" << std::endl
693 <<
Indent (level + 3) <<
"<Condition>"
695 <<
Indent (level + 3) <<
"<Actual>"
697 <<
Indent (level + 3) <<
"<Limit>"
699 <<
Indent (level + 3) <<
"<Message>"
701 <<
Indent (level + 3) <<
"<File>"
703 <<
Indent (level + 3) <<
"<Line>" << failure.
line <<
"</Line>" << std::endl
704 <<
Indent (level + 2) <<
"</FailureDetails>" << std::endl;
706 for (uint32_t i = 0; i < test->m_children.size (); i++)
708 TestCase *child = test->m_children[i];
711 *os <<
Indent (level) <<
"</Test>" << std::endl;
715 *os <<
Indent (level) << statusString <<
" " << test->GetName ()
716 <<
" " << real <<
" s" << std::endl;
719 for (uint32_t i = 0; i < test->m_result->failure.size (); i++)
721 *os <<
Indent (level) << test->m_result->failure[i] << std::endl;
723 for (uint32_t i = 0; i < test->m_children.size (); i++)
725 TestCase *child = test->m_children[i];
731 (*os).unsetf (std::ios_base::floatfield);
732 (*os).precision (oldPrecision);
739 std::cout <<
"Usage: " << program_name <<
" [OPTIONS]" << std::endl
741 <<
"Options: " << std::endl
742 <<
" --help : print these options" << std::endl
743 <<
" --print-test-name-list : print the list of names of tests available" << std::endl
744 <<
" --list : an alias for --print-test-name-list" << std::endl
745 <<
" --print-test-types : print the type of tests along with their names" << std::endl
746 <<
" --print-test-type-list : print the list of types of tests available" << std::endl
747 <<
" --print-temp-dir : print name of temporary directory before running " << std::endl
748 <<
" the tests" << std::endl
749 <<
" --test-type=TYPE : process only tests of type TYPE" << std::endl
750 <<
" --test-name=NAME : process only test whose name matches NAME" << std::endl
751 <<
" --suite=NAME : an alias (here for compatibility reasons only) " << std::endl
752 <<
" for --test-name=NAME" << std::endl
753 <<
" --assert-on-failure : when a test fails, crash immediately (useful" << std::endl
754 <<
" when running under a debugger" << std::endl
755 <<
" --stop-on-failure : when a test fails, stop immediately" << std::endl
756 <<
" --fullness=FULLNESS : choose the duration of tests to run: QUICK, " << std::endl
757 <<
" EXTENSIVE, or TAKES_FOREVER, where EXTENSIVE " << std::endl
758 <<
" includes QUICK and TAKES_FOREVER includes " << std::endl
759 <<
" QUICK and EXTENSIVE (only QUICK tests are " << std::endl
760 <<
" run by default)" << std::endl
761 <<
" --verbose : print details of test execution" << std::endl
762 <<
" --xml : format test run output as xml" << std::endl
763 <<
" --tempdir=DIR : set temp dir for tests to store output files" << std::endl
764 <<
" --datadir=DIR : set data dir for tests to read reference files" << std::endl
765 <<
" --out=FILE : send test result to FILE instead of standard "
766 <<
"output" << std::endl
767 <<
" --append=FILE : append test result to FILE instead of standard "
768 <<
"output" << std::endl
774 std::list<TestCase *>::const_iterator end,
775 bool printTestType)
const
778 std::map<TestSuite::Type, std::string> label;
786 for (std::list<TestCase *>::const_iterator i = begin; i != end; ++i)
792 std::cout << label[test->GetTestType ()];
794 std::cout << test->GetName () << std::endl;
802 std::cout <<
" core: Run all TestSuite-based tests (exclude examples)" << std::endl;
803 std::cout <<
" example: Examples (to see if example programs run successfully)" << std::endl;
804 std::cout <<
" performance: Performance Tests (check to see if the system is as fast as expected)" << std::endl;
805 std::cout <<
" system: System Tests (spans modules to check integration of modules)" << std::endl;
806 std::cout <<
" unit: Unit Tests (within modules to check basic functionality)" << std::endl;
810 std::list<TestCase *>
816 std::list<TestCase *>
tests;
817 for (uint32_t i = 0; i <
m_suites.size (); ++i)
820 if (testType !=
TestSuite::ALL && test->GetTestType () != testType)
825 if (testName !=
"" && test->GetName () != testName)
832 std::vector<TestCase *>::iterator j;
833 for (j = test->m_children.begin (); j != test->m_children.end ();)
839 if (testCase->
m_duration > maximumTestDuration)
845 j = test->m_children.erase (j);
856 tests.push_back (test);
866 std::string testName =
"";
867 std::string testTypeString =
"";
868 std::string out =
"";
869 std::string fullness =
"";
872 bool printTempDir =
false;
873 bool printTestTypeList =
false;
874 bool printTestNameList =
false;
875 bool printTestTypeAndName =
false;
877 char *progname = argv[0];
886 if (strcmp (arg,
"--assert-on-failure") == 0)
890 else if (strcmp (arg,
"--stop-on-failure") == 0)
894 else if (strcmp (arg,
"--verbose") == 0)
898 else if (strcmp (arg,
"--print-temp-dir") == 0)
902 else if (strcmp (arg,
"--update-data") == 0)
906 else if (strcmp (arg,
"--help") == 0)
911 else if (strcmp (arg,
"--print-test-name-list") == 0
912 || strcmp (arg,
"--list") == 0)
914 printTestNameList =
true;
916 else if (strcmp (arg,
"--print-test-types") == 0)
918 printTestTypeAndName =
true;
920 else if (strcmp (arg,
"--print-test-type-list") == 0)
922 printTestTypeList =
true;
924 else if (strcmp (arg,
"--append") == 0)
928 else if (strcmp (arg,
"--xml") == 0)
932 else if (strncmp (arg,
"--test-type=", strlen (
"--test-type=")) == 0)
934 testTypeString = arg + strlen (
"--test-type=");
936 else if (strncmp (arg,
"--test-name=", strlen (
"--test-name=")) == 0)
938 testName = arg + strlen (
"--test-name=");
940 else if (strncmp (arg,
"--suite=", strlen (
"--suite=")) == 0)
942 testName = arg + strlen (
"--suite=");
944 else if (strncmp (arg,
"--tempdir=", strlen (
"--tempdir=")) == 0)
948 else if (strncmp (arg,
"--out=", strlen (
"--out=")) == 0)
950 out = arg + strlen (
"--out=");
952 else if (strncmp (arg,
"--fullness=", strlen (
"--fullness=")) == 0)
954 fullness = arg + strlen (
"--fullness=");
957 if (fullness ==
"QUICK")
961 else if (fullness ==
"EXTENSIVE")
965 else if (fullness ==
"TAKES_FOREVER")
985 if (testTypeString ==
"")
989 else if (testTypeString ==
"core")
993 else if (testTypeString ==
"example")
997 else if (testTypeString ==
"unit")
1001 else if (testTypeString ==
"system")
1005 else if (testTypeString ==
"performance")
1011 std::cout <<
"Invalid test type specified: " << testTypeString << std::endl;
1016 std::list<TestCase *>
tests =
FilterTests (testName, testType, maximumTestDuration);
1026 if (printTestNameList)
1031 if (printTestTypeList)
1042 ofs =
new std::ofstream ();
1043 std::ios_base::openmode mode = std::ios_base::out;
1046 mode |= std::ios_base::app;
1050 mode |= std::ios_base::trunc;
1052 ofs->open (out.c_str (), mode);
1061 bool failed =
false;
1062 if (
tests.size () == 0)
1064 std::cerr <<
"Error: no tests match the requested string" << std::endl;
1067 for (std::list<TestCase *>::const_iterator i =
tests.begin (); i !=
tests.end (); ++i)
1071 #ifdef ENABLE_DES_METRICS
1080 std::string testname = test->GetName ();
1083 std::vector<std::string> desargs;
1084 desargs.push_back (testname);
1085 desargs.push_back (
runner);
1086 for (
int i = 1; i < argc; ++i)
1088 desargs.push_back (argv[i]);
1097 if (test->IsFailed ())
1112 return failed ? 1 : 0;
NS_ABORT_x macro definitions.
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
void Initialize(std::vector< std::string > args, std::string outDir="")
Open the DesMetrics trace file and print the header.
static TestRunnerImpl * Get(void)
Get a pointer to the singleton instance.
Measure elapsed wall clock time in milliseconds.
void Start(void)
Start a measure.
int64_t End(void)
Stop measuring the time since Start() was called.
std::string m_name
TestCase name.
bool IsStatusSuccess(void) const
Check if all tests passed.
TestDuration
How long the test takes to execute.
@ EXTENSIVE
Medium length test.
@ TAKES_FOREVER
Very long running test.
enum TestDuration m_duration
TestCase duration.
std::string m_dataDir
My data directory.
std::string CreateDataDirFilename(std::string filename)
Construct the full path to a file in the data directory.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
TestCase * m_parent
Pointer to my parent TestCase.
std::vector< TestCase * > m_children
Vector of my children.
virtual ~TestCase()
Destructor.
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
bool MustAssertOnFailure(void) const
Check if this run should assert on failure.
std::string CreateTempDirFilename(std::string filename)
Construct the full path to a file in a temporary directory.
TestRunnerImpl * m_runner
Pointer to the TestRunner.
TestCase * GetParent() const
Get the parent of this TestCsse.
virtual void DoRun(void)=0
Implementation to actually run this TestCase.
bool IsFailed(void) const
Check if any tests failed.
void SetDataDir(std::string directory)
Set the data directory where reference trace files can be found.
void Run(TestRunnerImpl *runner)
Actually run this TestCase.
TestCase(const TestCase &)=delete
bool MustContinueOnFailure(void) const
Check if this run should continue on failure.
bool IsStatusFailure(void) const
Check if any tests failed.
struct Result * m_result
Results data.
std::string GetName(void) 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.
static int Run(int argc, char *argv[])
Run the requested suite of tests, according to the given command line arguments.
void PrintHelp(const char *programName) const
Print the help text.
bool m_assertOnFailure
true if we should assert on failure.
bool MustUpdateData(void) const
Check if this run should update the reference data.
std::string ReplaceXmlSpecialCharacters(std::string xml) const
Clean up characters not allowed in XML.
std::string GetTempDir(void) const
Get the path to temporary directory.
bool IsTopLevelSourceDir(std::string path) const
Check if this is the root of the source tree.
std::list< TestCase * > FilterTests(std::string testName, enum TestSuite::Type testType, enum TestCase::TestDuration maximumTestDuration)
Generate the list of tests matching the constraints.
bool MustAssertOnFailure(void) const
Check if this run should assert on failure.
bool m_continueOnFailure
true if we should continue on failure.
bool m_updateData
true if we should update reference data.
std::string m_tempDir
The temporary directory.
std::vector< TestSuite * > TestSuiteVector
Container type for the test.
void PrintTestTypeList(void) const
Print the list of test types.
void PrintReport(TestCase *test, std::ostream *os, bool xml, int level)
Print the test report.
int Run(int argc, char *argv[])
Run the requested suite of tests, according to the given command line arguments.
bool MustContinueOnFailure(void) const
Check if this run should continue on failure.
TestRunnerImpl()
Constructor.
void AddTestSuite(TestSuite *testSuite)
Add a new top-level TestSuite.
bool m_verbose
Produce verbose output.
TestSuiteVector m_suites
The list of tests.
void PrintTestNameList(std::list< TestCase * >::const_iterator begin, std::list< TestCase * >::const_iterator end, bool printTestType) const
Print the list of all requested test suites.
std::string GetTopLevelSourceDir(void) const
Get the path to the root of the source tree.
@ EXAMPLE
This test suite implements an Example Test.
@ PERFORMANCE
This test suite implements a Performance Test.
@ UNIT
This test suite implements a Unit Test.
@ SYSTEM
This test suite implements a System Test.
TestSuite::Type m_type
Type of this TestSuite.
TestSuite(std::string name, Type type=UNIT)
Construct a new test suite.
virtual void DoRun(void)
Implementation to actually run this TestCase.
TestSuite::Type GetTestType(void)
get the kind of test this test suite implements
ns3::DesMetrics declaration.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionally.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
std::list< std::string > ReadFiles(std::string path)
Get the list of files located in a file system directory.
std::string MakeTemporaryDirectoryName(void)
Get the name of a temporary directory.
std::list< std::string > Split(std::string path)
Split a file system path into directories according to the local path separator.
void MakeDirectories(std::string path)
Create all the directories leading to path.
std::string Append(std::string left, std::string right)
Join two file system path elements.
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.
std::string FindSelfDirectory(void)
Get the file system path to the current executable.
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...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
ns3::Singleton declaration and template implementation.
Helper to indent output a specified number of steps.
Indent(int level)
Constructor.
int level
The number of steps.
Container for results from a TestCase.
std::vector< TestCaseFailure > failure
TestCaseFailure records for each child.
bool childrenFailed
true if any child TestCases failed.
SystemWallClockMs clock
Test running time.
Container for details of a test failure.
std::string actual
The actual value returned by the test.
std::string file
The source file.
std::string message
The associated message.
int32_t line
The source line.
TestCaseFailure(std::string _cond, std::string _actual, std::string _limit, std::string _message, std::string _file, int32_t _line)
Constructor.
std::string cond
The name of the condition being tested.
std::string limit
The expected value.
ns3::SystemPath declarations.
ns3::TestCase, ns3::TestSuite, ns3::TestRunner declarations, and NS_TEST_ASSERT macro definitions.