A Discrete-Event Network Simulator
API
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 
21 #include "system-wall-clock-ms.h"
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 
54 namespace ns3
55 {
56 
58 namespace 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 
1042 bool TestDoubleIsEqual(const double a,
1043  const double b,
1045 
1046 class TestRunnerImpl;
1047 
1060 {
1061  public:
1064  {
1065  QUICK = 1,
1067  TAKES_FOREVER = 3
1068  };
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 
1255 class TestSuite : public TestCase
1256 {
1257  public:
1262  enum Type
1263  {
1264  ALL = 0,
1268  PERFORMANCE
1269  };
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 
1317 template <typename T>
1319 {
1320  public:
1328  virtual ~TestVectors();
1329 
1330  // Delete copy constructor and assignment operator to avoid misuse
1331  TestVectors(const TestVectors&) = delete;
1332  TestVectors& operator=(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 
1365 template <typename T>
1367  : m_vectors()
1368 {
1369 }
1370 
1371 template <typename T>
1372 void
1373 TestVectors<T>::Reserve(uint32_t reserve)
1374 {
1375  m_vectors.reserve(reserve);
1376 }
1377 
1378 template <typename T>
1380 {
1381 }
1382 
1383 template <typename T>
1384 std::size_t
1386 {
1387  std::size_t index = m_vectors.size();
1388  m_vectors.push_back(vector);
1389  return index;
1390 }
1391 
1392 template <typename T>
1393 std::size_t
1395 {
1396  return m_vectors.size();
1397 }
1398 
1399 template <typename T>
1400 T
1401 TestVectors<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:1237
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.
TestCase & operator=(const TestCase &)=delete
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
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:1141
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
TestSuite(std::string name, Type type=UNIT)
Construct a new test suite.
Definition: test.cc:496
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
TestVectors & operator=(const TestVectors &)=delete
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
#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.