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)
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);
395 m_assertOnFailure (false),
396 m_continueOnFailure (true),
454 bool haveVersion =
false;
455 bool haveLicense =
false;
463 for (std::list<std::string>::const_iterator i = files.begin (); i != files.end (); ++i)
469 else if (*i ==
"LICENSE")
475 return haveVersion && haveLicense;
484 while (!elements.empty ())
491 elements.pop_back ();
493 NS_FATAL_ERROR (
"Could not find source directory from self=" <<
self);
505 typedef std::map <char, std::string> specials_map;
506 specials_map specials;
507 specials[
'<'] =
"<";
508 specials[
'>'] =
">";
509 specials[
'&'] =
"&";
510 specials[
'"'] =
"'";
511 specials[
'\''] =
""";
514 std::size_t length = xml.length ();
516 for (
size_t i = 0; i < length; ++i)
518 char character = xml[i];
520 specials_map::const_iterator it = specials.find (character);
522 if (it == specials.end ())
524 result.push_back (character);
528 result += it->second;
546 for (
int i = 0; i < val.
level; i++)
563 const double MS_PER_SEC = 1000.;
568 std::streamsize oldPrecision = (*os).precision (3);
571 std::string statusString = test->
IsFailed ()?
"FAIL":
"PASS";
574 *os <<
Indent (level) <<
"<Test>" << std::endl;
576 <<
"</Name>" << std::endl;
577 *os <<
Indent (level+1) <<
"<Result>" << statusString <<
"</Result>" << std::endl;
578 *os <<
Indent (level+1) <<
"<Time real=\"" << real <<
"\" user=\"" << user
579 <<
"\" system=\"" << system <<
"\"/>" << std::endl;
583 *os <<
Indent (level+2) <<
"<FailureDetails>" << std::endl
584 <<
Indent (level+3) <<
"<Condition>"
586 <<
Indent (level+3) <<
"<Actual>"
588 <<
Indent (level+3) <<
"<Limit>"
590 <<
Indent (level+3) <<
"<Message>"
592 <<
Indent (level+3) <<
"<File>"
594 <<
Indent (level+3) <<
"<Line>" << failure.
line <<
"</Line>" << std::endl
595 <<
Indent (level+2) <<
"</FailureDetails>" << std::endl;
597 for (uint32_t i = 0; i < test->
m_children.size (); i++)
602 *os <<
Indent (level) <<
"</Test>" << std::endl;
606 *os <<
Indent (level) << statusString <<
" " << test->
GetName ()
607 <<
" " << real <<
" s" << std::endl;
614 for (uint32_t i = 0; i < test->
m_children.size (); i++)
622 (*os).unsetf(std::ios_base::floatfield);
623 (*os).precision (oldPrecision);
630 std::cout <<
"Usage: " << program_name <<
" [OPTIONS]" << std::endl
632 <<
"Options: " << std::endl
633 <<
" --help : print these options" << std::endl
634 <<
" --print-test-name-list : print the list of names of tests available" << std::endl
635 <<
" --list : an alias for --print-test-name-list" << std::endl
636 <<
" --print-test-types : print the type of tests along with their names" << std::endl
637 <<
" --print-test-type-list : print the list of types of tests available" << std::endl
638 <<
" --print-temp-dir : print name of temporary directory before running " << std::endl
639 <<
" the tests" << std::endl
640 <<
" --test-type=TYPE : process only tests of type TYPE" << std::endl
641 <<
" --test-name=NAME : process only test whose name matches NAME" << std::endl
642 <<
" --suite=NAME : an alias (here for compatibility reasons only) " << std::endl
643 <<
" for --test-name=NAME" << std::endl
644 <<
" --assert-on-failure : when a test fails, crash immediately (useful" << std::endl
645 <<
" when running under a debugger" << std::endl
646 <<
" --stop-on-failure : when a test fails, stop immediately" << std::endl
647 <<
" --fullness=FULLNESS : choose the duration of tests to run: QUICK, " << std::endl
648 <<
" EXTENSIVE, or TAKES_FOREVER, where EXTENSIVE " << std::endl
649 <<
" includes QUICK and TAKES_FOREVER includes " << std::endl
650 <<
" QUICK and EXTENSIVE (only QUICK tests are " << std::endl
651 <<
" run by default)" << std::endl
652 <<
" --verbose : print details of test execution" << std::endl
653 <<
" --xml : format test run output as xml" << std::endl
654 <<
" --tempdir=DIR : set temp dir for tests to store output files" << std::endl
655 <<
" --datadir=DIR : set data dir for tests to read reference files" << std::endl
656 <<
" --out=FILE : send test result to FILE instead of standard "
657 <<
"output" << std::endl
658 <<
" --append=FILE : append test result to FILE instead of standard "
659 <<
"output" << std::endl
665 std::list<TestCase *>::const_iterator end,
666 bool printTestType)
const
669 std::map<TestSuite::Type, std::string> label;
678 for (std::list<TestCase *>::const_iterator i = begin; i != end; ++i)
686 std::cout << test->
GetName () << std::endl;
694 std::cout <<
" bvt: Build Verification Tests (to see if build completed successfully)" << std::endl;
695 std::cout <<
" core: Run all TestSuite-based tests (exclude examples)" << std::endl;
696 std::cout <<
" example: Examples (to see if example programs run successfully)" << std::endl;
697 std::cout <<
" performance: Performance Tests (check to see if the system is as fast as expected)" << std::endl;
698 std::cout <<
" system: System Tests (spans modules to check integration of modules)" << std::endl;
699 std::cout <<
" unit: Unit Tests (within modules to check basic functionality)" << std::endl;
703 std::list<TestCase *>
709 std::list<TestCase *> tests;
710 for (uint32_t i = 0; i <
m_suites.size (); ++i)
718 if (testName !=
"" && test->
GetName () != testName)
725 std::vector<TestCase *>::iterator j;
726 for (j = test->m_children.begin (); j != test->m_children.end ();)
732 if (testCase->
m_duration > maximumTestDuration)
738 j = test->m_children.erase (j);
749 tests.push_back (test);
759 std::string testName =
"";
760 std::string testTypeString =
"";
761 std::string out =
"";
762 std::string fullness =
"";
765 bool printTempDir =
false;
766 bool printTestTypeList =
false;
767 bool printTestNameList =
false;
768 bool printTestTypeAndName =
false;
770 char *progname = argv[0];
778 if (strcmp(arg,
"--assert-on-failure") == 0)
782 else if (strcmp (arg,
"--stop-on-failure") == 0)
786 else if (strcmp (arg,
"--verbose") == 0)
790 else if (strcmp (arg,
"--print-temp-dir") == 0)
794 else if (strcmp (arg,
"--update-data") == 0)
798 else if (strcmp (arg,
"--help") == 0)
803 else if (strcmp (arg,
"--print-test-name-list") == 0 ||
804 strcmp(arg,
"--list") == 0)
806 printTestNameList =
true;
808 else if (strcmp (arg,
"--print-test-types") == 0)
810 printTestTypeAndName =
true;
812 else if (strcmp (arg,
"--print-test-type-list") == 0)
814 printTestTypeList =
true;
816 else if (strcmp(arg,
"--append") == 0)
820 else if (strcmp(arg,
"--xml") == 0)
824 else if (strncmp(arg,
"--test-type=", strlen(
"--test-type=")) == 0)
826 testTypeString = arg + strlen(
"--test-type=");
828 else if (strncmp(arg,
"--test-name=", strlen(
"--test-name=")) == 0)
830 testName = arg + strlen(
"--test-name=");
832 else if (strncmp(arg,
"--suite=", strlen(
"--suite=")) == 0)
834 testName = arg + strlen(
"--suite=");
836 else if (strncmp(arg,
"--tempdir=", strlen(
"--tempdir=")) == 0)
840 else if (strncmp(arg,
"--out=", strlen(
"--out=")) == 0)
842 out = arg + strlen(
"--out=");
844 else if (strncmp(arg,
"--fullness=", strlen(
"--fullness=")) == 0)
846 fullness = arg + strlen(
"--fullness=");
849 if (fullness ==
"EXTENSIVE")
853 else if (fullness ==
"TAKES_FOREVER")
871 if (testTypeString ==
"")
875 else if (testTypeString ==
"bvt")
879 else if (testTypeString ==
"core")
883 else if (testTypeString ==
"example")
887 else if (testTypeString ==
"unit")
891 else if (testTypeString ==
"system")
895 else if (testTypeString ==
"performance")
901 std::cout <<
"Invalid test type specified: " << testTypeString << std::endl;
906 std::list<TestCase *> tests =
FilterTests (testName, testType, maximumTestDuration);
916 if (printTestNameList)
921 if (printTestTypeList)
932 ofs =
new std::ofstream();
933 std::ios_base::openmode mode = std::ios_base::out;
936 mode |= std::ios_base::app;
940 mode |= std::ios_base::trunc;
942 ofs->open (out.c_str (), mode);
952 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 "...
This test suite implements a System Test.
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
void MakeDirectories(std::string path)
#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.
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.
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)
std::string GetTempDir(void) const
measure elapsed time in milliseconds
TestCase * m_parent
Pointer to my parent TestCase.
TestRunnerImpl * m_runner
Pointer to the TestRunner.
std::string Join(std::list< std::string >::const_iterator begin, std::list< std::string >::const_iterator end)
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 GetTopLevelSourceDir(void) const
std::list< std::string > ReadFiles(std::string path)
void Start(void)
Start a measure.
bool MustUpdateData(void) const
TestSuite::Type m_type
Type of this TestSuite.
bool MustAssertOnFailure(void) const
This test suite implements a Performance Test.
TestCase(std::string name)
This test suite implements a Build Verification Test.
std::string FindSelfDirectory(void)
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 GetErrorStatus(void) const NS_DEPRECATED
TestDuration
How long the test takes to execute.
bool MustContinueOnFailure(void) const
virtual ~TestCase()
Destructor.
std::string CreateDataDirFilename(std::string filename)
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.
std::string Append(std::string left, std::string right)
std::string MakeTemporaryDirectoryName(void)
void Run(TestRunnerImpl *runner)
Actually run this TestCase.
void AddTestCase(TestCase *testCase) NS_DEPRECATED
Add an individual child TestCase case to this TestCase.
bool IsStatusSuccess(void) const
int64_t GetElapsedUser(void) const
std::string CreateTempDirFilename(std::string filename)
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.
This test suite implements an Example Test.
int64_t GetElapsedSystem(void) const
std::string GetName(void) const
bool IsTopLevelSourceDir(std::string path) const
This test suite implements a Unit Test.
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)
std::list< std::string > Split(std::string path)
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.
std::string m_dataDir
My data directory.
bool MustContinueOnFailure(void) const