A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 #include "deprecated.h"
33 
40 //
41 // Note on below macros:
42 //
43 // When multiple statements are used in a macro, they should be bound together
44 // in a loop syntactically, so the macro can appear safely inside if clauses
45 // or other places that expect a single statement or a statement block. The
46 // "strange" do while construct is a generally expected best practice for
47 // defining a robust macro.
48 //
49 
55 #define ASSERT_ON_FAILURE \
56  do { \
57  if (MustAssertOnFailure ()) \
58  { \
59  *(volatile int *)0 = 0; \
60  } \
61  } while (false)
62 
68 #define CONTINUE_ON_FAILURE \
69  do { \
70  if (!MustContinueOnFailure ()) \
71  { \
72  return; \
73  } \
74  } while (false)
75 
81 #define CONTINUE_ON_FAILURE_RETURNS_BOOL \
82  do { \
83  if (!MustContinueOnFailure ()) \
84  { \
85  return IsStatusFailure (); \
86  } \
87  } while (false)
88 
89 
90 
91 // ===========================================================================
92 // Test for equality (generic version)
93 // ===========================================================================
94 
101 #define NS_TEST_ASSERT_MSG_EQ_INTERNAL(actual, limit, msg, file, line) \
102  do { \
103  if (!((actual) == (limit))) \
104  { \
105  ASSERT_ON_FAILURE; \
106  std::ostringstream msgStream; \
107  msgStream << msg; \
108  std::ostringstream actualStream; \
109  actualStream << actual; \
110  std::ostringstream limitStream; \
111  limitStream << limit; \
112  ReportTestFailure (std::string (#actual) + " (actual) == " + \
113  std::string (#limit) + " (limit)", \
114  actualStream.str (), limitStream.str (), \
115  msgStream.str (), file, line); \
116  CONTINUE_ON_FAILURE; \
117  } \
118  } while (false)
119 
148 #define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg) \
149  NS_TEST_ASSERT_MSG_EQ_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
150 
157 #define NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL_INTERNAL(actual, limit, msg, file, line) \
158  do { \
159  if (!((actual) == (limit))) \
160  { \
161  ASSERT_ON_FAILURE; \
162  std::ostringstream msgStream; \
163  msgStream << msg; \
164  std::ostringstream actualStream; \
165  actualStream << actual; \
166  std::ostringstream limitStream; \
167  limitStream << limit; \
168  ReportTestFailure (std::string (#actual) + " (actual) == " + \
169  std::string (#limit) + " (limit)", \
170  actualStream.str (), limitStream.str (), \
171  msgStream.str (), file, line); \
172  CONTINUE_ON_FAILURE_RETURNS_BOOL; \
173  } \
174  } while (false)
175 
207 #define NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL(actual, limit, msg) \
208  NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
209 
219 #define NS_TEST_EXPECT_MSG_EQ_INTERNAL(actual, limit, msg, file, line) \
220  do { \
221  if (!((actual) == (limit))) \
222  { \
223  ASSERT_ON_FAILURE; \
224  std::ostringstream msgStream; \
225  msgStream << msg; \
226  std::ostringstream actualStream; \
227  actualStream << actual; \
228  std::ostringstream limitStream; \
229  limitStream << limit; \
230  ReportTestFailure (std::string (#actual) + " (actual) == " + \
231  std::string (#limit) + " (limit)", \
232  actualStream.str (), limitStream.str (), \
233  msgStream.str (), file, line); \
234  } \
235  } while (false)
236 
265 #define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg) \
266  NS_TEST_EXPECT_MSG_EQ_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
267 
268 // ===========================================================================
269 // Test for equality with a provided tolerance (use for floating point
270 // comparisons -- both float and double)
271 // ===========================================================================
272 
279 #define NS_TEST_ASSERT_MSG_EQ_TOL_INTERNAL(actual, limit, tol, msg, file, line) \
280  do { \
281  if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
282  { \
283  ASSERT_ON_FAILURE; \
284  std::ostringstream msgStream; \
285  msgStream << msg; \
286  std::ostringstream actualStream; \
287  actualStream << actual; \
288  std::ostringstream limitStream; \
289  limitStream << limit << " +- " << tol; \
290  std::ostringstream condStream; \
291  condStream << #actual << " (actual) < " << #limit \
292  << " (limit) + " << #tol << " (tol) && " \
293  << #actual << " (actual) > " << #limit \
294  << " (limit) - " << #tol << " (tol)"; \
295  ReportTestFailure (condStream.str (), actualStream.str (), \
296  limitStream.str (), msgStream.str (), \
297  file, line); \
298  CONTINUE_ON_FAILURE; \
299  } \
300  } while (false)
301 
355 #define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg) \
356  NS_TEST_ASSERT_MSG_EQ_TOL_INTERNAL (actual, limit, tol, msg, __FILE__, __LINE__)
357 
364 #define NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL_INTERNAL(actual, limit, tol, msg, file, line) \
365  do { \
366  if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
367  { \
368  ASSERT_ON_FAILURE; \
369  std::ostringstream msgStream; \
370  msgStream << msg; \
371  std::ostringstream actualStream; \
372  actualStream << actual; \
373  std::ostringstream limitStream; \
374  limitStream << limit << " +- " << tol; \
375  std::ostringstream condStream; \
376  condStream << #actual << " (actual) < " << #limit \
377  << " (limit) + " << #tol << " (tol) && " \
378  << #actual << " (actual) > " << #limit \
379  << " (limit) - " << #tol << " (tol)"; \
380  ReportTestFailure (condStream.str (), actualStream.str (), \
381  limitStream.str (), msgStream.str (), \
382  file, line); \
383  CONTINUE_ON_FAILURE_RETURNS_BOOL; \
384  } \
385  } while (false)
386 
443 #define NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL(actual, limit, tol, msg) \
444  NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL_INTERNAL (actual, limit, tol, msg, __FILE__, __LINE__)
445 
455 #define NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL(actual, limit, tol, msg, file, line) \
456  do { \
457  if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
458  { \
459  ASSERT_ON_FAILURE; \
460  std::ostringstream msgStream; \
461  msgStream << msg; \
462  std::ostringstream actualStream; \
463  actualStream << actual; \
464  std::ostringstream limitStream; \
465  limitStream << limit << " +- " << tol; \
466  std::ostringstream condStream; \
467  condStream << #actual << " (actual) < " << #limit \
468  << " (limit) + " << #tol << " (tol) && " \
469  << #actual << " (actual) > " << #limit \
470  << " (limit) - " << #tol << " (tol)"; \
471  ReportTestFailure (condStream.str (), actualStream.str (), \
472  limitStream.str (), msgStream.str (), \
473  file, line); \
474  } \
475  } while (false)
476 
530 #define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg) \
531  NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (actual, limit, tol, msg, __FILE__, __LINE__)
532 
533 // ===========================================================================
534 // Test for inequality
535 // ===========================================================================
536 
543 #define NS_TEST_ASSERT_MSG_NE_INTERNAL(actual, limit, msg, file, line) \
544  do { \
545  if (!((actual) != (limit))) \
546  { \
547  ASSERT_ON_FAILURE; \
548  std::ostringstream msgStream; \
549  msgStream << msg; \
550  std::ostringstream actualStream; \
551  actualStream << actual; \
552  std::ostringstream limitStream; \
553  limitStream << limit; \
554  ReportTestFailure (std::string (#actual) + " (actual) != " + \
555  std::string (#limit) + " (limit)", \
556  actualStream.str (), limitStream.str (), \
557  msgStream.str (), file, line); \
558  CONTINUE_ON_FAILURE; \
559  } \
560  } while (false)
561 
589 #define NS_TEST_ASSERT_MSG_NE(actual, limit, msg) \
590  NS_TEST_ASSERT_MSG_NE_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
591 
598 #define NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL_INTERNAL(actual, limit, msg, file, line) \
599  do { \
600  if (!((actual) != (limit))) \
601  { \
602  ASSERT_ON_FAILURE; \
603  std::ostringstream msgStream; \
604  msgStream << msg; \
605  std::ostringstream actualStream; \
606  actualStream << actual; \
607  std::ostringstream limitStream; \
608  limitStream << limit; \
609  ReportTestFailure (std::string (#actual) + " (actual) != " + \
610  std::string (#limit) + " (limit)", \
611  actualStream.str (), limitStream.str (), \
612  msgStream.str (), file, line); \
613  CONTINUE_ON_FAILURE_RETURNS_BOOL; \
614  } \
615  } while (false)
616 
647 #define NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL(actual, limit, msg) \
648  NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
649 
659 #define NS_TEST_EXPECT_MSG_NE_INTERNAL(actual, limit, msg, file, line) \
660  do { \
661  if (!((actual) != (limit))) \
662  { \
663  ASSERT_ON_FAILURE; \
664  std::ostringstream msgStream; \
665  msgStream << msg; \
666  std::ostringstream actualStream; \
667  actualStream << actual; \
668  std::ostringstream limitStream; \
669  limitStream << limit; \
670  ReportTestFailure (std::string (#actual) + " (actual) != " + \
671  std::string (#limit) + " (limit)", \
672  actualStream.str (), limitStream.str (), \
673  msgStream.str (), file, line); \
674  } \
675  } while (false)
676 
704 #define NS_TEST_EXPECT_MSG_NE(actual, limit, msg) \
705  NS_TEST_EXPECT_MSG_NE_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
706 
707 // ===========================================================================
708 // Test for less than relation
709 // ===========================================================================
710 
717 #define NS_TEST_ASSERT_MSG_LT_INTERNAL(actual, limit, msg, file, line) \
718  do { \
719  if (!((actual) < (limit))) \
720  { \
721  ASSERT_ON_FAILURE; \
722  std::ostringstream msgStream; \
723  msgStream << msg; \
724  std::ostringstream actualStream; \
725  actualStream << actual; \
726  std::ostringstream limitStream; \
727  limitStream << limit; \
728  ReportTestFailure (std::string (#actual) + " (actual) < " + \
729  std::string (#limit) + " (limit)", \
730  actualStream.str (), limitStream.str (), \
731  msgStream.str (), file, line); \
732  CONTINUE_ON_FAILURE; \
733  } \
734  } while (false)
735 
753 #define NS_TEST_ASSERT_MSG_LT(actual, limit, msg) \
754  NS_TEST_ASSERT_MSG_LT_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
755 
764 #define NS_TEST_EXPECT_MSG_LT_INTERNAL(actual, limit, msg, file, line) \
765  do { \
766  if (!((actual) < (limit))) \
767  { \
768  ASSERT_ON_FAILURE; \
769  std::ostringstream msgStream; \
770  msgStream << msg; \
771  std::ostringstream actualStream; \
772  actualStream << actual; \
773  std::ostringstream limitStream; \
774  limitStream << limit; \
775  ReportTestFailure (std::string (#actual) + " (actual) < " + \
776  std::string (#limit) + " (limit)", \
777  actualStream.str (), limitStream.str (), \
778  msgStream.str (), file, line); \
779  } \
780  } while (false)
781 
798 #define NS_TEST_EXPECT_MSG_LT(actual, limit, msg) \
799  NS_TEST_EXPECT_MSG_LT_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
800 
801 // ===========================================================================
802 // Test for greater than relation
803 // ===========================================================================
804 
811 #define NS_TEST_ASSERT_MSG_GT_INTERNAL(actual, limit, msg, file, line) \
812  do { \
813  if (!((actual) > (limit))) \
814  { \
815  ASSERT_ON_FAILURE; \
816  std::ostringstream msgStream; \
817  msgStream << msg; \
818  std::ostringstream actualStream; \
819  actualStream << actual; \
820  std::ostringstream limitStream; \
821  limitStream << limit; \
822  ReportTestFailure (std::string (#actual) + " (actual) > " + \
823  std::string (#limit) + " (limit)", \
824  actualStream.str (), limitStream.str (), \
825  msgStream.str (), file, line); \
826  CONTINUE_ON_FAILURE; \
827  } \
828  } while (false)
829 
847 #define NS_TEST_ASSERT_MSG_GT(actual, limit, msg) \
848  NS_TEST_ASSERT_MSG_GT_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
849 
858 #define NS_TEST_EXPECT_MSG_GT_INTERNAL(actual, limit, msg, file, line) \
859  do { \
860  if (!((actual) > (limit))) \
861  { \
862  ASSERT_ON_FAILURE; \
863  std::ostringstream msgStream; \
864  msgStream << msg; \
865  std::ostringstream actualStream; \
866  actualStream << actual; \
867  std::ostringstream limitStream; \
868  limitStream << limit; \
869  ReportTestFailure (std::string (#actual) + " (actual) > " + \
870  std::string (#limit) + " (limit)", \
871  actualStream.str (), limitStream.str (), \
872  msgStream.str (), file, line); \
873  } \
874  } while (false)
875 
892 #define NS_TEST_EXPECT_MSG_GT(actual, limit, msg) \
893  NS_TEST_EXPECT_MSG_GT_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
894 
895 namespace ns3 {
896 
915 bool TestDoubleIsEqual (const double a, const double b,
916  const double epsilon = std::numeric_limits<double>::epsilon ());
917 
918 class TestRunnerImpl;
919 
929 class TestCase
930 {
931 public:
937  QUICK = 1,
938  EXTENSIVE = 2,
940  };
941 
945  virtual ~TestCase ();
946 
950  std::string GetName (void) const;
951 
952 protected:
956  TestCase (std::string name);
957 
966  void AddTestCase (TestCase *testCase) NS_DEPRECATED;
967 
974  void AddTestCase (TestCase *testCase, enum TestDuration duration);
975 
988  void SetDataDir (std::string directory);
989 
994  bool GetErrorStatus (void) const NS_DEPRECATED;
998  bool IsStatusFailure (void) const;
1002  bool IsStatusSuccess (void) const;
1003 
1007  TestCase * GetParent () const;
1008 
1018  void ReportTestFailure (std::string cond, std::string actual,
1019  std::string limit, std::string message,
1020  std::string file, int32_t line);
1024  bool MustAssertOnFailure (void) const;
1028  bool MustContinueOnFailure (void) const;
1033  std::string CreateDataDirFilename (std::string filename);
1040  std::string CreateTempDirFilename (std::string filename);
1042 private:
1043  friend class TestRunnerImpl;
1044 
1051  virtual void DoSetup (void);
1052 
1058  virtual void DoRun (void) = 0;
1059 
1065  virtual void DoTeardown (void);
1066 
1070  TestCase (TestCase& tc);
1074  TestCase& operator= (TestCase& tc);
1075 
1076  // methods called by TestRunnerImpl
1082  void Run (TestRunnerImpl *runner);
1086  bool IsFailed (void) const;
1087 
1088  // Forward declaration is enough, since we only include a pointer here
1089  struct Result;
1090 
1091  TestCase *m_parent;
1092  std::vector<TestCase *> m_children;
1093  std::string m_dataDir;
1094  TestRunnerImpl *m_runner;
1095  struct Result *m_result;
1096  std::string m_name;
1098 };
1099 
1105 class TestSuite : public TestCase
1106 {
1107 public:
1112  enum Type {
1113  ALL = 0,
1114  BVT = 1,
1118  PERFORMANCE
1119  };
1120 
1127  TestSuite (std::string name, Type type = UNIT);
1128 
1134  TestSuite::Type GetTestType (void);
1135 
1136 private:
1137  virtual void DoRun (void);
1138 
1139 
1141 };
1142 
1149 {
1150 public:
1158  static int Run (int argc, char *argv[]);
1159 };
1160 
1166 template <typename T>
1168 {
1169 public:
1173  TestVectors ();
1177  virtual ~TestVectors ();
1178 
1182  void Reserve (uint32_t reserve);
1183 
1188  uint32_t Add (T vector);
1189 
1193  uint32_t GetN (void) const;
1199  T Get (uint32_t i) const;
1200 
1201 private:
1205  TestVectors (const TestVectors& tv);
1209  TestVectors& operator= (const TestVectors& tv);
1213  bool operator== (const TestVectors& tv) const;
1214 
1215  typedef std::vector<T> TestVector;
1217 };
1218 
1219 template <typename T>
1221  : m_vectors ()
1222 {
1223 }
1224 
1225 template <typename T>
1226 void
1227 TestVectors<T>::Reserve (uint32_t reserve)
1228 {
1229  m_vectors.reserve (reserve);
1230 }
1231 
1232 template <typename T>
1234 {
1235 }
1236 
1237 template <typename T>
1238 uint32_t
1240 {
1241  uint32_t index = m_vectors.size ();
1242  m_vectors.push_back (vector);
1243  return index;
1244 }
1245 
1246 template <typename T>
1247 uint32_t
1249 {
1250  return m_vectors.size ();
1251 }
1252 
1253 template <typename T>
1254 T
1255 TestVectors<T>::Get (uint32_t i) const
1256 {
1257  NS_ABORT_MSG_UNLESS (m_vectors.size () > i, "TestVectors::Get(): Bad index");
1258  return m_vectors[i];
1259 }
1260 
1261 } // namespace ns3
1262 
1263 #endif /* NS3_TEST_H */
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
Definition: test.cc:361
virtual void DoTeardown(void)
Implementation to do any local setup required for this TestCase.
Definition: test.cc:366
This test suite implements a System Test.
Definition: test.h:1116
#define private
T Get(uint32_t i) const
Get the i'th test vector.
Definition: test.h:1255
virtual ~TestVectors()
Virtual desctructor.
Definition: test.h:1233
A suite of tests to run.
Definition: test.h:1105
A runner to execute tests.
Definition: test.h:1148
void Reserve(uint32_t reserve)
Definition: test.h:1227
Very long running test.
Definition: test.h:939
Type
Type of test.
Definition: test.h:1112
bool IsFailed(void) const
Definition: test.cc:223
std::vector< T > TestVector
Container type.
Definition: test.h:1215
encapsulates test code
Definition: test.h:929
enum TestDuration m_duration
TestCase duration.
Definition: test.h:1097
uint32_t GetN(void) const
Definition: test.h:1248
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1167
TestVectors()
Constructor.
Definition: test.h:1220
TestCase * m_parent
Pointer to my parent TestCase.
Definition: test.h:1089
TestRunnerImpl * m_runner
Pointer to the TestRunner.
Definition: test.h:1094
#define NS_DEPRECATED
Definition: deprecated.h:7
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:36
uint32_t Add(T vector)
Definition: test.h:1239
Medium length test.
Definition: test.h:938
TestSuite::Type m_type
Type of this TestSuite.
Definition: test.h:1140
bool MustAssertOnFailure(void) const
Definition: test.cc:282
TestCase(std::string name)
Definition: test.cc:159
bool GetErrorStatus(void) const NS_DEPRECATED
Definition: test.cc:335
TestDuration
How long the test takes to execute.
Definition: test.h:936
virtual ~TestCase()
Destructor.
Definition: test.cc:170
std::string CreateDataDirFilename(std::string filename)
Definition: test.cc:295
virtual void DoRun(void)=0
Implementation to actually run this TestCase.
struct Result * m_result
Results data.
Definition: test.h:1095
bool IsStatusFailure(void) const
Definition: test.cc:341
TestCase * GetParent() const
Definition: test.cc:259
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:265
void Run(TestRunnerImpl *runner)
Actually run this TestCase.
Definition: test.cc:230
void AddTestCase(TestCase *testCase) NS_DEPRECATED
Add an individual child TestCase case to this TestCase.
Definition: test.cc:184
bool IsStatusSuccess(void) const
Definition: test.cc:347
Fast test.
Definition: test.h:937
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if cond is false.
Definition: abort.h:136
std::string CreateTempDirFilename(std::string filename)
Definition: test.cc:313
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.cc:89
void SetDataDir(std::string directory)
Definition: test.cc:354
TestVector m_vectors
The list of test vectors.
Definition: test.h:1216
std::vector< TestCase * > m_children
Vector of my children.
Definition: test.h:1092
This test suite implements an Example Test.
Definition: test.h:1117
std::string GetName(void) const
Definition: test.cc:253
This test suite implements a Unit Test.
Definition: test.h:1115
std::string m_name
TestCase name.
Definition: test.h:1096
TestCase & operator=(TestCase &tc)
Private, to block copying.
std::string m_dataDir
My data directory.
Definition: test.h:1093
bool MustContinueOnFailure(void) const
Definition: test.cc:288