A Discrete-Event Network Simulator
API
test.h
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 University of Washington
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */
18 
19 #ifndef NS3_TEST_H
20 #define NS3_TEST_H
21 
22 #include <iostream>
23 #include <fstream>
24 #include <sstream>
25 #include <string>
26 #include <vector>
27 #include <list>
28 #include <limits>
29 #include <stdint.h>
30 
31 #include "system-wall-clock-ms.h"
32 
55 namespace ns3 {
56 
58 namespace tests {} // namespace tests
59 
60 //
61 // Note on below macros:
62 //
63 // When multiple statements are used in a macro, they should be bound
64 // together in a loop syntactically, so the macro can appear safely
65 // inside if clauses or other places that expect a single statement or
66 // a statement block. The "strange" do while construct is a generally
67 // expected best practice for defining a robust macro.
68 //
69 
74 #define ASSERT_ON_FAILURE \
75  do { \
76  if (MustAssertOnFailure ()) \
77  { \
78  *(volatile int *)0 = 0; \
79  } \
80  } while (false)
81 
86 #define CONTINUE_ON_FAILURE \
87  do { \
88  if (!MustContinueOnFailure ()) \
89  { \
90  return; \
91  } \
92  } while (false)
93 
98 #define CONTINUE_ON_FAILURE_RETURNS_BOOL \
99  do { \
100  if (!MustContinueOnFailure ()) \
101  { \
102  return IsStatusFailure (); \
103  } \
104  } while (false)
105 
106 
107 
108 // ===========================================================================
109 // Test for equality (generic version)
110 // ===========================================================================
111 
141 #define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg) \
142  do { \
143  if (!((actual) == (limit))) \
144  { \
145  ASSERT_ON_FAILURE; \
146  std::ostringstream msgStream; \
147  msgStream << msg; \
148  std::ostringstream actualStream; \
149  actualStream << actual; \
150  std::ostringstream limitStream; \
151  limitStream << limit; \
152  ReportTestFailure (std::string (#actual) + " (actual) == " + \
153  std::string (#limit) + " (limit)", \
154  actualStream.str (), limitStream.str (), \
155  msgStream.str (), __FILE__, __LINE__); \
156  CONTINUE_ON_FAILURE; \
157  } \
158  } while (false)
159 
192 #define NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL(actual, limit, msg) \
193  do { \
194  if (!((actual) == (limit))) \
195  { \
196  ASSERT_ON_FAILURE; \
197  std::ostringstream msgStream; \
198  msgStream << msg; \
199  std::ostringstream actualStream; \
200  actualStream << actual; \
201  std::ostringstream limitStream; \
202  limitStream << limit; \
203  ReportTestFailure (std::string (#actual) + " (actual) == " + \
204  std::string (#limit) + " (limit)", \
205  actualStream.str (), limitStream.str (), \
206  msgStream.str (), __FILE__, __LINE__); \
207  CONTINUE_ON_FAILURE_RETURNS_BOOL; \
208  } \
209  } while (false)
210 
240 #define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg) \
241  do { \
242  if (!((actual) == (limit))) \
243  { \
244  ASSERT_ON_FAILURE; \
245  std::ostringstream msgStream; \
246  msgStream << msg; \
247  std::ostringstream actualStream; \
248  actualStream << actual; \
249  std::ostringstream limitStream; \
250  limitStream << limit; \
251  ReportTestFailure (std::string (#actual) + " (actual) == " + \
252  std::string (#limit) + " (limit)", \
253  actualStream.str (), limitStream.str (), \
254  msgStream.str (), __FILE__, __LINE__); \
255  } \
256  } while (false)
257 
258 
259 // ===========================================================================
260 // Test for equality with a provided tolerance (use for floating point
261 // comparisons -- both float and double)
262 // ===========================================================================
263 
323 #define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg) \
324  do { \
325  if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
326  { \
327  ASSERT_ON_FAILURE; \
328  std::ostringstream msgStream; \
329  msgStream << msg; \
330  std::ostringstream actualStream; \
331  actualStream << actual; \
332  std::ostringstream limitStream; \
333  limitStream << limit << " +- " << tol; \
334  std::ostringstream condStream; \
335  condStream << #actual << " (actual) < " << #limit \
336  << " (limit) + " << #tol << " (tol) && " \
337  << #actual << " (actual) > " << #limit \
338  << " (limit) - " << #tol << " (tol)"; \
339  ReportTestFailure (condStream.str (), actualStream.str (), \
340  limitStream.str (), msgStream.str (), \
341  __FILE__, __LINE__); \
342  CONTINUE_ON_FAILURE; \
343  } \
344  } while (false)
345 
408 #define NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL(actual, limit, tol, msg) \
409  do { \
410  if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
411  { \
412  ASSERT_ON_FAILURE; \
413  std::ostringstream msgStream; \
414  msgStream << msg; \
415  std::ostringstream actualStream; \
416  actualStream << actual; \
417  std::ostringstream limitStream; \
418  limitStream << limit << " +- " << tol; \
419  std::ostringstream condStream; \
420  condStream << #actual << " (actual) < " << #limit \
421  << " (limit) + " << #tol << " (tol) && " \
422  << #actual << " (actual) > " << #limit \
423  << " (limit) - " << #tol << " (tol)"; \
424  ReportTestFailure (condStream.str (), actualStream.str (), \
425  limitStream.str (), msgStream.str (), \
426  __FILE__, __LINE__); \
427  CONTINUE_ON_FAILURE_RETURNS_BOOL; \
428  } \
429  } while (false)
430 
431 
491 #define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg) \
492  do { \
493  if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
494  { \
495  ASSERT_ON_FAILURE; \
496  std::ostringstream msgStream; \
497  msgStream << msg; \
498  std::ostringstream actualStream; \
499  actualStream << actual; \
500  std::ostringstream limitStream; \
501  limitStream << limit << " +- " << tol; \
502  std::ostringstream condStream; \
503  condStream << #actual << " (actual) < " << #limit \
504  << " (limit) + " << #tol << " (tol) && " \
505  << #actual << " (actual) > " << #limit \
506  << " (limit) - " << #tol << " (tol)"; \
507  ReportTestFailure (condStream.str (), actualStream.str (), \
508  limitStream.str (), msgStream.str (), \
509  __FILE__, __LINE__); \
510  } \
511  } while (false)
512 
513 // ===========================================================================
514 // Test for inequality
515 // ===========================================================================
516 
542 #define NS_TEST_ASSERT_MSG_NE(actual, limit, msg) \
543  do { \
544  if (!((actual) != (limit))) \
545  { \
546  ASSERT_ON_FAILURE; \
547  std::ostringstream msgStream; \
548  msgStream << msg; \
549  std::ostringstream actualStream; \
550  actualStream << actual; \
551  std::ostringstream limitStream; \
552  limitStream << limit; \
553  ReportTestFailure (std::string (#actual) + " (actual) != " + \
554  std::string (#limit) + " (limit)", \
555  actualStream.str (), limitStream.str (), \
556  msgStream.str (), __FILE__, __LINE__); \
557  CONTINUE_ON_FAILURE; \
558  } \
559  } while (false)
560 
589 #define NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL(actual, limit, msg) \
590  do { \
591  if (!((actual) != (limit))) \
592  { \
593  ASSERT_ON_FAILURE; \
594  std::ostringstream msgStream; \
595  msgStream << msg; \
596  std::ostringstream actualStream; \
597  actualStream << actual; \
598  std::ostringstream limitStream; \
599  limitStream << limit; \
600  ReportTestFailure (std::string (#actual) + " (actual) != " + \
601  std::string (#limit) + " (limit)", \
602  actualStream.str (), limitStream.str (), \
603  msgStream.str (), __FILE__, __LINE__); \
604  CONTINUE_ON_FAILURE_RETURNS_BOOL; \
605  } \
606  } while (false)
607 
636 #define NS_TEST_EXPECT_MSG_NE(actual, limit, msg) \
637  do { \
638  if (!((actual) != (limit))) \
639  { \
640  ASSERT_ON_FAILURE; \
641  std::ostringstream msgStream; \
642  msgStream << msg; \
643  std::ostringstream actualStream; \
644  actualStream << actual; \
645  std::ostringstream limitStream; \
646  limitStream << limit; \
647  ReportTestFailure (std::string (#actual) + " (actual) != " + \
648  std::string (#limit) + " (limit)", \
649  actualStream.str (), limitStream.str (), \
650  msgStream.str (), __FILE__, __LINE__); \
651  } \
652  } while (false)
653 
654 // ===========================================================================
655 // Test for less than relation
656 // ===========================================================================
657 
675 #define NS_TEST_ASSERT_MSG_LT(actual, limit, msg) \
676  do { \
677  if (!((actual) < (limit))) \
678  { \
679  ASSERT_ON_FAILURE; \
680  std::ostringstream msgStream; \
681  msgStream << msg; \
682  std::ostringstream actualStream; \
683  actualStream << actual; \
684  std::ostringstream limitStream; \
685  limitStream << limit; \
686  ReportTestFailure (std::string (#actual) + " (actual) < " + \
687  std::string (#limit) + " (limit)", \
688  actualStream.str (), limitStream.str (), \
689  msgStream.str (), __FILE__, __LINE__); \
690  CONTINUE_ON_FAILURE; \
691  } \
692  } while (false)
693 
712 #define NS_TEST_ASSERT_MSG_LT_OR_EQ(actual, limit, msg) \
713  do { \
714  if (!((actual) <= (limit))) \
715  { \
716  ASSERT_ON_FAILURE; \
717  std::ostringstream msgStream; \
718  msgStream << msg; \
719  std::ostringstream actualStream; \
720  actualStream << actual; \
721  std::ostringstream limitStream; \
722  limitStream << limit; \
723  ReportTestFailure (std::string (#actual) + " (actual) < " + \
724  std::string (#limit) + " (limit)", \
725  actualStream.str (), limitStream.str (), \
726  msgStream.str (), __FILE__, __LINE__); \
727  CONTINUE_ON_FAILURE; \
728  } \
729  } while (false)
730 
748 #define NS_TEST_EXPECT_MSG_LT(actual, limit, msg) \
749  do { \
750  if (!((actual) < (limit))) \
751  { \
752  ASSERT_ON_FAILURE; \
753  std::ostringstream msgStream; \
754  msgStream << msg; \
755  std::ostringstream actualStream; \
756  actualStream << actual; \
757  std::ostringstream limitStream; \
758  limitStream << limit; \
759  ReportTestFailure (std::string (#actual) + " (actual) < " + \
760  std::string (#limit) + " (limit)", \
761  actualStream.str (), limitStream.str (), \
762  msgStream.str (), __FILE__, __LINE__); \
763  } \
764  } while (false)
765 
766 
785 #define NS_TEST_EXPECT_MSG_LT_OR_EQ(actual, limit, msg) \
786  do { \
787  if (!((actual) <= (limit))) \
788  { \
789  ASSERT_ON_FAILURE; \
790  std::ostringstream msgStream; \
791  msgStream << msg; \
792  std::ostringstream actualStream; \
793  actualStream << actual; \
794  std::ostringstream limitStream; \
795  limitStream << limit; \
796  ReportTestFailure (std::string (#actual) + " (actual) < " + \
797  std::string (#limit) + " (limit)", \
798  actualStream.str (), limitStream.str (), \
799  msgStream.str (), __FILE__, __LINE__); \
800  } \
801  } while (false)
802 
803 // ===========================================================================
804 // Test for greater than relation
805 // ===========================================================================
806 
825 #define NS_TEST_ASSERT_MSG_GT(actual, limit, msg) \
826  do { \
827  if (!((actual) > (limit))) \
828  { \
829  ASSERT_ON_FAILURE; \
830  std::ostringstream msgStream; \
831  msgStream << msg; \
832  std::ostringstream actualStream; \
833  actualStream << actual; \
834  std::ostringstream limitStream; \
835  limitStream << limit; \
836  ReportTestFailure (std::string (#actual) + " (actual) > " + \
837  std::string (#limit) + " (limit)", \
838  actualStream.str (), limitStream.str (), \
839  msgStream.str (), __FILE__, __LINE__); \
840  CONTINUE_ON_FAILURE; \
841  } \
842  } while (false)
843 
862 #define NS_TEST_ASSERT_MSG_GT_OR_EQ(actual, limit, msg) \
863  do { \
864  if (!((actual) >= (limit))) \
865  { \
866  ASSERT_ON_FAILURE; \
867  std::ostringstream msgStream; \
868  msgStream << msg; \
869  std::ostringstream actualStream; \
870  actualStream << actual; \
871  std::ostringstream limitStream; \
872  limitStream << limit; \
873  ReportTestFailure (std::string (#actual) + " (actual) > " + \
874  std::string (#limit) + " (limit)", \
875  actualStream.str (), limitStream.str (), \
876  msgStream.str (), __FILE__, __LINE__); \
877  CONTINUE_ON_FAILURE; \
878  } \
879  } while (false)
880 
899 #define NS_TEST_EXPECT_MSG_GT(actual, limit, msg) \
900  do { \
901  if (!((actual) > (limit))) \
902  { \
903  ASSERT_ON_FAILURE; \
904  std::ostringstream msgStream; \
905  msgStream << msg; \
906  std::ostringstream actualStream; \
907  actualStream << actual; \
908  std::ostringstream limitStream; \
909  limitStream << limit; \
910  ReportTestFailure (std::string (#actual) + " (actual) > " + \
911  std::string (#limit) + " (limit)", \
912  actualStream.str (), limitStream.str (), \
913  msgStream.str (), __FILE__, __LINE__); \
914  } \
915  } while (false)
916 
935 #define NS_TEST_EXPECT_MSG_GT_OR_EQ(actual, limit, msg) \
936  do { \
937  if (!((actual) >= (limit))) \
938  { \
939  ASSERT_ON_FAILURE; \
940  std::ostringstream msgStream; \
941  msgStream << msg; \
942  std::ostringstream actualStream; \
943  actualStream << actual; \
944  std::ostringstream limitStream; \
945  limitStream << limit; \
946  ReportTestFailure (std::string (#actual) + " (actual) > " + \
947  std::string (#limit) + " (limit)", \
948  actualStream.str (), limitStream.str (), \
949  msgStream.str (), __FILE__, __LINE__); \
950  } \
951  } while (false)
952 
977 bool TestDoubleIsEqual (const double a, const double b,
979 
980 class TestRunnerImpl;
981 
993 class TestCase
994 {
995 public:
998  {
999  QUICK = 1,
1001  TAKES_FOREVER = 3
1002  };
1003 
1007  virtual ~TestCase ();
1008 
1009  // Delete copy constructor and assignment operator to avoid misuse
1010  TestCase (const TestCase &) = delete;
1011  TestCase & operator = (const TestCase &) = delete;
1012 
1016  std::string GetName (void) const;
1017 
1018 protected:
1024  TestCase (std::string name);
1025 
1033  void AddTestCase (TestCase *testCase, TestDuration duration = QUICK);
1034 
1051  void SetDataDir (std::string directory);
1052 
1058  bool IsStatusFailure (void) const;
1064  bool IsStatusSuccess (void) const;
1065 
1071  TestCase * GetParent () const;
1072 
1089  void ReportTestFailure (std::string cond, std::string actual,
1090  std::string limit, std::string message,
1091  std::string file, int32_t line);
1097  bool MustAssertOnFailure (void) const;
1103  bool MustContinueOnFailure (void) const;
1112  std::string CreateDataDirFilename (std::string filename);
1122  std::string CreateTempDirFilename (std::string filename);
1125 private:
1126 
1128  friend class TestRunnerImpl;
1129 
1137  virtual void DoSetup (void);
1138 
1144  virtual void DoRun (void) = 0;
1145 
1153  virtual void DoTeardown (void);
1154 
1155  // methods called by TestRunnerImpl
1161  void Run (TestRunnerImpl *runner);
1163  bool IsFailed (void) const;
1164 
1169  struct Result;
1170 
1172  std::vector<TestCase *> m_children;
1173  std::string m_dataDir;
1175  struct Result *m_result;
1176  std::string m_name;
1177  enum TestDuration m_duration;
1178 };
1179 
1187 class TestSuite : public TestCase
1188 {
1189 public:
1194  enum Type
1195  {
1196  ALL = 0,
1200  PERFORMANCE
1201  };
1202 
1209  TestSuite (std::string name, Type type = UNIT);
1210 
1217 
1218 private:
1219  // Inherited
1220  virtual void DoRun (void);
1221 
1223 };
1224 
1231 {
1232 public:
1241  static int Run (int argc, char *argv[]);
1242 };
1243 
1249 template <typename T>
1251 {
1252 public:
1260  virtual ~TestVectors ();
1261 
1262  // Delete copy constructor and assignment operator to avoid misuse
1263  TestVectors (const TestVectors &) = delete;
1264  TestVectors & operator = (const TestVectors &) = delete;
1265 
1271  void Reserve (uint32_t reserve);
1272 
1278  std::size_t Add (T vector);
1279 
1284  std::size_t GetN (void) const;
1290  T Get (std::size_t i) const;
1291 
1292 private:
1293  typedef std::vector<T> TestVector;
1295 };
1296 
1297 template <typename T>
1299  : m_vectors ()
1300 {}
1301 
1302 template <typename T>
1303 void
1304 TestVectors<T>::Reserve (uint32_t reserve)
1305 {
1306  m_vectors.reserve (reserve);
1307 }
1308 
1309 template <typename T>
1311 {}
1312 
1313 template <typename T>
1314 std::size_t
1316 {
1317  std::size_t index = m_vectors.size ();
1318  m_vectors.push_back (vector);
1319  return index;
1320 }
1321 
1322 template <typename T>
1323 std::size_t
1325 {
1326  return m_vectors.size ();
1327 }
1328 
1329 template <typename T>
1330 T
1331 TestVectors<T>::Get (std::size_t i) const
1332 {
1333  NS_ABORT_MSG_UNLESS (m_vectors.size () > i, "TestVectors::Get(): Bad index");
1334  return m_vectors[i];
1335 }
1336 
1337 } // namespace ns3
1338 
1339 #endif /* NS3_TEST_H */
encapsulates test code
Definition: test.h:994
std::string m_name
TestCase name.
Definition: test.h:1176
bool IsStatusSuccess(void) const
Check if all tests passed.
Definition: test.cc:458
TestDuration
How long the test takes to execute.
Definition: test.h:998
@ EXTENSIVE
Medium length test.
Definition: test.h:1000
@ TAKES_FOREVER
Very long running test.
Definition: test.h:1001
@ QUICK
Fast test.
Definition: test.h:999
enum TestDuration m_duration
TestCase duration.
Definition: test.h:1177
std::string m_dataDir
My data directory.
Definition: test.h:1173
std::string CreateDataDirFilename(std::string filename)
Construct the full path to a file in the data directory.
Definition: test.cc:412
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
Definition: test.cc:472
TestCase * m_parent
Pointer to my parent TestCase.
Definition: test.h:1169
std::vector< TestCase * > m_children
Vector of my children.
Definition: test.h:1172
virtual ~TestCase()
Destructor.
Definition: test.cc:285
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
Definition: test.cc:477
bool MustAssertOnFailure(void) const
Check if this run should assert on failure.
Definition: test.cc:399
std::string CreateTempDirFilename(std::string filename)
Construct the full path to a file in a temporary directory.
Definition: test.cc:430
TestRunnerImpl * m_runner
Pointer to the TestRunner.
Definition: test.h:1174
TestCase * GetParent() const
Get the parent of this TestCsse.
Definition: test.cc:376
virtual void DoRun(void)=0
Implementation to actually run this TestCase.
bool IsFailed(void) const
Check if any tests failed.
Definition: test.cc:340
void SetDataDir(std::string directory)
Set the data directory where reference trace files can be found.
Definition: test.cc:465
void Run(TestRunnerImpl *runner)
Actually run this TestCase.
Definition: test.cc:347
TestCase(const TestCase &)=delete
TestCase & operator=(const TestCase &)=delete
bool MustContinueOnFailure(void) const
Check if this run should continue on failure.
Definition: test.cc:405
bool IsStatusFailure(void) const
Check if any tests failed.
Definition: test.cc:452
struct Result * m_result
Results data.
Definition: test.h:1175
std::string GetName(void) const
Definition: test.cc:370
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:382
A runner to execute tests.
Definition: test.h:1231
static int Run(int argc, char *argv[])
Run the requested suite of tests, according to the given command line arguments.
Definition: test.cc:1116
Container for all tests.
Definition: test.cc:139
A suite of tests to run.
Definition: test.h:1188
Type
Type of test.
Definition: test.h:1195
@ EXAMPLE
This test suite implements an Example Test.
Definition: test.h:1199
@ PERFORMANCE
This test suite implements a Performance Test.
Definition: test.h:1200
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1197
@ SYSTEM
This test suite implements a System Test.
Definition: test.h:1198
TestSuite::Type m_type
Type of this TestSuite.
Definition: test.h:1222
TestSuite(std::string name, Type type=UNIT)
Construct a new test suite.
Definition: test.cc:483
virtual void DoRun(void)
Implementation to actually run this TestCase.
Definition: test.cc:499
TestSuite::Type GetTestType(void)
get the kind of test this test suite implements
Definition: test.cc:492
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1251
std::vector< T > TestVector
Container type.
Definition: test.h:1293
TestVectors & operator=(const TestVectors &)=delete
T Get(std::size_t i) const
Get the i'th test vector.
Definition: test.h:1331
std::size_t GetN(void) const
Get the total number of test vectors.
Definition: test.h:1324
TestVectors(const TestVectors &)=delete
TestVectors()
Constructor.
Definition: test.h:1298
void Reserve(uint32_t reserve)
Set the expected length of this vector.
Definition: test.h:1304
std::size_t Add(T vector)
Definition: test.h:1315
TestVector m_vectors
The list of test vectors.
Definition: test.h:1294
virtual ~TestVectors()
Virtual destructor.
Definition: test.h:1310
#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:44
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.