A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
test.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 University of Washington
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18#ifndef NS3_TEST_H
19#define NS3_TEST_H
20
22
23#include <fstream>
24#include <iostream>
25#include <limits>
26#include <list>
27#include <sstream>
28#include <stdint.h>
29#include <string>
30#include <vector>
31
54namespace ns3
55{
56
58namespace tests
59{
60} // namespace tests
61
62//
63// Note on below macros:
64//
65// When multiple statements are used in a macro, they should be bound
66// together in a loop syntactically, so the macro can appear safely
67// inside if clauses or other places that expect a single statement or
68// a statement block. The "strange" do while construct is a generally
69// expected best practice for defining a robust macro.
70//
71
76#define ASSERT_ON_FAILURE \
77 do \
78 { \
79 if (MustAssertOnFailure()) \
80 { \
81 *(volatile int*)0 = 0; \
82 } \
83 } while (false)
84
89#define CONTINUE_ON_FAILURE \
90 do \
91 { \
92 if (!MustContinueOnFailure()) \
93 { \
94 return; \
95 } \
96 } while (false)
97
102#define CONTINUE_ON_FAILURE_RETURNS_BOOL \
103 do \
104 { \
105 if (!MustContinueOnFailure()) \
106 { \
107 return IsStatusFailure(); \
108 } \
109 } while (false)
110
111// ===========================================================================
112// Test for equality (generic version)
113// ===========================================================================
114
144#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg) \
145 do \
146 { \
147 if (!((actual) == (limit))) \
148 { \
149 ASSERT_ON_FAILURE; \
150 std::ostringstream msgStream; \
151 msgStream << msg; \
152 std::ostringstream actualStream; \
153 actualStream << actual; \
154 std::ostringstream limitStream; \
155 limitStream << limit; \
156 ReportTestFailure(std::string(#actual) + " (actual) == " + std::string(#limit) + \
157 " (limit)", \
158 actualStream.str(), \
159 limitStream.str(), \
160 msgStream.str(), \
161 __FILE__, \
162 __LINE__); \
163 CONTINUE_ON_FAILURE; \
164 } \
165 } while (false)
166
199#define NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL(actual, limit, msg) \
200 do \
201 { \
202 if (!((actual) == (limit))) \
203 { \
204 ASSERT_ON_FAILURE; \
205 std::ostringstream msgStream; \
206 msgStream << msg; \
207 std::ostringstream actualStream; \
208 actualStream << actual; \
209 std::ostringstream limitStream; \
210 limitStream << limit; \
211 ReportTestFailure(std::string(#actual) + " (actual) == " + std::string(#limit) + \
212 " (limit)", \
213 actualStream.str(), \
214 limitStream.str(), \
215 msgStream.str(), \
216 __FILE__, \
217 __LINE__); \
218 CONTINUE_ON_FAILURE_RETURNS_BOOL; \
219 } \
220 } while (false)
221
251#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg) \
252 do \
253 { \
254 if (!((actual) == (limit))) \
255 { \
256 ASSERT_ON_FAILURE; \
257 std::ostringstream msgStream; \
258 msgStream << msg; \
259 std::ostringstream actualStream; \
260 actualStream << actual; \
261 std::ostringstream limitStream; \
262 limitStream << limit; \
263 ReportTestFailure(std::string(#actual) + " (actual) == " + std::string(#limit) + \
264 " (limit)", \
265 actualStream.str(), \
266 limitStream.str(), \
267 msgStream.str(), \
268 __FILE__, \
269 __LINE__); \
270 } \
271 } while (false)
272
273// ===========================================================================
274// Test for equality with a provided tolerance (use for floating point
275// comparisons -- both float and double)
276// ===========================================================================
277
337#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg) \
338 do \
339 { \
340 if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
341 { \
342 ASSERT_ON_FAILURE; \
343 std::ostringstream msgStream; \
344 msgStream << msg; \
345 std::ostringstream actualStream; \
346 actualStream << actual; \
347 std::ostringstream limitStream; \
348 limitStream << limit << " +- " << tol; \
349 std::ostringstream condStream; \
350 condStream << #actual << " (actual) < " << #limit << " (limit) + " << #tol \
351 << " (tol) && " << #actual << " (actual) > " << #limit << " (limit) - " \
352 << #tol << " (tol)"; \
353 ReportTestFailure(condStream.str(), \
354 actualStream.str(), \
355 limitStream.str(), \
356 msgStream.str(), \
357 __FILE__, \
358 __LINE__); \
359 CONTINUE_ON_FAILURE; \
360 } \
361 } while (false)
362
425#define NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL(actual, limit, tol, msg) \
426 do \
427 { \
428 if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
429 { \
430 ASSERT_ON_FAILURE; \
431 std::ostringstream msgStream; \
432 msgStream << msg; \
433 std::ostringstream actualStream; \
434 actualStream << actual; \
435 std::ostringstream limitStream; \
436 limitStream << limit << " +- " << tol; \
437 std::ostringstream condStream; \
438 condStream << #actual << " (actual) < " << #limit << " (limit) + " << #tol \
439 << " (tol) && " << #actual << " (actual) > " << #limit << " (limit) - " \
440 << #tol << " (tol)"; \
441 ReportTestFailure(condStream.str(), \
442 actualStream.str(), \
443 limitStream.str(), \
444 msgStream.str(), \
445 __FILE__, \
446 __LINE__); \
447 CONTINUE_ON_FAILURE_RETURNS_BOOL; \
448 } \
449 } while (false)
450
510#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg) \
511 do \
512 { \
513 if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
514 { \
515 ASSERT_ON_FAILURE; \
516 std::ostringstream msgStream; \
517 msgStream << msg; \
518 std::ostringstream actualStream; \
519 actualStream << actual; \
520 std::ostringstream limitStream; \
521 limitStream << limit << " +- " << tol; \
522 std::ostringstream condStream; \
523 condStream << #actual << " (actual) < " << #limit << " (limit) + " << #tol \
524 << " (tol) && " << #actual << " (actual) > " << #limit << " (limit) - " \
525 << #tol << " (tol)"; \
526 ReportTestFailure(condStream.str(), \
527 actualStream.str(), \
528 limitStream.str(), \
529 msgStream.str(), \
530 __FILE__, \
531 __LINE__); \
532 } \
533 } while (false)
534
535// ===========================================================================
536// Test for inequality
537// ===========================================================================
538
564#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg) \
565 do \
566 { \
567 if (!((actual) != (limit))) \
568 { \
569 ASSERT_ON_FAILURE; \
570 std::ostringstream msgStream; \
571 msgStream << msg; \
572 std::ostringstream actualStream; \
573 actualStream << actual; \
574 std::ostringstream limitStream; \
575 limitStream << limit; \
576 ReportTestFailure(std::string(#actual) + " (actual) != " + std::string(#limit) + \
577 " (limit)", \
578 actualStream.str(), \
579 limitStream.str(), \
580 msgStream.str(), \
581 __FILE__, \
582 __LINE__); \
583 CONTINUE_ON_FAILURE; \
584 } \
585 } while (false)
586
615#define NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL(actual, limit, msg) \
616 do \
617 { \
618 if (!((actual) != (limit))) \
619 { \
620 ASSERT_ON_FAILURE; \
621 std::ostringstream msgStream; \
622 msgStream << msg; \
623 std::ostringstream actualStream; \
624 actualStream << actual; \
625 std::ostringstream limitStream; \
626 limitStream << limit; \
627 ReportTestFailure(std::string(#actual) + " (actual) != " + std::string(#limit) + \
628 " (limit)", \
629 actualStream.str(), \
630 limitStream.str(), \
631 msgStream.str(), \
632 __FILE__, \
633 __LINE__); \
634 CONTINUE_ON_FAILURE_RETURNS_BOOL; \
635 } \
636 } while (false)
637
666#define NS_TEST_EXPECT_MSG_NE(actual, limit, msg) \
667 do \
668 { \
669 if (!((actual) != (limit))) \
670 { \
671 ASSERT_ON_FAILURE; \
672 std::ostringstream msgStream; \
673 msgStream << msg; \
674 std::ostringstream actualStream; \
675 actualStream << actual; \
676 std::ostringstream limitStream; \
677 limitStream << limit; \
678 ReportTestFailure(std::string(#actual) + " (actual) != " + std::string(#limit) + \
679 " (limit)", \
680 actualStream.str(), \
681 limitStream.str(), \
682 msgStream.str(), \
683 __FILE__, \
684 __LINE__); \
685 } \
686 } while (false)
687
688// ===========================================================================
689// Test for less than relation
690// ===========================================================================
691
709#define NS_TEST_ASSERT_MSG_LT(actual, limit, msg) \
710 do \
711 { \
712 if (!((actual) < (limit))) \
713 { \
714 ASSERT_ON_FAILURE; \
715 std::ostringstream msgStream; \
716 msgStream << msg; \
717 std::ostringstream actualStream; \
718 actualStream << actual; \
719 std::ostringstream limitStream; \
720 limitStream << limit; \
721 ReportTestFailure(std::string(#actual) + " (actual) < " + std::string(#limit) + \
722 " (limit)", \
723 actualStream.str(), \
724 limitStream.str(), \
725 msgStream.str(), \
726 __FILE__, \
727 __LINE__); \
728 CONTINUE_ON_FAILURE; \
729 } \
730 } while (false)
731
750#define NS_TEST_ASSERT_MSG_LT_OR_EQ(actual, limit, msg) \
751 do \
752 { \
753 if (!((actual) <= (limit))) \
754 { \
755 ASSERT_ON_FAILURE; \
756 std::ostringstream msgStream; \
757 msgStream << msg; \
758 std::ostringstream actualStream; \
759 actualStream << actual; \
760 std::ostringstream limitStream; \
761 limitStream << limit; \
762 ReportTestFailure(std::string(#actual) + " (actual) < " + std::string(#limit) + \
763 " (limit)", \
764 actualStream.str(), \
765 limitStream.str(), \
766 msgStream.str(), \
767 __FILE__, \
768 __LINE__); \
769 CONTINUE_ON_FAILURE; \
770 } \
771 } while (false)
772
790#define NS_TEST_EXPECT_MSG_LT(actual, limit, msg) \
791 do \
792 { \
793 if (!((actual) < (limit))) \
794 { \
795 ASSERT_ON_FAILURE; \
796 std::ostringstream msgStream; \
797 msgStream << msg; \
798 std::ostringstream actualStream; \
799 actualStream << actual; \
800 std::ostringstream limitStream; \
801 limitStream << limit; \
802 ReportTestFailure(std::string(#actual) + " (actual) < " + std::string(#limit) + \
803 " (limit)", \
804 actualStream.str(), \
805 limitStream.str(), \
806 msgStream.str(), \
807 __FILE__, \
808 __LINE__); \
809 } \
810 } while (false)
811
830#define NS_TEST_EXPECT_MSG_LT_OR_EQ(actual, limit, msg) \
831 do \
832 { \
833 if (!((actual) <= (limit))) \
834 { \
835 ASSERT_ON_FAILURE; \
836 std::ostringstream msgStream; \
837 msgStream << msg; \
838 std::ostringstream actualStream; \
839 actualStream << actual; \
840 std::ostringstream limitStream; \
841 limitStream << limit; \
842 ReportTestFailure(std::string(#actual) + " (actual) < " + std::string(#limit) + \
843 " (limit)", \
844 actualStream.str(), \
845 limitStream.str(), \
846 msgStream.str(), \
847 __FILE__, \
848 __LINE__); \
849 } \
850 } while (false)
851
852// ===========================================================================
853// Test for greater than relation
854// ===========================================================================
855
874#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg) \
875 do \
876 { \
877 if (!((actual) > (limit))) \
878 { \
879 ASSERT_ON_FAILURE; \
880 std::ostringstream msgStream; \
881 msgStream << msg; \
882 std::ostringstream actualStream; \
883 actualStream << actual; \
884 std::ostringstream limitStream; \
885 limitStream << limit; \
886 ReportTestFailure(std::string(#actual) + " (actual) > " + std::string(#limit) + \
887 " (limit)", \
888 actualStream.str(), \
889 limitStream.str(), \
890 msgStream.str(), \
891 __FILE__, \
892 __LINE__); \
893 CONTINUE_ON_FAILURE; \
894 } \
895 } while (false)
896
915#define NS_TEST_ASSERT_MSG_GT_OR_EQ(actual, limit, msg) \
916 do \
917 { \
918 if (!((actual) >= (limit))) \
919 { \
920 ASSERT_ON_FAILURE; \
921 std::ostringstream msgStream; \
922 msgStream << msg; \
923 std::ostringstream actualStream; \
924 actualStream << actual; \
925 std::ostringstream limitStream; \
926 limitStream << limit; \
927 ReportTestFailure(std::string(#actual) + " (actual) > " + std::string(#limit) + \
928 " (limit)", \
929 actualStream.str(), \
930 limitStream.str(), \
931 msgStream.str(), \
932 __FILE__, \
933 __LINE__); \
934 CONTINUE_ON_FAILURE; \
935 } \
936 } while (false)
937
956#define NS_TEST_EXPECT_MSG_GT(actual, limit, msg) \
957 do \
958 { \
959 if (!((actual) > (limit))) \
960 { \
961 ASSERT_ON_FAILURE; \
962 std::ostringstream msgStream; \
963 msgStream << msg; \
964 std::ostringstream actualStream; \
965 actualStream << actual; \
966 std::ostringstream limitStream; \
967 limitStream << limit; \
968 ReportTestFailure(std::string(#actual) + " (actual) > " + std::string(#limit) + \
969 " (limit)", \
970 actualStream.str(), \
971 limitStream.str(), \
972 msgStream.str(), \
973 __FILE__, \
974 __LINE__); \
975 } \
976 } while (false)
977
996#define NS_TEST_EXPECT_MSG_GT_OR_EQ(actual, limit, msg) \
997 do \
998 { \
999 if (!((actual) >= (limit))) \
1000 { \
1001 ASSERT_ON_FAILURE; \
1002 std::ostringstream msgStream; \
1003 msgStream << msg; \
1004 std::ostringstream actualStream; \
1005 actualStream << actual; \
1006 std::ostringstream limitStream; \
1007 limitStream << limit; \
1008 ReportTestFailure(std::string(#actual) + " (actual) > " + std::string(#limit) + \
1009 " (limit)", \
1010 actualStream.str(), \
1011 limitStream.str(), \
1012 msgStream.str(), \
1013 __FILE__, \
1014 __LINE__); \
1015 } \
1016 } while (false)
1017
1042bool TestDoubleIsEqual(const double a,
1043 const double b,
1044 const double epsilon = std::numeric_limits<double>::epsilon());
1045
1046class TestRunnerImpl;
1047
1060{
1061 public:
1064 {
1065 QUICK = 1,
1067 TAKES_FOREVER = 3
1069
1073 virtual ~TestCase();
1074
1075 // Delete copy constructor and assignment operator to avoid misuse
1076 TestCase(const TestCase&) = delete;
1077 TestCase& operator=(const TestCase&) = delete;
1078
1082 std::string GetName() const;
1083
1084 protected:
1090 TestCase(std::string name);
1091
1099 void AddTestCase(TestCase* testCase, TestDuration duration = QUICK);
1100
1117 void SetDataDir(std::string directory);
1118
1124 bool IsStatusFailure() const;
1130 bool IsStatusSuccess() const;
1131
1137 TestCase* GetParent() const;
1138
1155 void ReportTestFailure(std::string cond,
1156 std::string actual,
1157 std::string limit,
1158 std::string message,
1159 std::string file,
1160 int32_t line);
1166 bool MustAssertOnFailure() const;
1172 bool MustContinueOnFailure() const;
1181 std::string CreateDataDirFilename(std::string filename);
1191 std::string CreateTempDirFilename(std::string filename);
1194 private:
1196 friend class TestRunnerImpl;
1197
1205 virtual void DoSetup();
1206
1212 virtual void DoRun() = 0;
1213
1221 virtual void DoTeardown();
1222
1223 // methods called by TestRunnerImpl
1229 void Run(TestRunnerImpl* runner);
1231 bool IsFailed() const;
1232
1237 struct Result;
1238
1240 std::vector<TestCase*> m_children;
1241 std::string m_dataDir;
1244 std::string m_name;
1246};
1247
1255class TestSuite : public TestCase
1256{
1257 public:
1262 enum Type
1263 {
1264 ALL = 0,
1270
1277 TestSuite(std::string name, Type type = UNIT);
1278
1285
1286 private:
1287 // Inherited
1288 void DoRun() override;
1289
1291};
1292
1299{
1300 public:
1309 static int Run(int argc, char* argv[]);
1310};
1311
1317template <typename T>
1319{
1320 public:
1328 virtual ~TestVectors();
1329
1330 // Delete copy constructor and assignment operator to avoid misuse
1331 TestVectors(const TestVectors&) = delete;
1333
1339 void Reserve(uint32_t reserve);
1340
1346 std::size_t Add(T vector);
1347
1352 std::size_t GetN() const;
1358 T Get(std::size_t i) const;
1359
1360 private:
1361 typedef std::vector<T> TestVector;
1363};
1364
1365template <typename T>
1367 : m_vectors()
1368{
1369}
1370
1371template <typename T>
1372void
1374{
1375 m_vectors.reserve(reserve);
1376}
1377
1378template <typename T>
1380{
1381}
1382
1383template <typename T>
1384std::size_t
1386{
1387 std::size_t index = m_vectors.size();
1388 m_vectors.push_back(vector);
1389 return index;
1390}
1391
1392template <typename T>
1393std::size_t
1395{
1396 return m_vectors.size();
1397}
1398
1399template <typename T>
1400T
1401TestVectors<T>::Get(std::size_t i) const
1402{
1403 NS_ABORT_MSG_UNLESS(m_vectors.size() > i, "TestVectors::Get(): Bad index");
1404 return m_vectors[i];
1405}
1406
1407} // namespace ns3
1408
1409#endif /* NS3_TEST_H */
encapsulates test code
Definition: test.h:1060
std::string m_name
TestCase name.
Definition: test.h:1244
TestDuration
How long the test takes to execute.
Definition: test.h:1064
@ EXTENSIVE
Medium length test.
Definition: test.h:1066
@ TAKES_FOREVER
Very long running test.
Definition: test.h:1067
@ QUICK
Fast test.
Definition: test.h:1065
bool MustContinueOnFailure() const
Check if this run should continue on failure.
Definition: test.cc:412
bool IsStatusFailure() const
Check if any tests failed.
Definition: test.cc:464
std::string m_dataDir
My data directory.
Definition: test.h:1241
std::string CreateDataDirFilename(std::string filename)
Construct the full path to a file in the data directory.
Definition: test.cc:419
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
TestCase * m_parent
Pointer to my parent TestCase.
Definition: test.h:1239
Result * m_result
Results data.
Definition: test.h:1243
bool IsStatusSuccess() const
Check if all tests passed.
Definition: test.cc:471
virtual void DoSetup()
Implementation to do any local setup required for this TestCase.
Definition: test.cc:485
virtual ~TestCase()
Destructor.
Definition: test.cc:287
std::string CreateTempDirFilename(std::string filename)
Construct the full path to a file in a temporary directory.
Definition: test.cc:438
TestRunnerImpl * m_runner
Pointer to the TestRunner.
Definition: test.h:1242
TestCase * GetParent() const
Get the parent of this TestCase.
Definition: test.cc:380
TestDuration m_duration
TestCase duration.
Definition: test.h:1245
bool MustAssertOnFailure() const
Check if this run should assert on failure.
Definition: test.cc:405
void SetDataDir(std::string directory)
Set the data directory where reference trace files can be found.
Definition: test.cc:478
virtual void DoTeardown()
Implementation to do any local setup required for this TestCase.
Definition: test.cc:491
void Run(TestRunnerImpl *runner)
Actually run this TestCase.
Definition: test.cc:349
TestCase(const TestCase &)=delete
virtual void DoRun()=0
Implementation to actually run this TestCase.
std::string GetName() const
Definition: test.cc:373
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.
Definition: test.cc:386
bool IsFailed() const
Check if any tests failed.
Definition: test.cc:342
TestCase & operator=(const TestCase &)=delete
std::vector< TestCase * > m_children
Vector of my children.
Definition: test.h:1240
A runner to execute tests.
Definition: test.h:1299
static int Run(int argc, char *argv[])
Run the requested suite of tests, according to the given command line arguments.
Definition: test.cc:1142
Container for all tests.
Definition: test.cc:139
A suite of tests to run.
Definition: test.h:1256
Type
Type of test.
Definition: test.h:1263
@ EXAMPLE
This test suite implements an Example Test.
Definition: test.h:1267
@ PERFORMANCE
This test suite implements a Performance Test.
Definition: test.h:1268
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1265
@ SYSTEM
This test suite implements a System Test.
Definition: test.h:1266
TestSuite::Type m_type
Type of this TestSuite.
Definition: test.h:1290
void DoRun() override
Implementation to actually run this TestCase.
Definition: test.cc:512
TestSuite::Type GetTestType()
get the kind of test this test suite implements
Definition: test.cc:505
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1319
std::vector< T > TestVector
Container type.
Definition: test.h:1361
T Get(std::size_t i) const
Get the i'th test vector.
Definition: test.h:1401
std::size_t GetN() const
Get the total number of test vectors.
Definition: test.h:1394
TestVectors(const TestVectors &)=delete
TestVectors()
Constructor.
Definition: test.h:1366
void Reserve(uint32_t reserve)
Set the expected length of this vector.
Definition: test.h:1373
std::size_t Add(T vector)
Definition: test.h:1385
TestVector m_vectors
The list of test vectors.
Definition: test.h:1362
virtual ~TestVectors()
Virtual destructor.
Definition: test.h:1379
TestVectors & operator=(const TestVectors &)=delete
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
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...
Definition: test.cc:45
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Container for results from a TestCase.
Definition: test.cc:121
ns3::SystemWallClockMs declaration.