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);
601 typedef std::map <char, std::string> specials_map;
602 specials_map specials;
603 specials[
'<'] =
"<";
604 specials[
'>'] =
">";
605 specials[
'&'] =
"&";
606 specials[
'"'] =
"'";
607 specials[
'\''] =
""";
610 std::size_t length = xml.length ();
612 for (
size_t i = 0; i < length; ++i)
614 char character = xml[i];
616 specials_map::const_iterator it = specials.find (character);
618 if (it == specials.end ())
620 result.push_back (character);
624 result += it->second;
654 for (
int i = 0; i < val.
level; i++)
665 if (test->m_result == 0)
671 const double MS_PER_SEC = 1000.;
672 double real = test->m_result->clock.GetElapsedReal () / MS_PER_SEC;
673 double user = test->m_result->clock.GetElapsedUser () / MS_PER_SEC;
674 double system = test->m_result->clock.GetElapsedSystem () / MS_PER_SEC;
676 std::streamsize oldPrecision = (*os).precision (3);
679 std::string statusString = test->IsFailed ()?
"FAIL":
"PASS";
682 *os <<
Indent (level) <<
"<Test>" << std::endl;
684 <<
"</Name>" << std::endl;
685 *os <<
Indent (level+1) <<
"<Result>" << statusString <<
"</Result>" << std::endl;
686 *os <<
Indent (level+1) <<
"<Time real=\"" << real <<
"\" user=\"" << user
687 <<
"\" system=\"" << system <<
"\"/>" << std::endl;
688 for (uint32_t i = 0; i < test->m_result->failure.size (); i++)
691 *os <<
Indent (level+2) <<
"<FailureDetails>" << std::endl
692 <<
Indent (level+3) <<
"<Condition>" 694 <<
Indent (level+3) <<
"<Actual>" 696 <<
Indent (level+3) <<
"<Limit>" 698 <<
Indent (level+3) <<
"<Message>" 700 <<
Indent (level+3) <<
"<File>" 702 <<
Indent (level+3) <<
"<Line>" << failure.
line <<
"</Line>" << std::endl
703 <<
Indent (level+2) <<
"</FailureDetails>" << std::endl;
705 for (uint32_t i = 0; i < test->m_children.size (); i++)
707 TestCase *child = test->m_children[i];
710 *os <<
Indent (level) <<
"</Test>" << std::endl;
714 *os <<
Indent (level) << statusString <<
" " << test->GetName ()
715 <<
" " << real <<
" s" << std::endl;
718 for (uint32_t i = 0; i < test->m_result->failure.size (); i++)
720 *os <<
Indent (level) << test->m_result->failure[i] << std::endl;
722 for (uint32_t i = 0; i < test->m_children.size (); i++)
724 TestCase *child = test->m_children[i];
730 (*os).unsetf(std::ios_base::floatfield);
731 (*os).precision (oldPrecision);
738 std::cout <<
"Usage: " << program_name <<
" [OPTIONS]" << std::endl
740 <<
"Options: " << std::endl
741 <<
" --help : print these options" << std::endl
742 <<
" --print-test-name-list : print the list of names of tests available" << std::endl
743 <<
" --list : an alias for --print-test-name-list" << std::endl
744 <<
" --print-test-types : print the type of tests along with their names" << std::endl
745 <<
" --print-test-type-list : print the list of types of tests available" << std::endl
746 <<
" --print-temp-dir : print name of temporary directory before running " << std::endl
747 <<
" the tests" << std::endl
748 <<
" --test-type=TYPE : process only tests of type TYPE" << std::endl
749 <<
" --test-name=NAME : process only test whose name matches NAME" << std::endl
750 <<
" --suite=NAME : an alias (here for compatibility reasons only) " << std::endl
751 <<
" for --test-name=NAME" << std::endl
752 <<
" --assert-on-failure : when a test fails, crash immediately (useful" << std::endl
753 <<
" when running under a debugger" << std::endl
754 <<
" --stop-on-failure : when a test fails, stop immediately" << std::endl
755 <<
" --fullness=FULLNESS : choose the duration of tests to run: QUICK, " << std::endl
756 <<
" EXTENSIVE, or TAKES_FOREVER, where EXTENSIVE " << std::endl
757 <<
" includes QUICK and TAKES_FOREVER includes " << std::endl
758 <<
" QUICK and EXTENSIVE (only QUICK tests are " << std::endl
759 <<
" run by default)" << std::endl
760 <<
" --verbose : print details of test execution" << std::endl
761 <<
" --xml : format test run output as xml" << std::endl
762 <<
" --tempdir=DIR : set temp dir for tests to store output files" << std::endl
763 <<
" --datadir=DIR : set data dir for tests to read reference files" << std::endl
764 <<
" --out=FILE : send test result to FILE instead of standard " 765 <<
"output" << std::endl
766 <<
" --append=FILE : append test result to FILE instead of standard " 767 <<
"output" << std::endl
773 std::list<TestCase *>::const_iterator end,
774 bool printTestType)
const 777 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 <<
" bvt: Build Verification Tests (to see if build completed successfully)" << std::endl;
803 std::cout <<
" core: Run all TestSuite-based tests (exclude examples)" << std::endl;
804 std::cout <<
" example: Examples (to see if example programs run successfully)" << std::endl;
805 std::cout <<
" performance: Performance Tests (check to see if the system is as fast as expected)" << std::endl;
806 std::cout <<
" system: System Tests (spans modules to check integration of modules)" << std::endl;
807 std::cout <<
" unit: Unit Tests (within modules to check basic functionality)" << std::endl;
811 std::list<TestCase *>
817 std::list<TestCase *> tests;
818 for (uint32_t i = 0; i <
m_suites.size (); ++i)
821 if (testType !=
TestSuite::ALL && test->GetTestType () != testType)
826 if (testName !=
"" && test->GetName () != testName)
833 std::vector<TestCase *>::iterator j;
834 for (j = test->m_children.begin (); j != test->m_children.end ();)
840 if (testCase->
m_duration > maximumTestDuration)
846 j = test->m_children.erase (j);
857 tests.push_back (test);
867 std::string testName =
"";
868 std::string testTypeString =
"";
869 std::string out =
"";
870 std::string fullness =
"";
873 bool printTempDir =
false;
874 bool printTestTypeList =
false;
875 bool printTestNameList =
false;
876 bool printTestTypeAndName =
false;
878 char *progname = argv[0];
887 if (strcmp(arg,
"--assert-on-failure") == 0)
891 else if (strcmp (arg,
"--stop-on-failure") == 0)
895 else if (strcmp (arg,
"--verbose") == 0)
899 else if (strcmp (arg,
"--print-temp-dir") == 0)
903 else if (strcmp (arg,
"--update-data") == 0)
907 else if (strcmp (arg,
"--help") == 0)
912 else if (strcmp (arg,
"--print-test-name-list") == 0 ||
913 strcmp(arg,
"--list") == 0)
915 printTestNameList =
true;
917 else if (strcmp (arg,
"--print-test-types") == 0)
919 printTestTypeAndName =
true;
921 else if (strcmp (arg,
"--print-test-type-list") == 0)
923 printTestTypeList =
true;
925 else if (strcmp(arg,
"--append") == 0)
929 else if (strcmp(arg,
"--xml") == 0)
933 else if (strncmp(arg,
"--test-type=", strlen(
"--test-type=")) == 0)
935 testTypeString = arg + strlen(
"--test-type=");
937 else if (strncmp(arg,
"--test-name=", strlen(
"--test-name=")) == 0)
939 testName = arg + strlen(
"--test-name=");
941 else if (strncmp(arg,
"--suite=", strlen(
"--suite=")) == 0)
943 testName = arg + strlen(
"--suite=");
945 else if (strncmp(arg,
"--tempdir=", strlen(
"--tempdir=")) == 0)
949 else if (strncmp(arg,
"--out=", strlen(
"--out=")) == 0)
951 out = arg + strlen(
"--out=");
953 else if (strncmp(arg,
"--fullness=", strlen(
"--fullness=")) == 0)
955 fullness = arg + strlen(
"--fullness=");
958 if (fullness ==
"QUICK")
962 else if (fullness ==
"EXTENSIVE")
966 else if (fullness ==
"TAKES_FOREVER")
986 if (testTypeString ==
"")
990 else if (testTypeString ==
"bvt")
994 else if (testTypeString ==
"core")
998 else if (testTypeString ==
"example")
1002 else if (testTypeString ==
"unit")
1006 else if (testTypeString ==
"system")
1010 else if (testTypeString ==
"performance")
1016 std::cout <<
"Invalid test type specified: " << testTypeString << std::endl;
1021 std::list<TestCase *> tests =
FilterTests (testName, testType, maximumTestDuration);
1031 if (printTestNameList)
1036 if (printTestTypeList)
1047 ofs =
new std::ofstream();
1048 std::ios_base::openmode mode = std::ios_base::out;
1051 mode |= std::ios_base::app;
1055 mode |= std::ios_base::trunc;
1057 ofs->open (out.c_str (), mode);
1066 bool failed =
false;
1067 if (tests.size () == 0)
1069 std::cerr <<
"Error: no tests match the requested string" << std::endl;
1072 for (std::list<TestCase *>::const_iterator i = tests.begin (); i != tests.end (); ++i)
1076 #ifdef ENABLE_DES_METRICS 1085 std::string testname = test->GetName ();
1088 std::vector<std::string> desargs;
1089 desargs.push_back (testname);
1090 desargs.push_back (runner);
1091 for (
int i = 1; i < argc; ++i)
1093 desargs.push_back (argv[i]);
1102 if (test->IsFailed ())
std::string message
The associated message.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
Helper to indent output a specified number of steps.
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 "...
ns3::Singleton declaration and template implementation.
This test suite implements a System Test.
bool IsStatusFailure(void) const
Check if any tests failed.
TestCaseFailure(std::string _cond, std::string _actual, std::string _limit, std::string _message, std::string _file, int32_t _line)
Constructor.
SystemWallClockMs clock
Test running time.
Container for results from a TestCase.
void AddTestSuite(TestSuite *testSuite)
Add a new top-level 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 m_continueOnFailure
true if we should continue on failure.
bool MustAssertOnFailure(void) const
Check if this run should assert on failure.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
ns3::TestCase, ns3::TestSuite, ns3::TestRunner declarations, and NS_TEST_ASSERT macro definitions...
enum TestDuration m_duration
TestCase duration.
static TestRunnerImpl * Get(void)
Get a pointer to the singleton instance.
TestSuiteVector m_suites
The list of tests.
void PrintReport(TestCase *test, std::ostream *os, bool xml, int level)
Print the test report.
ns3::DesMetrics declaration.
TestSuite(std::string name, Type type=UNIT)
Construct 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.
bool MustContinueOnFailure(void) const
Check if this run should continue on failure.
bool MustAssertOnFailure(void) const
Check if this run should assert on failure.
virtual void DoRun(void)
Implementation to actually run this TestCase.
bool IsStatusSuccess(void) const
Check if all tests passed.
std::string GetTempDir(void) const
Get the path to temporary directory.
std::list< TestCase * > FilterTests(std::string testName, enum TestSuite::Type testType, enum TestCase::TestDuration maximumTestDuration)
Generate the list of tests matching the constraints.
ns3::SystemPath declarations.
TestRunnerImpl()
Constructor.
void Initialize(std::vector< std::string > args, std::string outDir="")
Open the DesMetrics trace file and print the header.
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.
void PrintTestTypeList(void) const
Print the list of test types.
TestRunnerImpl * m_runner
Pointer to the TestRunner.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
std::string cond
The name of the condition being tested.
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
std::string MakeTemporaryDirectoryName(void)
Get the name of a temporary directory.
bool IsTopLevelSourceDir(std::string path) const
Check if this is the root of the source tree.
std::list< std::string > ReadFiles(std::string path)
Get the list of files located in a file system directory.
bool childrenFailed
true if any child TestCases failed.
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...
std::string m_tempDir
The temporary directory.
void Start(void)
Start a measure.
TestSuite::Type m_type
Type of this TestSuite.
std::string GetTopLevelSourceDir(void) const
Get the path to the root of the source tree.
This test suite implements a Performance Test.
TestCase(std::string name)
Constructor.
This test suite implements a Build Verification Test.
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
TestDuration
How long the test takes to execute.
virtual ~TestCase()
Destructor.
bool m_updateData
true if we should update reference data.
int32_t line
The source line.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::string CreateDataDirFilename(std::string filename)
Construct the full path to a file in the data directory.
virtual void DoRun(void)=0
Implementation to actually run this TestCase.
struct Result * m_result
Results data.
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.
TestCase * GetParent() const
Get the parent of this TestCsse.
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionally.
bool m_verbose
Produce verbose output.
void Run(TestRunnerImpl *runner)
Actually run this TestCase.
void MakeDirectories(std::string path)
Create all the directories leading to path.
Indent(int level)
Constructor.
bool MustContinueOnFailure(void) const
Check if this run should continue on failure.
std::string ReplaceXmlSpecialCharacters(std::string xml) const
Clean up characters not allowed in XML.
std::string actual
The actual value returned by the test.
std::string FindSelfDirectory(void)
Get the file system path to the current executable.
std::string GetName(void) const
std::string file
The source file.
std::string CreateTempDirFilename(std::string filename)
Construct the full path to a file in a temporary directory.
std::string Append(std::string left, std::string right)
Join two file system path elements.
void SetDataDir(std::string directory)
Set the data directory where reference trace files can be found.
std::vector< TestSuite * > TestSuiteVector
Container type for the test.
std::vector< TestCase * > m_children
Vector of my children.
This test suite implements an Example Test.
bool MustUpdateData(void) const
Check if this run should update the reference data.
Container for details of a test failure.
int level
The number of steps.
This test suite implements a Unit Test.
TestSuite::Type GetTestType(void)
get the kind of test this test suite implements
std::vector< TestCaseFailure > failure
TestCaseFailure records for each child.
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, according to the given command line arguments.
int Run(int argc, char *argv[])
Run the requested suite of tests, according to the given command line arguments. ...
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 m_name
TestCase name.
bool IsFailed(void) const
Check if any tests failed.
std::string m_dataDir
My data directory.
bool m_assertOnFailure
true if we should assert on failure.
void PrintHelp(const char *programName) const
Print the help text.
NS_ABORT_x macro definitions.
std::string limit
The expected value.