A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
config-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) 2008 INRIA
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  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #include "ns3/config.h"
21 #include "ns3/test.h"
22 #include "ns3/integer.h"
23 #include "ns3/traced-value.h"
24 #include "ns3/trace-source-accessor.h"
25 #include "ns3/callback.h"
26 
27 #include "ns3/singleton.h"
28 #include "ns3/object.h"
29 #include "ns3/object-vector.h"
30 #include "ns3/names.h"
31 #include "ns3/pointer.h"
32 #include "ns3/log.h"
33 
34 
35 #include <sstream>
36 
37 using namespace ns3;
38 
39 // ===========================================================================
40 // An object with some attributes that we can play with using config.
41 // ===========================================================================
42 class ConfigTestObject : public Object
43 {
44 public:
45  static TypeId GetTypeId (void);
46 
47  void AddNodeA (Ptr<ConfigTestObject> a);
48  void AddNodeB (Ptr<ConfigTestObject> b);
49 
50  void SetNodeA (Ptr<ConfigTestObject> a);
51  void SetNodeB (Ptr<ConfigTestObject> b);
52 
53  int8_t GetA (void) const;
54  int8_t GetB (void) const;
55 
56 private:
57  std::vector<Ptr<ConfigTestObject> > m_nodesA;
58  std::vector<Ptr<ConfigTestObject> > m_nodesB;
61  int8_t m_a;
62  int8_t m_b;
64 };
65 
66 TypeId
68 {
69  static TypeId tid = TypeId ("ConfigTestObject")
70  .SetParent<Object> ()
71  .AddAttribute ("NodesA", "",
74  MakeObjectVectorChecker<ConfigTestObject> ())
75  .AddAttribute ("NodesB", "",
78  MakeObjectVectorChecker<ConfigTestObject> ())
79  .AddAttribute ("NodeA", "",
80  PointerValue (),
81  MakePointerAccessor (&ConfigTestObject::m_nodeA),
82  MakePointerChecker<ConfigTestObject> ())
83  .AddAttribute ("NodeB", "",
84  PointerValue (),
85  MakePointerAccessor (&ConfigTestObject::m_nodeB),
86  MakePointerChecker<ConfigTestObject> ())
87  .AddAttribute ("A", "",
88  IntegerValue (10),
89  MakeIntegerAccessor (&ConfigTestObject::m_a),
90  MakeIntegerChecker<int8_t> ())
91  .AddAttribute ("B", "",
92  IntegerValue (9),
93  MakeIntegerAccessor (&ConfigTestObject::m_b),
94  MakeIntegerChecker<int8_t> ())
95  .AddAttribute ("Source", "XX",
96  IntegerValue (-1),
97  MakeIntegerAccessor (&ConfigTestObject::m_trace),
98  MakeIntegerChecker<int16_t> ())
99  .AddTraceSource ("Source", "XX",
101  ;
102  return tid;
103 }
104 
105 void
107 {
108  m_nodeA = a;
109 }
110 
111 void
113 {
114  m_nodeB = b;
115 }
116 
117 void
119 {
120  m_nodesA.push_back (a);
121 }
122 
123 void
125 {
126  m_nodesB.push_back (b);
127 }
128 
129 int8_t
131 {
132  return m_a;
133 }
134 
135 int8_t
137 {
138  return m_b;
139 }
140 
141 // Other test objects
142 //
143 
145 {
146 public:
147  static TypeId GetTypeId (void);
149  virtual ~DerivedConfigTestObject (void) {}
150 };
151 
152 TypeId
154 {
155  static TypeId tid = TypeId ("DerivedConfigTestObject")
157  ;
158  return tid;
159 }
160 
161 class BaseConfigObject : public Object
162 {
163 public:
164  static TypeId GetTypeId (void);
165  BaseConfigObject (void) : m_x(15) {}
166  virtual ~BaseConfigObject (void) {}
167 private:
168  int8_t m_x;
169  void Increment (void) { m_x++; } // silence unused variable warning
170 };
171 
172 TypeId
174 {
175  static TypeId tid = TypeId ("BaseConfigObject")
176  .SetParent<Object> ()
177  .AddAttribute ("X", "",
178  IntegerValue (10),
179  MakeIntegerAccessor (&BaseConfigObject::m_x),
180  MakeIntegerChecker<int8_t> ())
181  ;
182  return tid;
183 }
184 
186 {
187 public:
188  static TypeId GetTypeId (void);
190  virtual ~DerivedConfigObject (void) {}
191 };
192 
193 TypeId
195 {
196  static TypeId tid = TypeId ("DerivedConfigObject")
198  ;
199  return tid;
200 }
201 
202 
203 // ===========================================================================
204 // Test for the ability to register and use a root namespace
205 // ===========================================================================
207 {
208 public:
211 
212 private:
213  virtual void DoRun (void);
214 };
215 
217  : TestCase ("Check ability to register a root namespace and use it")
218 {
219 }
220 
221 void
223 {
224  IntegerValue iv;
225  //
226  // Create an object and register its attributes directly in the root
227  // namespace.
228  //
229  Ptr<ConfigTestObject> root = CreateObject<ConfigTestObject> ();
231 
232  //
233  // We should find the default values there.
234  //
235  root->GetAttribute ("A", iv);
236  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" not initialized as expected");
237 
238  //
239  // Now use the config mechanism to set the attribute; and we should find the
240  // new value.
241  //
242  Config::Set ("/A", IntegerValue (1));
243  root->GetAttribute ("A", iv);
244  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 1, "Object Attribute \"A\" not set correctly");
245 
246  //
247  // We should find the default values of "B" too.
248  //
249  root->GetAttribute ("B", iv);
250  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 9, "Object Attribute \"B\" not initialized as expected");
251 
252  //
253  // Now use the config mechanism to set the attribute; and we should find the
254  // new value.
255  //
256  Config::Set ("/B", IntegerValue (-1));
257  root->GetAttribute ("B", iv);
258  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -1, "Object Attribute \"B\" not set correctly");
259 }
260 
261 // ===========================================================================
262 // Test for the ability to add an object under the root namespace.
263 // ===========================================================================
265 {
266 public:
269 
270 private:
271  virtual void DoRun (void);
272 };
273 
275  : TestCase ("Check ability to register an object under the root namespace and use it")
276 {
277 }
278 
279 void
281 {
282  IntegerValue iv;
283  //
284  // Create an object and register its attributes directly in the root
285  // namespace.
286  //
287  Ptr<ConfigTestObject> root = CreateObject<ConfigTestObject> ();
289 
290  Ptr<ConfigTestObject> a = CreateObject<ConfigTestObject> ();
291  root->SetNodeA (a);
292 
293  //
294  // We should find the default values there.
295  //
296  a->GetAttribute ("A", iv);
297  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" not initialized as expected");
298 
299  //
300  // Now use the config mechanism to set the attribute; and we should find the
301  // new value.
302  //
303  Config::Set ("/NodeA/A", IntegerValue (1));
304  a->GetAttribute ("A", iv);
305  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 1, "Object Attribute \"A\" not set correctly");
306 
307 
308  //
309  // We should find the default values of "B" too.
310  //
311  a->GetAttribute ("B", iv);
312  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 9, "Object Attribute \"B\" not initialized as expected");
313 
314  //
315  // Now use the config mechanism to set the attribute; and we should find the
316  // new value.
317  //
318  Config::Set ("/NodeA/B", IntegerValue (-1));
319  a->GetAttribute ("B", iv);
320  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -1, "Object Attribute \"B\" not set correctly");
321 
322  //
323  // Try and set through a nonexistent path. Should do nothing.
324  //
325  Config::Set ("/NodeB/A", IntegerValue (1234));
326  a->GetAttribute ("A", iv);
327  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 1, "Object Attribute \"A\" unexpectedly set via bad path");
328 
329  Config::Set ("/NodeB/B", IntegerValue (1234));
330  a->GetAttribute ("B", iv);
331  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -1, "Object Attribute \"B\" unexpectedly set via bad path");
332 
333  //
334  // Step down one level of recursion and try again
335  //
336  Ptr<ConfigTestObject> b = CreateObject<ConfigTestObject> ();
337 
338  //
339  // We should find the default values there.
340  //
341  b->GetAttribute ("A", iv);
342  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" not initialized as expected");
343  b->GetAttribute ("B", iv);
344  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 9, "Object Attribute \"B\" not initialized as expected");
345 
346  //
347  // Now tell A that it has a B; and we should be able to set this new object's
348  // Attributes.
349  //
350  a->SetNodeB (b);
351 
352  Config::Set ("/NodeA/NodeB/A", IntegerValue (4));
353  Config::Set ("/NodeA/NodeB/B", IntegerValue (-4));
354  b->GetAttribute ("A", iv);
355  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 4, "Object Attribute \"A\" not set as expected");
356  b->GetAttribute ("B", iv);
357  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -4, "Object Attribute \"B\" not set as expected");
358 
359 
360  //
361  // Try '*' for attributes
362  //
363  Config::Set ("/*/A", IntegerValue (2));
364  a->GetAttribute ("A", iv);
365  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 2, "Object Attribute \"A\" not set correctly");
366  b->GetAttribute ("A", iv);
367  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 4, "Object Attribute \"A\" not set correctly");
368 }
369 
370 // ===========================================================================
371 // Test for the ability to deal configure with vectors of objects.
372 // ===========================================================================
374 {
375 public:
378 
379 private:
380  virtual void DoRun (void);
381 };
382 
384  : TestCase ("Check ability to configure vectors of Object using regular expressions")
385 {
386 }
387 
388 void
390 {
391  IntegerValue iv;
392 
393  //
394  // Create a root namespace object
395  //
396  Ptr<ConfigTestObject> root = CreateObject<ConfigTestObject> ();
398 
399  //
400  // Create an object under the root.
401  //
402  Ptr<ConfigTestObject> a = CreateObject<ConfigTestObject> ();
403  root->SetNodeA (a);
404 
405  //
406  // Create an object one level down.
407  //
408  Ptr<ConfigTestObject> b = CreateObject<ConfigTestObject> ();
409  a->SetNodeB (b);
410 
411  //
412  // Add four objects to the ObjectVector Attribute at the bottom of the
413  // object hierarchy. By this point, we believe that the Attributes
414  // will be initialized correctly.
415  //
416  Ptr<ConfigTestObject> obj0 = CreateObject<ConfigTestObject> ();
417  Ptr<ConfigTestObject> obj1 = CreateObject<ConfigTestObject> ();
418  Ptr<ConfigTestObject> obj2 = CreateObject<ConfigTestObject> ();
419  Ptr<ConfigTestObject> obj3 = CreateObject<ConfigTestObject> ();
420  b->AddNodeB (obj0);
421  b->AddNodeB (obj1);
422  b->AddNodeB (obj2);
423  b->AddNodeB (obj3);
424 
425  //
426  // Set an Attribute of the zeroth Object in the vector by explicitly writing
427  // the '0' and make sure that only the one thing changed.
428  //
429  Config::Set ("/NodeA/NodeB/NodesB/0/A", IntegerValue (-11));
430  obj0->GetAttribute ("A", iv);
431  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -11, "Object Attribute \"A\" not set as expected");
432 
433  obj1->GetAttribute ("A", iv);
434  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set");
435 
436  obj2->GetAttribute ("A", iv);
437  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set");
438 
439  obj3->GetAttribute ("A", iv);
440  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set");
441 
442  //
443  // Start using regular expression-like syntax to set Attributes. First try
444  // the OR syntax. Make sure that the two objects changed and nothing else
445  //
446  Config::Set ("/NodeA/NodeB/NodesB/0|1/A", IntegerValue (-12));
447  obj0->GetAttribute ("A", iv);
448  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -12, "Object Attribute \"A\" not set as expected");
449 
450  obj1->GetAttribute ("A", iv);
451  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -12, "Object Attribute \"A\" not set as expected");
452 
453  obj2->GetAttribute ("A", iv);
454  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set");
455 
456  obj3->GetAttribute ("A", iv);
457  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set");
458 
459  //
460  // Make sure that extra '|' are allowed at the start and end of the regular expression
461  //
462  Config::Set ("/NodeA/NodeB/NodesB/|0|1|/A", IntegerValue (-13));
463  obj0->GetAttribute ("A", iv);
464  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -13, "Object Attribute \"A\" not set as expected");
465 
466  obj1->GetAttribute ("A", iv);
467  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -13, "Object Attribute \"A\" not set as expected");
468 
469  obj2->GetAttribute ("A", iv);
470  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set");
471 
472  obj3->GetAttribute ("A", iv);
473  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set");
474 
475  //
476  // Try the [x-y] syntax
477  //
478  Config::Set ("/NodeA/NodeB/NodesB/[0-2]/A", IntegerValue (-14));
479  obj0->GetAttribute ("A", iv);
480  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -14, "Object Attribute \"A\" not set as expected");
481 
482  obj1->GetAttribute ("A", iv);
483  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -14, "Object Attribute \"A\" not set as expected");
484 
485  obj2->GetAttribute ("A", iv);
486  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -14, "Object Attribute \"A\" not set as expected");
487 
488  obj3->GetAttribute ("A", iv);
489  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set");
490 
491  //
492  // Try the [x-y] syntax at the other limit
493  //
494  Config::Set ("/NodeA/NodeB/NodesB/[1-3]/A", IntegerValue (-15));
495  obj0->GetAttribute ("A", iv);
496  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -14, "Object Attribute \"A\" unexpectedly set");
497 
498  obj1->GetAttribute ("A", iv);
499  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -15, "Object Attribute \"A\" not set as expected");
500 
501  obj2->GetAttribute ("A", iv);
502  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -15, "Object Attribute \"A\" not set as expected");
503 
504  obj3->GetAttribute ("A", iv);
505  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -15, "Object Attribute \"A\" not set as expected");
506 
507  //
508  // Combine the [x-y] syntax and the OR sntax
509  //
510  Config::Set ("/NodeA/NodeB/NodesB/[0-1]|3/A", IntegerValue (-16));
511  obj0->GetAttribute ("A", iv);
512  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -16, "Object Attribute \"A\" not set as expected");
513 
514  obj1->GetAttribute ("A", iv);
515  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -16, "Object Attribute \"A\" not set as expected");
516 
517  obj2->GetAttribute ("A", iv);
518  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -15, "Object Attribute \"A\" unexpectedly set");
519 
520  obj3->GetAttribute ("A", iv);
521  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -16, "Object Attribute \"A\" not set as expected");
522 }
523 
524 // ===========================================================================
525 // Test for the ability to trace configure with vectors of objects.
526 // ===========================================================================
528 {
529 public:
532 
533  void Trace (int16_t oldValue, int16_t newValue) { m_newValue = newValue; }
534  void TraceWithPath (std::string path, int16_t old, int16_t newValue) { m_newValue = newValue; m_path = path; }
535 
536 private:
537  virtual void DoRun (void);
538 
539  int16_t m_newValue;
540  std::string m_path;
541 };
542 
544  : TestCase ("Check ability to trace connect through vectors of Object using regular expressions")
545 {
546 }
547 
548 void
550 {
551  IntegerValue iv;
552 
553  //
554  // Create a root namespace object
555  //
556  Ptr<ConfigTestObject> root = CreateObject<ConfigTestObject> ();
558 
559  //
560  // Create an object under the root.
561  //
562  Ptr<ConfigTestObject> a = CreateObject<ConfigTestObject> ();
563  root->SetNodeA (a);
564 
565  //
566  // Create an object one level down.
567  //
568  Ptr<ConfigTestObject> b = CreateObject<ConfigTestObject> ();
569  a->SetNodeB (b);
570 
571  //
572  // Add four objects to the ObjectVector Attribute at the bottom of the
573  // object hierarchy. By this point, we believe that the Attributes
574  // will be initialized correctly.
575  //
576  Ptr<ConfigTestObject> obj0 = CreateObject<ConfigTestObject> ();
577  Ptr<ConfigTestObject> obj1 = CreateObject<ConfigTestObject> ();
578  Ptr<ConfigTestObject> obj2 = CreateObject<ConfigTestObject> ();
579  Ptr<ConfigTestObject> obj3 = CreateObject<ConfigTestObject> ();
580  b->AddNodeB (obj0);
581  b->AddNodeB (obj1);
582  b->AddNodeB (obj2);
583  b->AddNodeB (obj3);
584 
585  //
586  // Do a trace connect to some of the sources. We already checked parsing of
587  // the regular expressions, so we'll concentrate on the tracing part of the
588  // puzzle here.
589  //
590  Config::ConnectWithoutContext ("/NodeA/NodeB/NodesB/[0-1]|3/Source",
592 
593  //
594  // If we bug the trace source referred to by index '0' above, we should see
595  // the trace fire.
596  //
597  m_newValue = 0;
598  obj0->SetAttribute ("Source", IntegerValue (-1));
599  NS_TEST_ASSERT_MSG_EQ (m_newValue, -1, "Trace 0 did not fire as expected");
600 
601  //
602  // If we bug the trace source referred to by index '1' above, we should see
603  // the trace fire.
604  //
605  m_newValue = 0;
606  obj1->SetAttribute ("Source", IntegerValue (-2));
607  NS_TEST_ASSERT_MSG_EQ (m_newValue, -2, "Trace 1 did not fire as expected");
608 
609  //
610  // If we bug the trace source referred to by index '2' which is skipped above,
611  // we should not see the trace fire.
612  //
613  m_newValue = 0;
614  obj2->SetAttribute ("Source", IntegerValue (-3));
615  NS_TEST_ASSERT_MSG_EQ (m_newValue, 0, "Trace 2 fired unexpectedly");
616 
617  //
618  // If we bug the trace source referred to by index '3' above, we should see
619  // the trace fire.
620  //
621  m_newValue = 0;
622  obj3->SetAttribute ("Source", IntegerValue (-4));
623  NS_TEST_ASSERT_MSG_EQ (m_newValue, -4, "Trace 3 did not fire as expected");
624 
625  //
626  // Do a trace connect (with context) to some of the sources.
627  //
628  Config::Connect ("/NodeA/NodeB/NodesB/[0-1]|3/Source",
630 
631  //
632  // If we bug the trace source referred to by index '0' above, we should see
633  // the trace fire with the expected context path.
634  //
635  m_newValue = 0;
636  m_path = "";
637  obj0->SetAttribute ("Source", IntegerValue (-1));
638  NS_TEST_ASSERT_MSG_EQ (m_newValue, -1, "Trace 0 did not fire as expected");
639  NS_TEST_ASSERT_MSG_EQ (m_path, "/NodeA/NodeB/NodesB/0/Source", "Trace 0 did not provide expected context");
640 
641  //
642  // If we bug the trace source referred to by index '1' above, we should see
643  // the trace fire with the expected context path.
644  //
645  m_newValue = 0;
646  m_path = "";
647  obj1->SetAttribute ("Source", IntegerValue (-2));
648  NS_TEST_ASSERT_MSG_EQ (m_newValue, -2, "Trace 1 did not fire as expected");
649  NS_TEST_ASSERT_MSG_EQ (m_path, "/NodeA/NodeB/NodesB/1/Source", "Trace 1 did not provide expected context");
650 
651  //
652  // If we bug the trace source referred to by index '2' which is skipped above,
653  // we should not see the trace fire.
654  //
655  m_newValue = 0;
656  m_path = "";
657  obj2->SetAttribute ("Source", IntegerValue (-3));
658  NS_TEST_ASSERT_MSG_EQ (m_newValue, 0, "Trace 2 fired unexpectedly");
659 
660  //
661  // If we bug the trace source referred to by index '3' above, we should see
662  // the trace fire with the expected context path.
663  //
664  m_newValue = 0;
665  m_path = "";
666  obj3->SetAttribute ("Source", IntegerValue (-4));
667  NS_TEST_ASSERT_MSG_EQ (m_newValue, -4, "Trace 3 did not fire as expected");
668  NS_TEST_ASSERT_MSG_EQ (m_path, "/NodeA/NodeB/NodesB/1/Source", "Trace 1 did not provide expected context");
669 }
670 
671 // ===========================================================================
672 // Test for the ability to search attributes of parent classes
673 // when Resolver searches for attributes in a derived class object.
674 // This test passes with the patch found in
675 // https://www.nsnam.org/bugzilla/show_bug.cgi?id=1673
676 // (also reported in https://www.nsnam.org/bugzilla/show_bug.cgi?id=1959)
677 // ===========================================================================
679 {
680 public:
683 
684 private:
685  virtual void DoRun (void);
686 
687 };
688 
690  : TestCase ("Check that attributes of base class are searchable from paths including objects of derived class")
691 {
692 }
693 
694 void
696 {
697  IntegerValue iv;
698  //
699  // Create a root namespace object that doesn't have attributes but
700  // whose parent class has 'NodeA' attribute
701  //
702  Ptr<DerivedConfigTestObject> root = CreateObject<DerivedConfigTestObject> ();
704 
705  //
706  // Instantiate /NodeA
707  //
708  Ptr<DerivedConfigTestObject> a = CreateObject<DerivedConfigTestObject> ();
709  root->SetNodeA (a);
710 
711  //
712  // BaseConfigObject has attribute X, but we aggregate DerivedConfigObject
713  // instead
714  //
715  Ptr<DerivedConfigObject> derived = CreateObject<DerivedConfigObject> ();
716  a->AggregateObject (derived);
717  Config::Set ("/NodeA/$DerivedConfigObject/X", IntegerValue (42));
718  derived->GetAttribute ("X", iv);
719  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 42, "Object Attribute \"X\" not settable in derived class");
720 
721 }
722 
723 // ===========================================================================
724 // The Test Suite that glues all of the Test Cases together.
725 // ===========================================================================
727 {
728 public:
729  ConfigTestSuite ();
730 };
731 
733  : TestSuite ("config", UNIT)
734 {
735  AddTestCase (new RootNamespaceConfigTestCase, TestCase::QUICK);
736  AddTestCase (new UnderRootNamespaceConfigTestCase, TestCase::QUICK);
737  AddTestCase (new ObjectVectorConfigTestCase, TestCase::QUICK);
739 }
740 
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberContainer)
Definition: object-vector.h:51
Ptr< ConfigTestObject > m_nodeA
virtual void DoRun(void)
Implementation to actually run this TestCase.
A suite of tests to run.
Definition: test.h:1289
static ConfigTestSuite configTestSuite
Hold a signed integer type.
Definition: integer.h:45
void AddNodeA(Ptr< ConfigTestObject > a)
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:672
encapsulates test code
Definition: test.h:1113
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:738
int8_t GetB(void) const
void AddNodeB(Ptr< ConfigTestObject > b)
int64_t Get(void) const
static TypeId GetTypeId(void)
virtual void DoRun(void)
Implementation to actually run this TestCase.
static TypeId GetTypeId(void)
#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:148
static TypeId GetTypeId(void)
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1283
std::vector< Ptr< ConfigTestObject > > m_nodesA
void AggregateObject(Ptr< Object > other)
Definition: object.cc:242
hold objects of type Ptr
Definition: pointer.h:33
virtual ~DerivedConfigObject(void)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
static TypeId GetTypeId(void)
virtual ~BaseConfigObject(void)
void GetAttribute(std::string name, AttributeValue &value) const
Definition: object-base.cc:214
Ptr< ConfigTestObject > m_nodeB
void AddTestCase(TestCase *testCase) NS_DEPRECATED
Add an individual child TestCase case to this TestCase.
Definition: test.cc:184
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual ~DerivedConfigTestObject(void)
void RegisterRootNamespaceObject(Ptr< Object > obj)
Definition: config.cc:755
void TraceWithPath(std::string path, int16_t old, int16_t newValue)
virtual void DoRun(void)
Implementation to actually run this TestCase.
a base class which provides memory management and object aggregation
Definition: object.h:64
contain a set of ns3::Object pointers.
void SetNodeA(Ptr< ConfigTestObject > a)
int8_t GetA(void) const
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:176
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
virtual void DoRun(void)
Implementation to actually run this TestCase.
void Trace(int16_t oldValue, int16_t newValue)
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:727
void SetNodeB(Ptr< ConfigTestObject > b)
std::vector< Ptr< ConfigTestObject > > m_nodesB
TracedValue< int16_t > m_trace