48        double max = (std::fabs(x1) > std::fabs(x2)) ? x1 : x2;
 
   49        std::frexp(max, &exponent);
 
   55    delta = std::ldexp(
epsilon, exponent);
 
   58    return difference <= delta && difference >= -delta;
 
 
  101    os << 
"    test=\"" << failure.
cond << 
"\" actual=\"" << failure.
actual << 
"\" limit=\"" 
  102       << failure.
limit << 
"\" in=\"" << failure.
file << 
":" << failure.
line << 
"\" " 
 
  165    int Run(
int argc, 
char* argv[]);
 
  211                           std::list<TestCase*>::const_iterator end,
 
  212                           bool printTestType) 
const;
 
  219    void PrintHelp(
const char* programName) 
const;
 
  231    std::list<TestCase*> 
FilterTests(std::string testName,
 
  233                                     std::vector<TestCase::Duration> filteredTestDuration);
 
 
  249                                 std::string _message,
 
  259    NS_LOG_FUNCTION(
this << _cond << _actual << _limit << _message << _file << _line);
 
 
  309    std::string badchars = 
"\"/\\|?";
 
  316    std::string::size_type badch = testCase->
m_name.find_first_of(badchars);
 
  317    if (badch != std::string::npos)
 
  324        NS_LOG_UNCOND(
"Invalid test name: cannot contain any of '" << badchars
 
  325                                                                   << 
"': " << testCase->
m_name);
 
 
  388    NS_LOG_FUNCTION(
this << cond << actual << limit << message << file << line);
 
  389    m_result->failure.emplace_back(cond, actual, limit, message, file, line);
 
  392    while (current != 
nullptr)
 
 
  403    return m_runner->MustAssertOnFailure();
 
 
  410    return m_runner->MustContinueOnFailure();
 
 
  418    while (current != 
nullptr && current->
m_dataDir.empty())
 
  422    if (current == 
nullptr)
 
  424        NS_FATAL_ERROR(
"No one called SetDataDir prior to calling this function");
 
 
  442        std::list<std::string> names;
 
  444        while (current != 
nullptr)
 
  446            names.push_front(current->
m_name);
 
 
  560    bool haveVersion = 
false;
 
  561    bool haveLicense = 
