40 double delta, difference;
46 double max = (std::fabs (x1) > std::fabs (x2)) ? x1 : x2;
47 (void)std::frexp (max, &exponent);
53 delta = std::ldexp (epsilon, exponent);
56 if (difference > delta || difference < -delta)
66 std::string _limit, std::string _message,
67 std::string _file, int32_t _line);
77 os <<
" test=\"" << failure.
cond
78 <<
"\" actual=\"" << failure.
actual
79 <<
"\" limit=\"" << failure.
limit
80 <<
"\" in=\"" << failure.
file
81 <<
":" << failure.
line
102 std::string limit, std::string message,
103 std::string file, int32_t line);
110 int Run (
int argc,
char *argv[]);
122 std::list<TestCase *>::const_iterator end,
123 bool printTestType)
const;
125 void PrintHelp (
const char *programName)
const;
126 std::list<TestCase *>
FilterTests (std::string testName,
144 std::string _limit, std::string _message,
145 std::string _file, int32_t _line)
146 : cond (_cond), actual (_actual), limit (_limit),
147 message (_message), file (_file), line (_line)
149 NS_LOG_FUNCTION (
this << _cond << _actual << _limit << _message << _file << _line);
152 : childrenFailed (false)
176 for (std::vector<TestCase *>::const_iterator i =
m_children.begin (); i !=
m_children.end (); ++i)
193 std::string::size_type slash, antislash;
194 slash = testCase->
m_name.find (
"/");
195 antislash = testCase->
m_name.find (
"\\");
196 if (slash != std::string::npos || antislash != std::string::npos)
198 std::string fullname = testCase->
m_name;
202 fullname = current->
m_name +
"/" + fullname;
205 if (slash != std::string::npos)
207 NS_FATAL_ERROR (
"Invalid test name: cannot contain slashes: \"" << fullname <<
"\"");
209 if (antislash != std::string::npos)
211 NS_FATAL_ERROR (
"Invalid test name: cannot contain antislashes: \"" << fullname <<
"\"");
231 for (std::vector<TestCase *>::const_iterator i =
m_children.begin (); i !=
m_children.end (); ++i)
260 std::string limit, std::string message,
261 std::string file, int32_t line)
263 NS_LOG_FUNCTION (
this << cond << actual << limit << message << file << line);
265 message, file, line));
293 while (current != 0 && current->
m_dataDir ==
"")
299 NS_FATAL_ERROR (
"No one called SetDataDir prior to calling this function");
316 std::list<std::string> names;
320 names.push_front (current->
m_name);
383 m_assertOnFailure (false),
384 m_continueOnFailure (true),
442 bool haveVersion =
false;
443 bool haveLicense =
false;
451 for (std::list<std::string>::const_iterator i = files.begin (); i != files.end (); ++i)
457 else if (*i ==
"LICENSE")
463 return haveVersion && haveLicense;
472 while (!elements.empty ())
479 elements.pop_back ();
481 NS_FATAL_ERROR (
"Could not find source directory from self=" <<
self);
493 typedef std::map <char, std::string> specials_map;
494 specials_map specials;
495 specials[
'<'] =
"<";
496 specials[
'>'] =
">";
497 specials[
'&'] =
"&";
498 specials[
'"'] =
"'";
499 specials[
'\''] =
""";
502 std::size_t length = xml.length ();
504 for (
size_t i = 0; i < length; ++i)
506 char character = xml[i];
508 specials_map::const_iterator it = specials.find (character);
510 if (it == specials.end ())
512 result.push_back (character);
516 result += it->second;
534 for (
int i = 0; i < val.
level; i++)
551 const double MS_PER_SEC = 1000.;
556 std::streamsize oldPrecision = (*os).precision (3);
559 std::string statusString = test->
IsFailed ()?
"FAIL":
"PASS";
562 *os <<
Indent (level) <<
"<Test>" << std::endl;
564 <<
"</Name>" << std::endl;
565 *os <<
Indent (level+1) <<
"<Result>" << statusString <<
"</Result>" << std::endl;
566 *os <<
Indent (level+1) <<
"<Time real=\"" << real <<
"\" user=\"" << user
567 <<
"\" system=\"" << system <<
"\"/>" << std::endl;
571 *os <<
Indent (level+2) <<
"<FailureDetails>" << std::endl
572 <<
Indent (level+3) <<
"<Condition>"
574 <<
Indent (level+3) <<
"<Actual>"
576 <<
Indent (level+3) <<
"<Limit>"
578 <<
Indent (level+3) <<
"<Message>"
580 <<
Indent (level+3) <<
"<File>"
582 <<
Indent (level+3) <<
"<Line>" << failure.
line <<
"</Line>" << std::endl
583 <<
Indent (level+2) <<
"</FailureDetails>" << std::endl;
585 for (uint32_t i = 0; i < test->
m_children.size (); i++)
590 *os <<
Indent (level) <<
"</Test>" << std::endl;
594 *os <<
Indent (level) << statusString <<
" " << test->
GetName ()
595 <<
" " << real <<
" s" << std::endl;
602 for (uint32_t i = 0; i < test->
m_children.size (); i++)
610 (*os).unsetf(std::ios_base::floatfield);
611 (*os).precision (oldPrecision);
618 std::cout <<
"Usage: " << program_name <<
" [OPTIONS]" << std::endl
620 <<
"Options: " << std::endl
621 <<
" --help : print these options" << std::endl
622 <<
" --print-test-name-list : print the list of names of tests available" << std::endl
623 <<
" --list : an alias for --print-test-name-list" << std::endl
624 <<
" --print-test-types : print the type of tests along with their names" << std::endl
625 <<
" --print-test-type-list : print the list of types of tests available" << std::endl
626 <<
" --print-temp-dir : print name of temporary directory before running " << std::endl
627 <<
" the tests" << std::endl
628 <<
" --test-type=TYPE : process only tests of type TYPE" << std::endl
629 <<
" --test-name=NAME : process only test whose name matches NAME" << std::endl
630 <<
" --suite=NAME : an alias (here for compatibility reasons only) " << std::endl
631 <<
" for --test-name=NAME" << std::endl
632 <<
" --assert-on-failure : when a test fails, crash immediately (useful" << std::endl
633 <<
" when running under a debugger" << std::endl
634 <<
" --stop-on-failure : when a test fails, stop immediately" << std::endl
635 <<
" --fullness=FULLNESS : choose the duration of tests to run: QUICK, " << std::endl
636 <<
" EXTENSIVE, or TAKES_FOREVER, where EXTENSIVE " << std::endl
637 <<
" includes QUICK and TAKES_FOREVER includes " << std::endl
638 <<
" QUICK and EXTENSIVE (only QUICK tests are " << std::endl
639 <<
" run by default)" << std::endl
640 <<
" --verbose : print details of test execution" << std::endl
641 <<
" --xml : format test run output as xml" << std::endl
642 <<
" --tempdir=DIR : set temp dir for tests to store output files" << std::endl
643 <<
" --datadir=DIR : set data dir for tests to read reference files" << std::endl
644 <<
" --out=FILE : send test result to FILE instead of standard "
645 <<
"output" << std::endl
646 <<
" --append=FILE : append test result to FILE instead of standard "
647 <<
"output" << std::endl
653 std::list<TestCase *>::const_iterator end,
654 bool printTestType)
const
657 std::map<TestSuite::Type, std::string> label;
666 for (std::list<TestCase *>::const_iterator i = begin; i != end; ++i)
674 std::cout << test->
GetName () << std::endl;
682 std::cout <<
" bvt: Build Verification Tests (to see if build completed successfully)" << std::endl;
683 std::cout <<
" core: Run all TestSuite-based tests (exclude examples)" << std::endl;
684 std::cout <<
" example: Examples (to see if example programs run successfully)" << std::endl;
685 std::cout <<
" performance: Performance Tests (check to see if the system is as fast as expected)" << std::endl;
686 std::cout <<
" system: System Tests (spans modules to check integration of modules)" << std::endl;
687 std::cout <<
" unit: Unit Tests (within modules to check basic functionality)" << std::endl;
691 std::list<TestCase *>
697 std::list<TestCase *> tests;
698 for (uint32_t i = 0; i <
m_suites.size (); ++i)
706 if (testName !=
"" && test->
GetName () != testName)
713 std::vector<TestCase *>::iterator j;
714 for (j = test->m_children.begin (); j != test->m_children.end ();)
720 if (testCase->
m_duration > maximumTestDuration)
726 j = test->m_children.erase (j);
737 tests.push_back (test);
747 std::string testName =
"";
748 std::string testTypeString =
"";
749 std::string out =
"";
750 std::string fullness =
"";
753 bool printTempDir =
false;
754 bool printTestTypeList =
false;
755 bool printTestNameList =
false;
756 bool printTestTypeAndName =
false;
758 char *progname = argv[0];
766 if (strcmp(arg,
"--assert-on-failure") == 0)
770 else if (strcmp (arg,
"--stop-on-failure") == 0)
774 else if (strcmp (arg,
"--verbose") == 0)
778 else if (strcmp (arg,
"--print-temp-dir") == 0)
782 else if (strcmp (arg,
"--update-data") == 0)
786 else if (strcmp (arg,
"--help") == 0)
791 else if (strcmp (arg,
"--print-test-name-list") == 0 ||
792 strcmp(arg,
"--list") == 0)
794 printTestNameList =
true;
796 else if (strcmp (arg,
"--print-test-types") == 0)
798 printTestTypeAndName =
true;
800 else if (strcmp (arg,
"--print-test-type-list") == 0)
802 printTestTypeList =
true;
804 else if (strcmp(arg,
"--append") == 0)
808 else if (strcmp(arg,
"--xml") == 0)
812 else if (strncmp(arg,
"--test-type=", strlen(
"--test-type=")) == 0)
814 testTypeString = arg + strlen(
"--test-type=");
816 else if (strncmp(arg,
"--test-name=", strlen(
"--test-name=")) == 0)
818 testName = arg + strlen(
"--test-name=");
820 else if (strncmp(arg,
"--suite=", strlen(
"--suite=")) == 0)
822 testName = arg + strlen(
"--suite=");
824 else if (strncmp(arg,
"--tempdir=", strlen(
"--tempdir=")) == 0)
828 else if (strncmp(arg,
"--out=", strlen(
"--out=")) == 0)
830 out = arg + strlen(
"--out=");
832 else if (strncmp(arg,
"--fullness=", strlen(
"--fullness=")) == 0)
834 fullness = arg + strlen(
"--fullness=");
837 if (fullness ==
"EXTENSIVE")
841 else if (fullness ==
"TAKES_FOREVER")
859 if (testTypeString ==
"")
863 else if (testTypeString ==
"bvt")
867 else if (testTypeString ==
"core")
871 else if (testTypeString ==
"example")
875 else if (testTypeString ==
"unit")
879 else if (testTypeString ==
"system")
883 else if (testTypeString ==
"performance")
889 std::cout <<
"Invalid test type specified: " << testTypeString << std::endl;
894 std::list<TestCase *> tests =
FilterTests (testName, testType, maximumTestDuration);
904 if (printTestNameList)
909 if (printTestTypeList)
920 ofs =
new std::ofstream();
921 std::ios_base::openmode mode = std::ios_base::out;
924 mode |= std::ios_base::app;
928 mode |= std::ios_base::trunc;
930 ofs->open (out.c_str (), mode);
940 if (tests.size () == 0)
942 std::cerr <<
"Error: no tests match the requested string" << std::endl;
945 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.
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.
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.