A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
test.h
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 
34 //
35 // Note on below macros:
36 //
37 // When multiple statements are used in a macro, they should be bound together
38 // in a loop syntactically, so the macro can appear safely inside if clauses
39 // or other places that expect a single statement or a statement block. The
40 // "strange" do while construct is a generally expected best practice for
41 // defining a robust macro.
42 //
43 
44 #define ASSERT_ON_FAILURE \
45  do { \
46  if (MustAssertOnFailure ()) \
47  { \
48  *(volatile int *)0 = 0; \
49  } \
50  } while (false)
51 
52 #define CONTINUE_ON_FAILURE \
53  do { \
54  if (!MustContinueOnFailure ()) \
55  { \
56  return; \
57  } \
58  } while (false)
59 
60 #define CONTINUE_ON_FAILURE_RETURNS_BOOL \
61  do { \
62  if (!MustContinueOnFailure ()) \
63  { \
64  return IsStatusFailure (); \
65  } \
66  } while (false)
67 
68 
69 
70 // ===========================================================================
71 // Test for equality (generic version)
72 // ===========================================================================
73 
77 #define NS_TEST_ASSERT_MSG_EQ_INTERNAL(actual, limit, msg, file, line) \
78  do { \
79  if (!((actual) == (limit))) \
80  { \
81  ASSERT_ON_FAILURE; \
82  std::ostringstream msgStream; \
83  msgStream << msg; \
84  std::ostringstream actualStream; \
85  actualStream << actual; \
86  std::ostringstream limitStream; \
87  limitStream << limit; \
88  ReportTestFailure (std::string (#actual) + " (actual) == " + \
89  std::string (#limit) + " (limit)", \
90  actualStream.str (), limitStream.str (), \
91  msgStream.str (), file, line); \
92  CONTINUE_ON_FAILURE; \
93  } \
94  } while (false)
95 
122 #define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg) \
123  NS_TEST_ASSERT_MSG_EQ_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
124 
128 #define NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL_INTERNAL(actual, limit, msg, file, line) \
129  do { \
130  if (!((actual) == (limit))) \
131  { \
132  ASSERT_ON_FAILURE; \
133  std::ostringstream msgStream; \
134  msgStream << msg; \
135  std::ostringstream actualStream; \
136  actualStream << actual; \
137  std::ostringstream limitStream; \
138  limitStream << limit; \
139  ReportTestFailure (std::string (#actual) + " (actual) == " + \
140  std::string (#limit) + " (limit)", \
141  actualStream.str (), limitStream.str (), \
142  msgStream.str (), file, line); \
143  CONTINUE_ON_FAILURE_RETURNS_BOOL; \
144  } \
145  } while (false)
146 
176 #define NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL(actual, limit, msg) \
177  NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
178 
185 #define NS_TEST_EXPECT_MSG_EQ_INTERNAL(actual, limit, msg, file, line) \
186  do { \
187  if (!((actual) == (limit))) \
188  { \
189  ASSERT_ON_FAILURE; \
190  std::ostringstream msgStream; \
191  msgStream << msg; \
192  std::ostringstream actualStream; \
193  actualStream << actual; \
194  std::ostringstream limitStream; \
195  limitStream << limit; \
196  ReportTestFailure (std::string (#actual) + " (actual) == " + \
197  std::string (#limit) + " (limit)", \
198  actualStream.str (), limitStream.str (), \
199  msgStream.str (), file, line); \
200  } \
201  } while (false)
202 
229 #define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg) \
230  NS_TEST_EXPECT_MSG_EQ_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
231 
232 // ===========================================================================
233 // Test for equality with a provided tolerance (use for floating point
234 // comparisons -- both float and double)
235 // ===========================================================================
236 
240 #define NS_TEST_ASSERT_MSG_EQ_TOL_INTERNAL(actual, limit, tol, msg, file, line) \
241  do { \
242  if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
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 << " +- " << tol; \
251  std::ostringstream condStream; \
252  condStream << #actual << " (actual) < " << #limit \
253  << " (limit) + " << #tol << " (tol) && " \
254  << #actual << " (actual) > " << #limit \
255  << " (limit) - " << #tol << " (tol)"; \
256  ReportTestFailure (condStream.str (), actualStream.str (), \
257  limitStream.str (), msgStream.str (), \
258  file, line); \
259  CONTINUE_ON_FAILURE; \
260  } \
261  } while (false)
262 
311 #define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg) \
312  NS_TEST_ASSERT_MSG_EQ_TOL_INTERNAL (actual, limit, tol, msg, __FILE__, __LINE__)
313 
317 #define NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL_INTERNAL(actual, limit, tol, msg, file, line) \
318  do { \
319  if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
320  { \
321  ASSERT_ON_FAILURE; \
322  std::ostringstream msgStream; \
323  msgStream << msg; \
324  std::ostringstream actualStream; \
325  actualStream << actual; \
326  std::ostringstream limitStream; \
327  limitStream << limit << " +- " << tol; \
328  std::ostringstream condStream; \
329  condStream << #actual << " (actual) < " << #limit \
330  << " (limit) + " << #tol << " (tol) && " \
331  << #actual << " (actual) > " << #limit \
332  << " (limit) - " << #tol << " (tol)"; \
333  ReportTestFailure (condStream.str (), actualStream.str (), \
334  limitStream.str (), msgStream.str (), \
335  file, line); \
336  CONTINUE_ON_FAILURE_RETURNS_BOOL; \
337  } \
338  } while (false)
339 
391 #define NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL(actual, limit, tol, msg) \
392  NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL_INTERNAL (actual, limit, tol, msg, __FILE__, __LINE__)
393 
400 #define NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL(actual, limit, tol, msg, file, line) \
401  do { \
402  if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
403  { \
404  ASSERT_ON_FAILURE; \
405  std::ostringstream msgStream; \
406  msgStream << msg; \
407  std::ostringstream actualStream; \
408  actualStream << actual; \
409  std::ostringstream limitStream; \
410  limitStream << limit << " +- " << tol; \
411  std::ostringstream condStream; \
412  condStream << #actual << " (actual) < " << #limit \
413  << " (limit) + " << #tol << " (tol) && " \
414  << #actual << " (actual) > " << #limit \
415  << " (limit) - " << #tol << " (tol)"; \
416  ReportTestFailure (condStream.str (), actualStream.str (), \
417  limitStream.str (), msgStream.str (), \
418  file, line); \
419  } \
420  } while (false)
421 
470 #define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg) \
471  NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (actual, limit, tol, msg, __FILE__, __LINE__)
472 
473 // ===========================================================================
474 // Test for inequality
475 // ===========================================================================
476 
480 #define NS_TEST_ASSERT_MSG_NE_INTERNAL(actual, limit, msg, file, line) \
481  do { \
482  if (!((actual) != (limit))) \
483  { \
484  ASSERT_ON_FAILURE; \
485  std::ostringstream msgStream; \
486  msgStream << msg; \
487  std::ostringstream actualStream; \
488  actualStream << actual; \
489  std::ostringstream limitStream; \
490  limitStream << limit; \
491  ReportTestFailure (std::string (#actual) + " (actual) != " + \
492  std::string (#limit) + " (limit)", \
493  actualStream.str (), limitStream.str (), \
494  msgStream.str (), file, line); \
495  CONTINUE_ON_FAILURE; \
496  } \
497  } while (false)
498 
524 #define NS_TEST_ASSERT_MSG_NE(actual, limit, msg) \
525  NS_TEST_ASSERT_MSG_NE_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
526 
530 #define NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL_INTERNAL(actual, limit, msg, file, line) \
531  do { \
532  if (!((actual) != (limit))) \
533  { \
534  ASSERT_ON_FAILURE; \
535  std::ostringstream msgStream; \
536  msgStream << msg; \
537  std::ostringstream actualStream; \
538  actualStream << actual; \
539  std::ostringstream limitStream; \
540  limitStream << limit; \
541  ReportTestFailure (std::string (#actual) + " (actual) != " + \
542  std::string (#limit) + " (limit)", \
543  actualStream.str (), limitStream.str (), \
544  msgStream.str (), file, line); \
545  CONTINUE_ON_FAILURE_RETURNS_BOOL; \
546  } \
547  } while (false)
548 
577 #define NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL(actual, limit, msg) \
578  NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
579 
586 #define NS_TEST_EXPECT_MSG_NE_INTERNAL(actual, limit, msg, file, line) \
587  do { \
588  if (!((actual) != (limit))) \
589  { \
590  ASSERT_ON_FAILURE; \
591  std::ostringstream msgStream; \
592  msgStream << msg; \
593  std::ostringstream actualStream; \
594  actualStream << actual; \
595  std::ostringstream limitStream; \
596  limitStream << limit; \
597  ReportTestFailure (std::string (#actual) + " (actual) != " + \
598  std::string (#limit) + " (limit)", \
599  actualStream.str (), limitStream.str (), \
600  msgStream.str (), file, line); \
601  } \
602  } while (false)
603 
629 #define NS_TEST_EXPECT_MSG_NE(actual, limit, msg) \
630  NS_TEST_EXPECT_MSG_NE_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
631 
632 // ===========================================================================
633 // Test for less than relation
634 // ===========================================================================
635 
639 #define NS_TEST_ASSERT_MSG_LT_INTERNAL(actual, limit, msg, file, line) \
640  do { \
641  if (!((actual) < (limit))) \
642  { \
643  ASSERT_ON_FAILURE; \
644  std::ostringstream msgStream; \
645  msgStream << msg; \
646  std::ostringstream actualStream; \
647  actualStream << actual; \
648  std::ostringstream limitStream; \
649  limitStream << limit; \
650  ReportTestFailure (std::string (#actual) + " (actual) < " + \
651  std::string (#limit) + " (limit)", \
652  actualStream.str (), limitStream.str (), \
653  msgStream.str (), file, line); \
654  CONTINUE_ON_FAILURE; \
655  } \
656  } while (false)
657 
673 #define NS_TEST_ASSERT_MSG_LT(actual, limit, msg) \
674  NS_TEST_ASSERT_MSG_LT_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
675 
682 #define NS_TEST_EXPECT_MSG_LT_INTERNAL(actual, limit, msg, file, line) \
683  do { \
684  if (!((actual) < (limit))) \
685  { \
686  ASSERT_ON_FAILURE; \
687  std::ostringstream msgStream; \
688  msgStream << msg; \
689  std::ostringstream actualStream; \
690  actualStream << actual; \
691  std::ostringstream limitStream; \
692  limitStream << limit; \
693  ReportTestFailure (std::string (#actual) + " (actual) < " + \
694  std::string (#limit) + " (limit)", \
695  actualStream.str (), limitStream.str (), \
696  msgStream.str (), file, line); \
697  } \
698  } while (false)
699 
714 #define NS_TEST_EXPECT_MSG_LT(actual, limit, msg) \
715  NS_TEST_EXPECT_MSG_LT_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
716 
717 // ===========================================================================
718 // Test for greater than relation
719 // ===========================================================================
720 
724 #define NS_TEST_ASSERT_MSG_GT_INTERNAL(actual, limit, msg, file, line) \
725  do { \
726  if (!((actual) > (limit))) \
727  { \
728  ASSERT_ON_FAILURE; \
729  std::ostringstream msgStream; \
730  msgStream << msg; \
731  std::ostringstream actualStream; \
732  actualStream << actual; \
733  std::ostringstream limitStream; \
734  limitStream << limit; \
735  ReportTestFailure (std::string (#actual) + " (actual) > " + \
736  std::string (#limit) + " (limit)", \
737  actualStream.str (), limitStream.str (), \
738  msgStream.str (), file, line); \
739  CONTINUE_ON_FAILURE; \
740  } \
741  } while (false)
742 
758 #define NS_TEST_ASSERT_MSG_GT(actual, limit, msg) \
759  NS_TEST_ASSERT_MSG_GT_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
760 
767 #define NS_TEST_EXPECT_MSG_GT_INTERNAL(actual, limit, msg, file, line) \
768  do { \
769  if (!((actual) > (limit))) \
770  { \
771  ASSERT_ON_FAILURE; \
772  std::ostringstream msgStream; \
773  msgStream << msg; \
774  std::ostringstream actualStream; \
775  actualStream << actual; \
776  std::ostringstream limitStream; \
777  limitStream << limit; \
778  ReportTestFailure (std::string (#actual) + " (actual) > " + \
779  std::string (#limit) + " (limit)", \
780  actualStream.str (), limitStream.str (), \
781  msgStream.str (), file, line); \
782  } \
783  } while (false)
784 
799 #define NS_TEST_EXPECT_MSG_GT(actual, limit, msg) \
800  NS_TEST_EXPECT_MSG_GT_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
801 
802 namespace ns3 {
803 
822 bool TestDoubleIsEqual (const double a, const double b,
823  const double epsilon = std::numeric_limits<double>::epsilon ());
824 
825 class TestRunnerImpl;
826 
834 class TestCase
835 {
836 public:
842  QUICK = 1,
843  EXTENSIVE = 2,
845  };
846 
847  virtual ~TestCase ();
848 
849 protected:
853  TestCase (std::string name);
854 
863  void AddTestCase (TestCase *testCase) NS_DEPRECATED;
864 
871  void AddTestCase (TestCase *testCase, enum TestDuration duration);
872 
885  void SetDataDir (std::string directory);
886 
890  bool GetErrorStatus (void) const NS_DEPRECATED;
894  bool IsStatusFailure (void) const;
898  bool IsStatusSuccess (void) const;
899 
903  std::string GetName (void) const;
904 
905  // The methods below are used only by test macros and should not
906  // be used by normal users.
907  void ReportTestFailure (std::string cond, std::string actual,
908  std::string limit, std::string message,
909  std::string file, int32_t line);
910  bool MustAssertOnFailure (void) const;
911  bool MustContinueOnFailure (void) const;
912  std::string CreateDataDirFilename (std::string filename);
913  std::string CreateTempDirFilename (std::string filename);
914 private:
915  friend class TestRunnerImpl;
916 
923  virtual void DoSetup (void);
924 
930  virtual void DoRun (void) = 0;
931 
937  virtual void DoTeardown (void);
938 
939  // forbid copying objects
940  TestCase (TestCase& tc);
941  TestCase& operator= (TestCase& tc);
942 
943  // methods called by TestRunnerImpl
944  void Run (TestRunnerImpl *runner);
945  bool IsFailed (void) const;
946 
947 
948  struct Result;
949 
950  TestCase *m_parent;
951  std::vector<TestCase *> m_children;
952  std::string m_dataDir;
953  TestRunnerImpl *m_runner;
954  struct Result *m_result;
955  std::string m_name;
956  enum TestDuration m_duration;
957 };
958 
962 class TestSuite : public TestCase
963 {
964 public:
969  enum Type {
970  ALL = 0,
971  BVT = 1,
975  PERFORMANCE
976  };
977 
984  TestSuite (std::string name, Type type = UNIT);
985 
991  TestSuite::Type GetTestType (void);
992 
993 private:
994  virtual void DoRun (void);
995 
996 
997  TestSuite::Type m_type;
998 };
999 
1004 {
1005 public:
1006  static int Run (int argc, char *argv[]);
1007 };
1008 
1012 template <typename T>
1014 {
1015 public:
1016  TestVectors ();
1017  virtual ~TestVectors ();
1018 
1019  void Reserve (uint32_t reserve);
1020 
1021  uint32_t Add (T vector);
1022 
1023  uint32_t GetN (void) const;
1024  T Get (uint32_t i) const;
1025 
1026 private:
1027  TestVectors (const TestVectors& tv);
1028  TestVectors& operator= (const TestVectors& tv);
1029  bool operator== (const TestVectors& tv) const;
1030 
1031  typedef std::vector<T> TestVector;
1032  TestVector m_vectors;
1033 };
1034 
1035 template <typename T>
1037  : m_vectors ()
1038 {
1039 }
1040 
1041 template <typename T>
1042 void
1043 TestVectors<T>::Reserve (uint32_t reserve)
1044 {
1045  m_vectors.reserve (reserve);
1046 }
1047 
1048 template <typename T>
1049 TestVectors<T>::~TestVectors ()
1050 {
1051 }
1052 
1053 template <typename T>
1054 uint32_t
1055 TestVectors<T>::Add (T vector)
1056 {
1057  uint32_t index = m_vectors.size ();
1058  m_vectors.push_back (vector);
1059  return index;
1060 }
1061 
1062 template <typename T>
1063 uint32_t
1064 TestVectors<T>::GetN (void) const
1065 {
1066  return m_vectors.size ();
1067 }
1068 
1069 template <typename T>
1070 T
1071 TestVectors<T>::Get (uint32_t i) const
1072 {
1073  NS_ABORT_MSG_UNLESS (m_vectors.size () > i, "TestVectors::Get(): Bad index");
1074  return m_vectors[i];
1075 }
1076 
1077 } // namespace ns3
1078 
1079 #endif /* NS3_TEST_H */
virtual void DoSetup(void)
Implementation to do any local setup required for this test case.
Definition: test.cc:343
virtual void DoTeardown(void)
Implementation to do any local setup required for this test case.
Definition: test.cc:348
A suite of tests to run.
Definition: test.h:962
A runner to execute tests.
Definition: test.h:1003
Medium length test.
Definition: test.h:844
Type
Type of test.
Definition: test.h:969
encapsulates test code
Definition: test.h:834
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if cond is false.
Definition: abort.h:131
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1013
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
Fast test.
Definition: test.h:843
TestCase(std::string name)
Definition: test.cc:147
bool GetErrorStatus(void) const NS_DEPRECATED
Definition: test.cc:317
TestDuration
How long the test takes to execute.
Definition: test.h:841
virtual void DoRun(void)=0
Implementation to actually run this test case.
bool IsStatusFailure(void) const
Definition: test.cc:323
void AddTestCase(TestCase *testCase) NS_DEPRECATED
Add an individual test case to this test suite.
Definition: test.cc:172
bool IsStatusSuccess(void) const
Definition: test.cc:329
void SetDataDir(std::string directory)
Definition: test.cc:336
std::string GetName(void) const
Definition: test.cc:241