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
32
55namespace ns3 {
56
58namespace 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
977bool TestDoubleIsEqual (const double a, const double b,
979
980class TestRunnerImpl;
981
994{
995public:
998 {
999 QUICK = 1,
1001 TAKES_FOREVER = 3
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
1018protected:
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);
1125private:
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;
1176 std::string m_name;
1178};
1179
1187class TestSuite : public TestCase
1188{
1189public:
1194 enum Type
1195 {
1196 ALL = 0,
1202
1209 TestSuite (std::string name, Type type = UNIT);
1210
1217
1218private:
1219 // Inherited
1220 virtual void DoRun (void);
1221
1223};
1224
1231{
1232public:
1241 static int Run (int argc, char *argv[]);
1242};
1243
1249template <typename T>
1251{
1252public:
1260 virtual ~TestVectors ();
1261
1262 // Delete copy constructor and assignment operator to avoid misuse
1263 TestVectors (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
1292private:
1293 typedef std::vector<T> TestVector;
1295};
1296
1297template <typename T>
1299 : m_vectors ()
1300{}
1301
1302template <typename T>
1303void
1305{
1306 m_vectors.reserve (reserve);
1307}
1308
1309template <typename T>
1311{}
1312
1313template <typename T>
1314std::size_t
1316{
1317 std::size_t index = m_vectors.size ();
1318 m_vectors.push_back (vector);
1319 return index;
1320}
1321
1322template <typename T>
1323std::size_t
1325{
1326 return m_vectors.size ();
1327}
1328
1329template <typename T>
1330T
1331TestVectors<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
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
TestCase & operator=(const TestCase &)=delete
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:1115
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
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
TestVectors & operator=(const TestVectors &)=delete
#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.