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