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 
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:
837  virtual ~TestCase ();
838 
839 protected:
843  TestCase (std::string name);
844 
850  void AddTestCase (TestCase *testCase);
851 
864  void SetDataDir (std::string directory);
865 
869  bool GetErrorStatus (void) const NS_DEPRECATED;
873  bool IsStatusFailure (void) const;
877  bool IsStatusSuccess (void) const;
878 
882  std::string GetName (void) const;
883 
884  // The methods below are used only by test macros and should not
885  // be used by normal users.
886  void ReportTestFailure (std::string cond, std::string actual,
887  std::string limit, std::string message,
888  std::string file, int32_t line);
889  bool MustAssertOnFailure (void) const;
890  bool MustContinueOnFailure (void) const;
891  std::string CreateDataDirFilename (std::string filename);
892  std::string CreateTempDirFilename (std::string filename);
893 private:
894  friend class TestRunnerImpl;
895 
902  virtual void DoSetup (void);
903 
909  virtual void DoRun (void) = 0;
910 
916  virtual void DoTeardown (void);
917 
918  // forbid copying objects
919  TestCase (TestCase& tc);
921 
922  // methods called by TestRunnerImpl
923  void Run (TestRunnerImpl *runner);
924  bool IsFailed (void) const;
925 
926 
927  struct Result;
928 
930  std::vector<TestCase *> m_children;
931  std::string m_dataDir;
933  struct Result *m_result;
934  std::string m_name;
935 };
936 
940 class TestSuite : public TestCase
941 {
942 public:
947  enum Type {
948  ALL = 0,
949  BVT = 1,
954  };
955 
962  TestSuite (std::string name, Type type = UNIT);
963 
970 
971 private:
972  virtual void DoRun (void);
973 
974 
976 };
977 
982 {
983 public:
984  static int Run (int argc, char *argv[]);
985 };
986 
990 template <typename T>
992 {
993 public:
994  TestVectors ();
995  virtual ~TestVectors ();
996 
997  void Reserve (uint32_t reserve);
998 
999  uint32_t Add (T vector);
1000 
1001  uint32_t GetN (void) const;
1002  T Get (uint32_t i) const;
1003 
1004 private:
1005  TestVectors (const TestVectors& tv);
1006  TestVectors& operator= (const TestVectors& tv);
1007  bool operator== (const TestVectors& tv) const;
1008 
1009  typedef std::vector<T> TestVector;
1011 };
1012 
1013 template <typename T>
1015  : m_vectors ()
1016 {
1017 }
1018 
1019 template <typename T>
1020 void
1021 TestVectors<T>::Reserve (uint32_t reserve)
1022 {
1023  m_vectors.reserve (reserve);
1024 }
1025 
1026 template <typename T>
1028 {
1029 }
1030 
1031 template <typename T>
1032 uint32_t
1034 {
1035  uint32_t index = m_vectors.size ();
1036  m_vectors.push_back (vector);
1037  return index;
1038 }
1039 
1040 template <typename T>
1041 uint32_t
1043 {
1044  return m_vectors.size ();
1045 }
1046 
1047 template <typename T>
1048 T
1049 TestVectors<T>::Get (uint32_t i) const
1050 {
1051  NS_ABORT_MSG_UNLESS (m_vectors.size () > i, "TestVectors::Get(): Bad index");
1052  return m_vectors[i];
1053 }
1054 
1055 } // namespace ns3
1056 
1057 #endif /* NS3_TEST_H */