false;
 
  569    for (
auto i = files.begin(); i != files.end(); ++i)
 
  575        else if (*i == 
"LICENSE")
 
  581    return haveVersion && haveLicense;
 
 
  590    while (!elements.empty())
 
  599    NS_FATAL_ERROR(
"Could not find source directory from self=" << self);
 
 
  612    typedef std::map<char, std::string> specials_map;
 
  613    specials_map specials;
 
  614    specials[
'<'] = 
"<";
 
  615    specials[
'>'] = 
">";
 
  616    specials[
'&'] = 
"&";
 
  617    specials[
'"'] = 
"'";
 
  618    specials[
'\''] = 
""";
 
  621    std::size_t length = xml.length();
 
  623    for (
size_t i = 0; i < length; ++i)
 
  625        char character = xml[i];
 
  627        auto it = specials.find(character);
 
  629        if (it == specials.end())
 
  631            result.push_back(character);
 
 
  668    for (
int i = 0; i < val.
level; i++)
 
 
  679    if (
test->m_result == 
nullptr)
 
  685    const double MS_PER_SEC = 1000.;
 
  686    double real = 
test->m_result->clock.GetElapsedReal() / MS_PER_SEC;
 
  687    double user = 
test->m_result->clock.GetElapsedUser() / MS_PER_SEC;
 
  688    double system = 
test->m_result->clock.GetElapsedSystem() / MS_PER_SEC;
 
  690    std::streamsize oldPrecision = (*os).precision(3);
 
  693    std::string statusString = 
test->IsFailed() ? 
"FAIL" : 
"PASS";
 
  696        *os << 
Indent(level) << 
"<Test>" << std::endl;
 
  698            << 
"</Name>" << std::endl;
 
  699        *os << 
Indent(level + 1) << 
"<Result>" << statusString << 
"</Result>" << std::endl;
 
  700        *os << 
Indent(level + 1) << 
"<Time real=\"" << real << 
"\" user=\"" << user
 
  701            << 
"\" system=\"" << system << 
"\"/>" << std::endl;
 
  702        for (
uint32_t i = 0; i < 
test->m_result->failure.size(); i++)
 
  705            *os << 
Indent(level + 2) << 
"<FailureDetails>" << std::endl
 
  707                << 
"</Condition>" << std::endl
 
  709                << 
"</Actual>" << std::endl
 
  711                << 
"</Limit>" << std::endl
 
  713                << 
"</Message>" << std::endl
 
  715                << 
"</File>" << std::endl
 
  716                << 
Indent(level + 3) << 
"<Line>" << failure.
line << 
"</Line>" << std::endl
 
  717                << 
Indent(level + 2) << 
"</FailureDetails>" << std::endl;
 
  724        *os << 
Indent(level) << 
"</Test>" << std::endl;
 
  728        *os << 
Indent(level) << statusString << 
" " << 
test->GetName() << 
" " << real << 
" s" 
  732            for (
uint32_t i = 0; i < 
test->m_result->failure.size(); i++)
 
  734                *os << 
Indent(level) << 
test->m_result->failure[i] << std::endl;
 
  744    (*os).unsetf(std::ios_base::floatfield);
 
  745    (*os).precision(oldPrecision);
 
 
  753        << 
"Usage: " << program_name << 
" [OPTIONS]" << std::endl
 
  755        << 
"Options: " << std::endl
 
  756        << 
"  --help                   : print these options" << std::endl
 
  757        << 
"  --print-test-name-list   : print the list of names of tests available" << std::endl
 
  758        << 
"  --list                   : an alias for --print-test-name-list" << std::endl
 
  759        << 
"  --print-test-types       : print the type of tests along with their names" 
  761        << 
"  --print-test-type-list   : print the list of types of tests available" << std::endl
 
  762        << 
"  --print-temp-dir         : print name of temporary directory before running " 
  764        << 
"                             the tests" << std::endl
 
  765        << 
"  --test-type=TYPE         : process only tests of type TYPE" << std::endl
 
  766        << 
"  --test-name=NAME         : process only test whose name matches NAME" << std::endl
 
  767        << 
"  --suite=NAME             : an alias (here for compatibility reasons only) " 
  769        << 
"                             for --test-name=NAME" << std::endl
 
  770        << 
"  --assert-on-failure      : when a test fails, crash immediately (useful" << std::endl
 
  771        << 
"                             when running under a debugger" << std::endl
 
  772        << 
"  --stop-on-failure        : when a test fails, stop immediately" << std::endl
 
  773        << 
"  --fullness=FULLNESS      : choose the duration of tests to run: QUICK, " << std::endl
 
  774        << 
"                             EXTENSIVE, or TAKES_FOREVER, where EXTENSIVE " << std::endl
 
  775        << 
"                             includes QUICK and TAKES_FOREVER includes " << std::endl
 
  776        << 
"                             QUICK and EXTENSIVE (only QUICK tests are " << std::endl
 
  777        << 
"                             run by default)" << std::endl
 
  778        << 
"  --only-fullness=FULLNESS : choose the duration of tests to run: QUICK, " << std::endl
 
  779        << 
"                             EXTENSIVE, TAKES_FOREVER (only tests marked " << std::endl
 
  780        << 
"                             with fullness will be executed)" << std::endl
 
  781        << 
"  --verbose                : print details of test execution" << std::endl
 
  782        << 
"  --xml                    : format test run output as xml" << std::endl
 
  783        << 
"  --tempdir=DIR            : set temp dir for tests to store output files" << std::endl
 
  784        << 
"  --datadir=DIR            : set data dir for tests to read reference files" 
  786        << 
"  --out=FILE               : send test result to FILE instead of standard output" 
  788        << 
"  --append=FILE            : append test result to FILE instead of standard output" 
 
  794                                  std::list<TestCase*>::const_iterator end,
 
  795                                  bool printTestType)
 const 
  798    std::map<TestSuite::Type, std::string> label;
 
  806    for (
auto i = begin; i != end; ++i)
 
  812            std::cout << label[
test->GetTestType()];
 
  814        std::cout << 
test->GetName() << std::endl;
 
 
  822    std::cout << 
"  core:            Run all TestSuite-based tests (exclude examples)" << std::endl
 
  823              << 
"  example:         Examples (to see if example programs run successfully)" 
  825              << 
"  example-as-test: Examples (which are tested against reference outputs)" 
  827              << 
"  performance:     Performance Tests (check to see if the system is as fast as " 
  830              << 
"  system:          System Tests (spans modules to check integration of modules)" 
  832              << 
"  unit:            Unit Tests (within modules to check basic functionality)" 
 
  839                            std::vector<TestCase::Duration> filteredTestDuration)
 
  842    std::list<TestCase*> 
tests;
 
  851        if (!testName.empty() && 
test->GetName() != testName)
 
  858        for (
auto j = 
test->m_children.begin(); j != 
test->m_children.end();)
 
  864            auto it = std::find(filteredTestDuration.begin(),
 
  865                                filteredTestDuration.end(),
 
  867            if (it == filteredTestDuration.end())
 
  873                j = 
test->m_children.erase(j);
 
 
  893    std::string testName = 
"";
 
  894    std::string testTypeString = 
"";
 
  895    std::string out = 
"";
 
  896    std::string fullness = 
"";
 
  897    std::string onlyFullness = 
"";
 
  900    bool printTempDir = 
false;
 
  901    bool printTestTypeList = 
false;
 
  902    bool printTestNameList = 
false;
 
  903    bool printTestTypeAndName = 
false;
 
  905    char* progname = argv[0];
 
  910    while (*argi != 
nullptr)
 
  912        std::string arg = *argi;
 
  914        if (arg == 
"--assert-on-failure")
 
  918        else if (arg == 
"--stop-on-failure")
 
  922        else if (arg == 
"--verbose")
 
  926        else if (arg == 
"--print-temp-dir")
 
  930        else if (arg == 
"--update-data")
 
  934        else if (arg == 
"--print-test-name-list" || arg == 
"--list")
 
  936            printTestNameList = 
true;
 
  938        else if (arg == 
"--print-test-types")
 
  940            printTestTypeAndName = 
true;
 
  942        else if (arg == 
"--print-test-type-list")
 
  944            printTestTypeList = 
true;
 
  946        else if (arg == 
"--append")
 
  950        else if (arg == 
"--xml")
 
  954        else if (arg.find(
"--test-type=") != std::string::npos)
 
  956            testTypeString = arg.substr(arg.find_first_of(
'=') + 1);
 
  958        else if (arg.find(
"--test-name=") != std::string::npos ||
 
  959                 arg.find(
"--suite=") != std::string::npos)
 
  961            testName = arg.substr(arg.find_first_of(
'=') + 1);
 
  963        else if (arg.find(
"--tempdir=") != std::string::npos)
 
  965            m_tempDir = arg.substr(arg.find_first_of(
'=') + 1);
 
  967        else if (arg.find(
"--out=") != std::string::npos)
 
  969            out = arg.substr(arg.find_first_of(
'=') + 1);
 
  971        else if (arg.find(
"--fullness=") != std::string::npos)
 
  973            fullness = arg.substr(arg.find_first_of(
'=') + 1);
 
  976            if (fullness == 
"QUICK")
 
  980            else if (fullness == 
"EXTENSIVE")
 
  984            else if (fullness == 
"TAKES_FOREVER")
 
  997        else if (arg.find(
"--only-fullness=") != std::string::npos)
 
  999            onlyFullness = arg.substr(arg.find_first_of(
'=') + 1);
 
 1002            if (onlyFullness == 
"QUICK")
 
 1006            else if (onlyFullness == 
"EXTENSIVE")
 
 1010            else if (onlyFullness == 
"TAKES_FOREVER")
 
 1030    if (testTypeString.empty() || testTypeString == 
"core")
 
 1034    else if (testTypeString == 
"example")
 
 1038    else if (testTypeString == 
"unit")
 
 1042    else if (testTypeString == 
"system")
 
 1046    else if (testTypeString == 
"performance")
 
 1052        std::cout << 
"Invalid test type specified: " << testTypeString << std::endl;
 
 1057    if (!fullness.empty() && !onlyFullness.empty())
 
 1059        std::cout << 
"Invalid simultaneous use of '--fullness' and '--only-fullness'. " 
 1060                  << 
"Use only one of them." << std::endl;
 
 1065    std::list<TestCase*> 
tests = 
FilterTests(testName, testType, filteredTestDuration);
 
 1075    if (printTestNameList)
 
 1080    if (printTestTypeList)
 
 1090        ofs = 
new std::ofstream();
 
 1091        std::ios_base::openmode mode = std::ios_base::out;
 
 1094            mode |= std::ios_base::app;
 
 1098            mode |= std::ios_base::trunc;
 
 1100        ofs->open(out, mode);
 
 1109    bool failed = 
false;
 
 1112        std::cerr << 
"Error:  no tests match the requested string" << std::endl;
 
 1115    else if (
tests.size() > 1)
 
 1117        std::cerr << 
"Error:  tests should be launched separately (one at a time)" << std::endl;
 
 1121    for (
auto i = 
tests.begin(); i != 
tests.end(); ++i)
 
 1125#ifdef ENABLE_DES_METRICS 
 1134            std::string testname = 
test->GetName();
 
 1137            std::vector<std::string> desargs;
 
 1138            desargs.push_back(testname);
 
 1139            desargs.push_back(runner);
 
 1140            for (
int i = 1; i < argc; ++i)
 
 1142                desargs.push_back(argv[i]);
 
 1145            DesMetrics::Get()->Initialize(desargs, 
m_tempDir);
 
 1151        if (
test->IsFailed())
 
 1166    return failed ? 1 : 0;
 
 
 1184        return os << 
"UNIT";
 
 1186        return os << 
"SYSTEM";
 
 1188        return os << 
"EXAMPLE";
 
 1190        return os << 
"PERFORMANCE";
 
 1192    return os << 
"UNKNOWN(" << 
static_cast<uint32_t>(type) << 
")";
 
 
 1201        return os << 
"QUICK";
 
 1203        return os << 
"EXTENSIVE";
 
 1205        return os << 
"TAKES_FOREVER";
 
 1207    return os << 
"UNKNOWN(" << 
static_cast<uint32_t>(duration) << 
")";
 
 
NS_ABORT_x macro definitions.
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
static void ResetNextStreamIndex()
Resets the global stream index counter.
Singleton(const Singleton< TestRunnerImpl > &)=delete
static TestRunnerImpl * Get()
Measure elapsed wall clock time in milliseconds.
std::string m_name
TestCase name.
bool MustContinueOnFailure() const
Check if this run should continue on failure.
bool IsStatusFailure() const
Check if any tests failed.
std::string m_dataDir
My data directory.
std::string CreateDataDirFilename(std::string filename)
Construct the full path to a file in the data directory.
TestCase * m_parent
Pointer to my parent TestCase.
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Result * m_result
Results data.
bool IsStatusSuccess() const
Check if all tests passed.
virtual void DoSetup()
Implementation to do any local setup required for this TestCase.
virtual ~TestCase()
Destructor.
Duration
How long the test takes to execute.
@ EXTENSIVE
Medium length test.
@ TAKES_FOREVER
Very long running test.
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 TestCase.
bool MustAssertOnFailure() const
Check if this run should assert on failure.
void SetDataDir(std::string directory)
Set the data directory where reference trace files can be found.
virtual void DoTeardown()
Implementation to do any local setup required for this TestCase.
void Run(TestRunnerImpl *runner)
Executes DoSetup(), DoRun(), and DoTeardown() for the TestCase.
TestCase(const TestCase &)=delete
virtual void DoRun()=0
Implementation to actually run this TestCase.
std::string GetName() const
friend class TestRunnerImpl
Needs access to the TestCase data members.
Duration m_duration
TestCase duration.
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.
bool IsFailed() const
Check if any tests failed.
std::vector< TestCase * > m_children
Vector of my children.
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.
std::string ReplaceXmlSpecialCharacters(std::string xml) const
Clean up characters not allowed in XML.
bool MustUpdateData() const
Check if this run should update the reference data.
bool IsTopLevelSourceDir(std::string path) const
Check if this is the root of the source tree.
bool m_continueOnFailure
true if we should continue on failure.
bool m_updateData
true if we should update reference data.
std::list< TestCase * > FilterTests(std::string testName, TestSuite::Type testType, std::vector< TestCase::Duration > filteredTestDuration)
Generate the list of tests matching the constraints.
std::string m_tempDir
The temporary directory.
std::string GetTempDir() const
Get the path to temporary directory.
void PrintReport(TestCase *test, std::ostream *os, bool xml, int level)
Print the test report.
std::vector< TestSuite * > TestSuiteVector
Container type for the test.
bool MustContinueOnFailure() const
Check if this run should continue on failure.
int Run(int argc, char *argv[])
Run the requested suite of tests, according to the given command line arguments.
bool MustAssertOnFailure() const
Check if this run should assert 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.
std::string GetTopLevelSourceDir() const
Get the path to the root of the source tree.
void PrintTestTypeList() const
Print the list of test types.
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.
@ PERFORMANCE
This test suite implements a Performance Test.
@ ALL
Token to represent all tests.
@ EXAMPLE
This test suite implements an Example Test.
@ UNIT
This test suite implements a Unit Test.
@ SYSTEM
This test suite implements a System Test.
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
TestSuite::Type m_type
Type of this TestSuite.
void DoRun() override
Implementation to actually run this TestCase.
TestSuite::Type GetTestType()
get the kind of test this test suite implements
Declaration of the various ns3::Config functions and classes.
ns3::DesMetrics declaration.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
void Reset()
Reset the initial value of every attribute as well as the value of every global to what they were bef...
#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::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 MakeTemporaryDirectoryName()
Get the name of a temporary directory.
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 CreateValidSystemPath(const std::string path)
Replace incompatible characters in a path, to get a path compatible with different file systems.
std::string FindSelfDirectory()
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...
Namespace for test files, TestCases and TestSuites.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
-ns3 Test suite for the ns3 wrapper script
ns3::RngSeedManager declaration.
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.