A Discrete-Event Network Simulator
API
callback-test-suite.cc
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 #include "ns3/test.h"
20 #include "ns3/callback.h"
21 #include "ns3/unused.h"
22 #include <stdint.h>
23 
24 using namespace ns3;
25 
26 // ===========================================================================
27 // Test the basic Callback mechanism
28 // ===========================================================================
30 {
31 public:
33  virtual ~BasicCallbackTestCase () {}
34 
35  void Target1 (void) { m_test1 = true; }
36  int Target2 (void) { m_test2 = true; return 2; }
37  void Target3 (double a)
38  {
39  NS_UNUSED (a);
40  m_test3 = true;
41  }
42  int Target4 (double a, int b)
43  {
44  NS_UNUSED (a);
45  NS_UNUSED (b);
46  m_test4 = true;
47  return 4;
48  }
49 
50 private:
51  virtual void DoRun (void);
52  virtual void DoSetup (void);
53 
54  bool m_test1;
55  bool m_test2;
56  bool m_test3;
57  bool m_test4;
58 };
59 
60 static bool gBasicCallbackTest5;
61 static bool gBasicCallbackTest6;
62 static bool gBasicCallbackTest7;
63 
64 void
66 {
67  gBasicCallbackTest5 = true;
68 }
69 
70 void
72 {
73  gBasicCallbackTest6 = true;
74 }
75 
76 int
78 {
79  gBasicCallbackTest7 = true;
80  return a;
81 }
82 
84  : TestCase ("Check basic Callback mechansim")
85 {
86 }
87 
88 void
90 {
91  m_test1 = false;
92  m_test2 = false;
93  m_test3 = false;
94  m_test4 = false;
95  gBasicCallbackTest5 = false;
96  gBasicCallbackTest6 = false;
97  gBasicCallbackTest7 = false;
98 }
99 
100 void
102 {
103  //
104  // Make sure we can declare and compile a Callback pointing to a member
105  // function returning void and execute it.
106  //
108  target1 ();
109  NS_TEST_ASSERT_MSG_EQ (m_test1, true, "Callback did not fire");
110 
111  //
112  // Make sure we can declare and compile a Callback pointing to a member
113  // function that returns an int and execute it.
114  //
115  Callback<int> target2;
117  target2 ();
118  NS_TEST_ASSERT_MSG_EQ (m_test2, true, "Callback did not fire");
119 
120  //
121  // Make sure we can declare and compile a Callback pointing to a member
122  // function that returns void, takes a double parameter, and execute it.
123  //
125  target3 (0.0);
126  NS_TEST_ASSERT_MSG_EQ (m_test3, true, "Callback did not fire");
127 
128  //
129  // Make sure we can declare and compile a Callback pointing to a member
130  // function that returns void, takes two parameters, and execute it.
131  //
133  target4 (0.0, 1);
134  NS_TEST_ASSERT_MSG_EQ (m_test4, true, "Callback did not fire");
135 
136  //
137  // Make sure we can declare and compile a Callback pointing to a non-member
138  // function that returns void, and execute it. This is a lower level call
139  // than MakeCallback so we have got to include at least two arguments to make
140  // sure that the constructor is properly disambiguated. If the arguments are
141  // not needed, we just pass in dummy values.
142  //
143  Callback<void> target5 = Callback<void> (&BasicCallbackTarget5, true, true);
144  target5 ();
145  NS_TEST_ASSERT_MSG_EQ (gBasicCallbackTest5, true, "Callback did not fire");
146 
147  //
148  // Make sure we can declare and compile a Callback pointing to a non-member
149  // function that returns void, takes one integer argument and execute it.
150  // We also need to provide two dummy arguments to the constructor here.
151  //
153  target6 (1);
154  NS_TEST_ASSERT_MSG_EQ (gBasicCallbackTest6, true, "Callback did not fire");
155 
156  //
157  // Make sure we can declare and compile a Callback pointing to a non-member
158  // function that returns int, takes one integer argument and execute it.
159  // We also need to provide two dummy arguments to the constructor here.
160  //
162  target7 (1);
163  NS_TEST_ASSERT_MSG_EQ (gBasicCallbackTest7, true, "Callback did not fire");
164 }
165 
166 // ===========================================================================
167 // Test the MakeCallback mechanism
168 // ===========================================================================
170 {
171 public:
173  virtual ~MakeCallbackTestCase () {}
174 
175  void Target1 (void) { m_test1 = true; }
176  int Target2 (void) { m_test2 = true; return 2; }
177  void Target3 (double a)
178  {
179  NS_UNUSED (a);
180  m_test3 = true;
181  }
182  int Target4 (double a, int b)
183  {
184  NS_UNUSED (a);
185  NS_UNUSED (b);
186  m_test4 = true;
187  return 4;
188  }
189 
190 private:
191  virtual void DoRun (void);
192  virtual void DoSetup (void);
193 
194  bool m_test1;
195  bool m_test2;
196  bool m_test3;
197  bool m_test4;
198 };
199 
200 static bool gMakeCallbackTest5;
201 static bool gMakeCallbackTest6;
202 static bool gMakeCallbackTest7;
203 
204 void
206 {
207  gMakeCallbackTest5 = true;
208 }
209 
210 void
212 {
213  gMakeCallbackTest6 = true;
214 }
215 
216 int
218 {
219  gMakeCallbackTest7 = true;
220  return a;
221 }
222 
224  : TestCase ("Check MakeCallback() mechanism")
225 {
226 }
227 
228 void
230 {
231  m_test1 = false;
232  m_test2 = false;
233  m_test3 = false;
234  m_test4 = false;
235  gMakeCallbackTest5 = false;
236  gMakeCallbackTest6 = false;
237  gMakeCallbackTest7 = false;
238 }
239 
240 void
242 {
243  //
244  // Make sure we can declare and make a Callback pointing to a member
245  // function returning void and execute it.
246  //
248  target1 ();
249  NS_TEST_ASSERT_MSG_EQ (m_test1, true, "Callback did not fire");
250 
251  //
252  // Make sure we can declare and make a Callback pointing to a member
253  // function that returns an int and execute it.
254  //
256  target2 ();
257  NS_TEST_ASSERT_MSG_EQ (m_test2, true, "Callback did not fire");
258 
259  //
260  // Make sure we can declare and make a Callback pointing to a member
261  // function that returns void, takes a double parameter, and execute it.
262  //
264  target3 (0.0);
265  NS_TEST_ASSERT_MSG_EQ (m_test3, true, "Callback did not fire");
266 
267  //
268  // Make sure we can declare and make a Callback pointing to a member
269  // function that returns void, takes two parameters, and execute it.
270  //
272  target4 (0.0, 1);
273  NS_TEST_ASSERT_MSG_EQ (m_test4, true, "Callback did not fire");
274 
275  //
276  // Make sure we can declare and make a Callback pointing to a non-member
277  // function that returns void, and execute it. This uses a higher level call
278  // than in the basic tests so we do not need to include any dummy arguments
279  // here.
280  //
282  target5 ();
283  NS_TEST_ASSERT_MSG_EQ (gMakeCallbackTest5, true, "Callback did not fire");
284 
285  //
286  // Make sure we can declare and compile a Callback pointing to a non-member
287  // function that returns void, takes one integer argument and execute it.
288  // This uses a higher level call than in the basic tests so we do not need to
289  // include any dummy arguments here.
290  //
292  target6 (1);
293  NS_TEST_ASSERT_MSG_EQ (gMakeCallbackTest6, true, "Callback did not fire");
294 
295  //
296  // Make sure we can declare and compile a Callback pointing to a non-member
297  // function that returns int, takes one integer argument and execute it.
298  // This uses a higher level call than in the basic tests so we do not need to
299  // include any dummy arguments here.
300  //
302  target7 (1);
303  NS_TEST_ASSERT_MSG_EQ (gMakeCallbackTest7, true, "Callback did not fire");
304 }
305 
306 // ===========================================================================
307 // Test the MakeBoundCallback mechanism
308 // ===========================================================================
310 {
311 public:
314 
315 private:
316  virtual void DoRun (void);
317  virtual void DoSetup (void);
318 };
319 
342 
343 void
345 {
347 }
348 
349 void
351 {
353 }
354 
355 int
356 MakeBoundCallbackTarget3 (bool *a, int b)
357 {
360  return 1234;
361 }
362 
363 void
365 {
368 }
369 
370 int
372 {
375  return 1234;
376 }
377 
378 int
379 MakeBoundCallbackTarget6 (int a, int b, int c)
380 {
384  return 1234;
385 }
386 
387 void
388 MakeBoundCallbackTarget7 (int a, int b, int c)
389 {
393 }
394 
395 int
396 MakeBoundCallbackTarget8 (int a, int b, int c)
397 {
401  return 1234;
402 }
403 
404 int
405 MakeBoundCallbackTarget9 (int a, int b, int c, int d)
406 {
411  return 1234;
412 }
413 
415  : TestCase ("Check MakeBoundCallback() mechanism")
416 {
417 }
418 
419 void
421 {
444 }
445 
446 void
448 {
449  //
450  // This is slightly tricky to explain. A bound Callback allows us to package
451  // up arguments for use later. The arguments are bound when the callback is
452  // created and the code that fires the Callback does not know they are there.
453  //
454  // Since the callback is *declared* according to the way it will be used, the
455  // arguments are not seen there. However, the target function of the callback
456  // will have the provided arguments present. The MakeBoundCallback template
457  // function is what connects the two together and where you provide the
458  // arguments to be bound.
459  //
460  // Here we declare a Callback that returns a void and takes no parameters.
461  // MakeBoundCallback connects this Callback to a target function that returns
462  // void and takes an integer argument. That integer argument is bound to the
463  // value 1234. When the Callback is fired, no integer argument is provided
464  // directly. The argument is provided by bound Callback mechanism.
465  //
467  target1 ();
468  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest1, 1234, "Callback did not fire or binding not correct");
469 
470  //
471  // Make sure we can bind a pointer value (a common use case).
472  //
473  bool a;
475  target2 ();
476  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest2, &a, "Callback did not fire or binding not correct");
477 
478  //
479  // Make sure we can mix and match bound and unbound arguments. This callback
480  // returns an integer so we should see that appear.
481  //
483  int result = target3 (2468);
484  NS_TEST_ASSERT_MSG_EQ (result, 1234, "Return value of callback not correct");
485  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest3a, &a, "Callback did not fire or binding not correct");
486  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest3b, 2468, "Callback did not fire or argument not correct");
487 
488  //
489  // Test the TwoBound variant
490  //
492  target4 ();
493  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest4a, 3456, "Callback did not fire or binding not correct");
494  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest4b, 5678, "Callback did not fire or binding not correct");
495 
497  int resultTwoA = target5 ();
498  NS_TEST_ASSERT_MSG_EQ (resultTwoA, 1234, "Return value of callback not correct");
499  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest5a, 3456, "Callback did not fire or binding not correct");
500  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest5b, 5678, "Callback did not fire or binding not correct");
501 
503  int resultTwoB = target6 (6789);
504  NS_TEST_ASSERT_MSG_EQ (resultTwoB, 1234, "Return value of callback not correct");
505  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest6a, 3456, "Callback did not fire or binding not correct");
506  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest6b, 5678, "Callback did not fire or binding not correct");
507  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest6c, 6789, "Callback did not fire or argument not correct");
508 
509  //
510  // Test the ThreeBound variant
511  //
512  Callback<void> target7 = MakeBoundCallback (&MakeBoundCallbackTarget7, 2345, 3456, 4567);
513  target7 ();
514  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest7a, 2345, "Callback did not fire or binding not correct");
515  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest7b, 3456, "Callback did not fire or binding not correct");
516  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest7c, 4567, "Callback did not fire or binding not correct");
517 
518  Callback<int> target8 = MakeBoundCallback (&MakeBoundCallbackTarget8, 2345, 3456, 4567);
519  int resultThreeA = target8 ();
520  NS_TEST_ASSERT_MSG_EQ (resultThreeA, 1234, "Return value of callback not correct");
521  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest8a, 2345, "Callback did not fire or binding not correct");
522  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest8b, 3456, "Callback did not fire or binding not correct");
523  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest8c, 4567, "Callback did not fire or binding not correct");
524 
525  Callback<int, int> target9 = MakeBoundCallback (&MakeBoundCallbackTarget9, 2345, 3456, 4567);
526  int resultThreeB = target9 (5678);
527  NS_TEST_ASSERT_MSG_EQ (resultThreeB, 1234, "Return value of callback not correct");
528  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest9a, 2345, "Callback did not fire or binding not correct");
529  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest9b, 3456, "Callback did not fire or binding not correct");
530  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest9c, 4567, "Callback did not fire or binding not correct");
531  NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest9d, 5678, "Callback did not fire or binding not correct");
532 }
533 
534 // ===========================================================================
535 // Test the Nullify mechanism
536 // ===========================================================================
538 {
539 public:
542 
543  void Target1 (void) { m_test1 = true; }
544 
545 private:
546  virtual void DoRun (void);
547  virtual void DoSetup (void);
548 
549  bool m_test1;
550 };
551 
553  : TestCase ("Check Nullify() and IsNull()")
554 {
555 }
556 
557 void
559 {
560  m_test1 = false;
561 }
562 
563 void
565 {
566  //
567  // Make sure we can declare and make a Callback pointing to a member
568  // function returning void and execute it.
569  //
571  target1 ();
572  NS_TEST_ASSERT_MSG_EQ (m_test1, true, "Callback did not fire");
573 
574  NS_TEST_ASSERT_MSG_EQ (target1.IsNull (), false, "Working Callback reports IsNull()");
575 
576  target1.Nullify ();
577 
578  NS_TEST_ASSERT_MSG_EQ (target1.IsNull (), true, "Nullified Callback reports not IsNull()");
579 }
580 
581 // ===========================================================================
582 // Make sure that various MakeCallback template functions compile and execute.
583 // Doesn't check an results of the execution.
584 // ===========================================================================
586 {
587 public:
590 
591  void Target1 (void) { m_test1 = true; }
592 
593 private:
594  virtual void DoRun (void);
595 
596  bool m_test1;
597 };
598 
599 void TestFZero (void) {}
600 void TestFOne (int) {}
601 void TestFTwo (int, int) {}
602 void TestFThree (int, int, int) {}
603 void TestFFour (int, int, int, int) {}
604 void TestFFive (int, int, int, int, int) {}
605 void TestFSix (int, int, int, int, int, int) {}
606 
607 void TestFROne (int &) {}
608 void TestFRTwo (int &, int &) {}
609 void TestFRThree (int &, int &, int &) {}
610 void TestFRFour (int &, int &, int &, int &) {}
611 void TestFRFive (int &, int &, int &, int &, int &) {}
612 void TestFRSix (int &, int &, int &, int &, int &, int &) {}
613 
615 {
616 public:
617  void PublicParent (void) {}
618 protected:
619  void ProtectedParent (void) {}
620  static void StaticProtectedParent (void) {}
621 private:
622  void PrivateParent (void) {}
623 };
624 
626 {
627 public:
628  void TestZero (void) {}
629  void TestOne (int) {}
630  void TestTwo (int, int) {}
631  void TestThree (int, int, int) {}
632  void TestFour (int, int, int, int) {}
633  void TestFive (int, int, int, int, int) {}
634  void TestSix (int, int, int, int, int, int) {}
635  void TestCZero (void) const {}
636  void TestCOne (int) const {}
637  void TestCTwo (int, int) const {}
638  void TestCThree (int, int, int) const {}
639  void TestCFour (int, int, int, int) const {}
640  void TestCFive (int, int, int, int, int) const {}
641  void TestCSix (int, int, int, int, int, int) const {}
642 
644  {
648  // as expected, fails.
649  // MakeCallback (&CallbackTestParent::PrivateParent, this);
650  // unexpected, but fails too. It does fumble me.
651  // MakeCallback (&CallbackTestParent::ProtectedParent, this);
652  }
653 
654 };
655 
657  : TestCase ("Check various MakeCallback() template functions")
658 {
659 }
660 
661 void
663 {
664  CallbackTestClass that;
665 
673 
681 
689 
696 
702 
708 
709  that.CheckParentalRights ();
710 }
711 
712 // ===========================================================================
713 // The Test Suite that glues all of the Test Cases together.
714 // ===========================================================================
716 {
717 public:
719 };
720 
722  : TestSuite ("callback", UNIT)
723 {
724  AddTestCase (new BasicCallbackTestCase, TestCase::QUICK);
725  AddTestCase (new MakeCallbackTestCase, TestCase::QUICK);
726  AddTestCase (new MakeBoundCallbackTestCase, TestCase::QUICK);
727  AddTestCase (new NullifyCallbackTestCase, TestCase::QUICK);
728  AddTestCase (new MakeCallbackTemplatesTestCase, TestCase::QUICK);
729 }
730 
void MakeBoundCallbackTarget2(bool *a)
static int gMakeBoundCallbackTest5a
static int gMakeBoundCallbackTest5b
void MakeBoundCallbackTarget4(int a, int b)
void TestCThree(int, int, int) const
void TestFThree(int, int, int)
void TestFRThree(int &, int &, int &)
static int gMakeBoundCallbackTest9c
void TestFROne(int &)
A suite of tests to run.
Definition: test.h:1342
static int gMakeBoundCallbackTest8a
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1686
void TestFRFive(int &, int &, int &, int &, int &)
#define NS_UNUSED(x)
Mark a local variable as unused.
Definition: unused.h:36
static int gMakeBoundCallbackTest8b
void TestFOne(int)
void TestCTwo(int, int) const
encapsulates test code
Definition: test.h:1155
static int gMakeBoundCallbackTest9b
int MakeBoundCallbackTarget8(int a, int b, int c)
virtual void DoRun(void)
Implementation to actually run this TestCase.
static bool * gMakeBoundCallbackTest2
void TestFFive(int, int, int, int, int)
virtual void DoRun(void)
Implementation to actually run this TestCase.
int MakeBoundCallbackTarget5(int a, int b)
static int gMakeBoundCallbackTest1
static int gMakeBoundCallbackTest6a
static bool gBasicCallbackTest5
static int gMakeBoundCallbackTest8c
int Target4(double a, int b)
void TestSix(int, int, int, int, int, int)
static int gMakeBoundCallbackTest5c
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
static int gMakeBoundCallbackTest9d
void MakeBoundCallbackTarget1(int a)
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:168
void TestFSix(int, int, int, int, int, int)
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
static int gMakeBoundCallbackTest4a
void TestFZero(void)
void MakeCallbackTarget6(int)
int MakeBoundCallbackTarget6(int a, int b, int c)
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
static CallbackTestSuite CallbackTestSuite
static bool gBasicCallbackTest6
void BasicCallbackTarget6(int)
void MakeBoundCallbackTarget7(int a, int b, int c)
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
static int gMakeBoundCallbackTest7a
static bool gBasicCallbackTest7
Every class exported by the ns3 library is enclosed in the ns3 namespace.
int BasicCallbackTarget7(int a)
void TestCOne(int) const
void TestFive(int, int, int, int, int)
static int gMakeBoundCallbackTest7c
void TestFTwo(int, int)
static bool gMakeCallbackTest5
static int gMakeBoundCallbackTest9a
void TestCSix(int, int, int, int, int, int) const
void TestCZero(void) const
static void StaticProtectedParent(void)
int MakeCallbackTarget7(int a)
void TestFRSix(int &, int &, int &, int &, int &, int &)
void BasicCallbackTarget5(void)
int MakeBoundCallbackTarget9(int a, int b, int c, int d)
void TestFRFour(int &, int &, int &, int &)
void TestFour(int, int, int, int)
static int gMakeBoundCallbackTest7b
void TestFRTwo(int &, int &)
static int gMakeBoundCallbackTest6b
void TestFFour(int, int, int, int)
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
void Nullify(void)
Discard the implementation, set it to null.
Definition: callback.h:1274
static bool gMakeCallbackTest6
static int gMakeBoundCallbackTest6c
virtual void DoSetup(void)
Implementation to do any local setup required for this TestCase.
static int gMakeBoundCallbackTest4b
virtual void DoRun(void)
Implementation to actually run this TestCase.
static bool gMakeCallbackTest7
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1270
void TestCFour(int, int, int, int) const
int Target4(double a, int b)
static int gMakeBoundCallbackTest3b
void MakeCallbackTarget5(void)
int MakeBoundCallbackTarget3(bool *a, int b)
void TestCFive(int, int, int, int, int) const
void TestThree(int, int, int)
static bool * gMakeBoundCallbackTest3a