A Discrete-Event Network Simulator
API
config-test-suite.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 #include "ns3/callback.h"
20 #include "ns3/config.h"
21 #include "ns3/integer.h"
22 #include "ns3/log.h"
23 #include "ns3/names.h"
24 #include "ns3/object-vector.h"
25 #include "ns3/object.h"
26 #include "ns3/pointer.h"
27 #include "ns3/singleton.h"
28 #include "ns3/test.h"
29 #include "ns3/trace-source-accessor.h"
30 #include "ns3/traced-value.h"
31 
32 #include <sstream>
33 
47 namespace ns3
48 {
49 
50 namespace tests
51 {
52 
57 class ConfigTestObject : public Object
58 {
59  public:
64  static TypeId GetTypeId();
65 
76 
87 
92  int8_t GetA() const;
97  int8_t GetB() const;
98 
99  private:
100  std::vector<Ptr<ConfigTestObject>> m_nodesA;
101  std::vector<Ptr<ConfigTestObject>> m_nodesB;
104  int8_t m_a;
105  int8_t m_b;
107 };
108 
109 TypeId
111 {
112  static TypeId tid = TypeId("ConfigTestObject")
113  .SetParent<Object>()
114  .AddAttribute("NodesA",
115  "",
118  MakeObjectVectorChecker<ConfigTestObject>())
119  .AddAttribute("NodesB",
120  "",
123  MakeObjectVectorChecker<ConfigTestObject>())
124  .AddAttribute("NodeA",
125  "",
126  PointerValue(),
128  MakePointerChecker<ConfigTestObject>())
129  .AddAttribute("NodeB",
130  "",
131  PointerValue(),
133  MakePointerChecker<ConfigTestObject>())
134  .AddAttribute("A",
135  "",
136  IntegerValue(10),
138  MakeIntegerChecker<int8_t>())
139  .AddAttribute("B",
140  "",
141  IntegerValue(9),
143  MakeIntegerChecker<int8_t>())
144  .AddAttribute("Source",
145  "XX",
146  IntegerValue(-1),
148  MakeIntegerChecker<int16_t>())
149  .AddTraceSource("Source",
150  "XX",
152  "ns3::TracedValueCallback::Int16");
153  return tid;
154 }
155 
156 void
158 {
159  m_nodeA = a;
160 }
161 
162 void
164 {
165  m_nodeB = b;
166 }
167 
168 void
170 {
171  m_nodesA.push_back(a);
172 }
173 
174 void
176 {
177  m_nodesB.push_back(b);
178 }
179 
180 int8_t
182 {
183  return m_a;
184 }
185 
186 int8_t
188 {
189  return m_b;
190 }
191 
197 {
198  public:
203  static TypeId GetTypeId();
204 
207  {
208  }
209 
212  {
213  }
214 };
215 
216 TypeId
218 {
219  static TypeId tid = TypeId("DerivedConfigTestObject").SetParent<ConfigTestObject>();
220  return tid;
221 }
222 
227 class BaseConfigObject : public Object
228 {
229  public:
234  static TypeId GetTypeId();
235 
238  : m_x(15)
239  {
240  }
241 
243  ~BaseConfigObject() override
244  {
245  }
246 
247  private:
248  int8_t m_x;
249 };
250 
251 TypeId
253 {
254  static TypeId tid = TypeId("BaseConfigObject")
255  .SetParent<Object>()
256  .AddAttribute("X",
257  "",
258  IntegerValue(10),
260  MakeIntegerChecker<int8_t>());
261  return tid;
262 }
263 
269 {
270  public:
275  static TypeId GetTypeId();
276 
279  {
280  }
281 
284  {
285  }
286 };
287 
288 TypeId
290 {
291  static TypeId tid = TypeId("DerivedConfigObject").SetParent<BaseConfigObject>();
292  return tid;
293 }
294 
300 {
301  public:
304 
307  {
308  }
309 
310  private:
311  void DoRun() override;
312 };
313 
315  : TestCase("Check ability to register a root namespace and use it")
316 {
317 }
318 
319 void
321 {
322  IntegerValue iv;
323  //
324  // Create an object and register its attributes directly in the root
325  // namespace.
326  //
327  Ptr<ConfigTestObject> root = CreateObject<ConfigTestObject>();
329 
330  //
331  // We should find the default values there.
332  //
333  root->GetAttribute("A", iv);
334  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 10, "Object Attribute \"A\" not initialized as expected");
335 
336  //
337  // Now use the config mechanism to set the attribute; and we should find the
338  // new value.
339  //
340  Config::Set("/A", IntegerValue(1));
341  root->GetAttribute("A", iv);
342  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 1, "Object Attribute \"A\" not set correctly");
343 
344  //
345  // We should find the default values of "B" too.
346  //
347  root->GetAttribute("B", iv);
348  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 9, "Object Attribute \"B\" not initialized as expected");
349 
350  //
351  // Now use the config mechanism to set the attribute; and we should find the
352  // new value.
353  //
354  Config::Set("/B", IntegerValue(-1));
355  root->GetAttribute("B", iv);
356  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -1, "Object Attribute \"B\" not set correctly");
357 }
358 
364 {
365  public:
368 
371  {
372  }
373 
374  private:
375  void DoRun() override;
376 };
377 
379  : TestCase("Check ability to register an object under the root namespace and use it")
380 {
381 }
382 
383 void
385 {
386  IntegerValue iv;
387  //
388  // Create an object and register its attributes directly in the root
389  // namespace.
390  //
391  Ptr<ConfigTestObject> root = CreateObject<ConfigTestObject>();
393 
394  Ptr<ConfigTestObject> a = CreateObject<ConfigTestObject>();
395  root->SetNodeA(a);
396 
397  //
398  // We should find the default values there.
399  //
400  a->GetAttribute("A", iv);
401  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 10, "Object Attribute \"A\" not initialized as expected");
402 
403  //
404  // Now use the config mechanism to set the attribute; and we should find the
405  // new value.
406  //
407  Config::Set("/NodeA/A", IntegerValue(1));
408  a->GetAttribute("A", iv);
409  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 1, "Object Attribute \"A\" not set correctly");
410 
411  //
412  // We should find the default values of "B" too.
413  //
414  a->GetAttribute("B", iv);
415  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 9, "Object Attribute \"B\" not initialized as expected");
416 
417  //
418  // Now use the config mechanism to set the attribute; and we should find the
419  // new value.
420  //
421  Config::Set("/NodeA/B", IntegerValue(-1));
422  a->GetAttribute("B", iv);
423  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -1, "Object Attribute \"B\" not set correctly");
424 
425  //
426  // Try and set through a nonexistent path. Should do nothing.
427  //
428  Config::Set("/NodeB/A", IntegerValue(1234));
429  a->GetAttribute("A", iv);
430  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 1, "Object Attribute \"A\" unexpectedly set via bad path");
431 
432  Config::Set("/NodeB/B", IntegerValue(1234));
433  a->GetAttribute("B", iv);
434  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -1, "Object Attribute \"B\" unexpectedly set via bad path");
435 
436  //
437  // Step down one level of recursion and try again
438  //
439  Ptr<ConfigTestObject> b = CreateObject<ConfigTestObject>();
440 
441  //
442  // We should find the default values there.
443  //
444  b->GetAttribute("A", iv);
445  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 10, "Object Attribute \"A\" not initialized as expected");
446  b->GetAttribute("B", iv);
447  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 9, "Object Attribute \"B\" not initialized as expected");
448 
449  //
450  // Now tell A that it has a B; and we should be able to set this new object's
451  // Attributes.
452  //
453  a->SetNodeB(b);
454 
455  Config::Set("/NodeA/NodeB/A", IntegerValue(4));
456  Config::Set("/NodeA/NodeB/B", IntegerValue(-4));
457  b->GetAttribute("A", iv);
458  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 4, "Object Attribute \"A\" not set as expected");
459  b->GetAttribute("B", iv);
460  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -4, "Object Attribute \"B\" not set as expected");
461 
462  //
463  // Try '*' for attributes
464  //
465  Config::Set("/*/A", IntegerValue(2));
466  a->GetAttribute("A", iv);
467  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 2, "Object Attribute \"A\" not set correctly");
468  b->GetAttribute("A", iv);
469  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 4, "Object Attribute \"A\" not set correctly");
470 }
471 
477 {
478  public:
481 
484  {
485  }
486 
487  private:
488  void DoRun() override;
489 };
490 
492  : TestCase("Check ability to configure vectors of Object using regular expressions")
493 {
494 }
495 
496 void
498 {
499  IntegerValue iv;
500 
501  //
502  // Create a root namespace object
503  //
504  Ptr<ConfigTestObject> root = CreateObject<ConfigTestObject>();
506 
507  //
508  // Create an object under the root.
509  //
510  Ptr<ConfigTestObject> a = CreateObject<ConfigTestObject>();
511  root->SetNodeA(a);
512 
513  //
514  // Create an object one level down.
515  //
516  Ptr<ConfigTestObject> b = CreateObject<ConfigTestObject>();
517  a->SetNodeB(b);
518 
519  //
520  // Add four objects to the ObjectVector Attribute at the bottom of the
521  // object hierarchy. By this point, we believe that the Attributes
522  // will be initialized correctly.
523  //
524  Ptr<ConfigTestObject> obj0 = CreateObject<ConfigTestObject>();
525  Ptr<ConfigTestObject> obj1 = CreateObject<ConfigTestObject>();
526  Ptr<ConfigTestObject> obj2 = CreateObject<ConfigTestObject>();
527  Ptr<ConfigTestObject> obj3 = CreateObject<ConfigTestObject>();
528  b->AddNodeB(obj0);
529  b->AddNodeB(obj1);
530  b->AddNodeB(obj2);
531  b->AddNodeB(obj3);
532 
533  //
534  // Set an Attribute of the zeroth Object in the vector by explicitly writing
535  // the '0' and make sure that only the one thing changed.
536  //
537  Config::Set("/NodeA/NodeB/NodesB/0/A", IntegerValue(-11));
538  obj0->GetAttribute("A", iv);
539  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -11, "Object Attribute \"A\" not set as expected");
540 
541  obj1->GetAttribute("A", iv);
542  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 10, "Object Attribute \"A\" unexpectedly set");
543 
544  obj2->GetAttribute("A", iv);
545  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 10, "Object Attribute \"A\" unexpectedly set");
546 
547  obj3->GetAttribute("A", iv);
548  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 10, "Object Attribute \"A\" unexpectedly set");
549 
550  //
551  // Start using regular expression-like syntax to set Attributes. First try
552  // the OR syntax. Make sure that the two objects changed and nothing else
553  //
554  Config::Set("/NodeA/NodeB/NodesB/0|1/A", IntegerValue(-12));
555  obj0->GetAttribute("A", iv);
556  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -12, "Object Attribute \"A\" not set as expected");
557 
558  obj1->GetAttribute("A", iv);
559  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -12, "Object Attribute \"A\" not set as expected");
560 
561  obj2->GetAttribute("A", iv);
562  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 10, "Object Attribute \"A\" unexpectedly set");
563 
564  obj3->GetAttribute("A", iv);
565  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 10, "Object Attribute \"A\" unexpectedly set");
566 
567  //
568  // Make sure that extra '|' are allowed at the start and end of the regular expression
569  //
570  Config::Set("/NodeA/NodeB/NodesB/|0|1|/A", IntegerValue(-13));
571  obj0->GetAttribute("A", iv);
572  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -13, "Object Attribute \"A\" not set as expected");
573 
574  obj1->GetAttribute("A", iv);
575  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -13, "Object Attribute \"A\" not set as expected");
576 
577  obj2->GetAttribute("A", iv);
578  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 10, "Object Attribute \"A\" unexpectedly set");
579 
580  obj3->GetAttribute("A", iv);
581  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 10, "Object Attribute \"A\" unexpectedly set");
582 
583  //
584  // Try the [x-y] syntax
585  //
586  Config::Set("/NodeA/NodeB/NodesB/[0-2]/A", IntegerValue(-14));
587  obj0->GetAttribute("A", iv);
588  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -14, "Object Attribute \"A\" not set as expected");
589 
590  obj1->GetAttribute("A", iv);
591  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -14, "Object Attribute \"A\" not set as expected");
592 
593  obj2->GetAttribute("A", iv);
594  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -14, "Object Attribute \"A\" not set as expected");
595 
596  obj3->GetAttribute("A", iv);
597  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 10, "Object Attribute \"A\" unexpectedly set");
598 
599  //
600  // Try the [x-y] syntax at the other limit
601  //
602  Config::Set("/NodeA/NodeB/NodesB/[1-3]/A", IntegerValue(-15));
603  obj0->GetAttribute("A", iv);
604  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -14, "Object Attribute \"A\" unexpectedly set");
605 
606  obj1->GetAttribute("A", iv);
607  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -15, "Object Attribute \"A\" not set as expected");
608 
609  obj2->GetAttribute("A", iv);
610  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -15, "Object Attribute \"A\" not set as expected");
611 
612  obj3->GetAttribute("A", iv);
613  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -15, "Object Attribute \"A\" not set as expected");
614 
615  //
616  // Combine the [x-y] syntax and the OR sntax
617  //
618  Config::Set("/NodeA/NodeB/NodesB/[0-1]|3/A", IntegerValue(-16));
619  obj0->GetAttribute("A", iv);
620  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -16, "Object Attribute \"A\" not set as expected");
621 
622  obj1->GetAttribute("A", iv);
623  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -16, "Object Attribute \"A\" not set as expected");
624 
625  obj2->GetAttribute("A", iv);
626  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -15, "Object Attribute \"A\" unexpectedly set");
627 
628  obj3->GetAttribute("A", iv);
629  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -16, "Object Attribute \"A\" not set as expected");
630 }
631 
637 {
638  public:
641 
644  {
645  }
646 
652  void Trace(int16_t oldValue [[maybe_unused]], int16_t newValue)
653  {
654  m_newValue = newValue;
655  }
656 
663  void TraceWithPath(std::string path, int16_t old [[maybe_unused]], int16_t newValue)
664  {
665  m_newValue = newValue;
666  m_path = path;
667  }
668 
669  private:
670  void DoRun() override;
671 
672  int16_t m_newValue;
673  std::string m_path;
674 };
675 
677  : TestCase("Check ability to trace connect through vectors of Object using regular expressions")
678 {
679 }
680 
681 void
683 {
684  IntegerValue iv;
685 
686  //
687  // Create a root namespace object
688  //
689  Ptr<ConfigTestObject> root = CreateObject<ConfigTestObject>();
691 
692  //
693  // Create an object under the root.
694  //
695  Ptr<ConfigTestObject> a = CreateObject<ConfigTestObject>();
696  root->SetNodeA(a);
697 
698  //
699  // Create an object one level down.
700  //
701  Ptr<ConfigTestObject> b = CreateObject<ConfigTestObject>();
702  a->SetNodeB(b);
703 
704  //
705  // Add four objects to the ObjectVector Attribute at the bottom of the
706  // object hierarchy. By this point, we believe that the Attributes
707  // will be initialized correctly.
708  //
709  Ptr<ConfigTestObject> obj0 = CreateObject<ConfigTestObject>();
710  Ptr<ConfigTestObject> obj1 = CreateObject<ConfigTestObject>();
711  Ptr<ConfigTestObject> obj2 = CreateObject<ConfigTestObject>();
712  Ptr<ConfigTestObject> obj3 = CreateObject<ConfigTestObject>();
713  b->AddNodeB(obj0);
714  b->AddNodeB(obj1);
715  b->AddNodeB(obj2);
716  b->AddNodeB(obj3);
717 
718  //
719  // Do a trace connect to some of the sources. We already checked parsing of
720  // the regular expressions, so we'll concentrate on the tracing part of the
721  // puzzle here.
722  //
723  Config::ConnectWithoutContext("/NodeA/NodeB/NodesB/[0-1]|3/Source",
725 
726  //
727  // If we bug the trace source referred to by index '0' above, we should see
728  // the trace fire.
729  //
730  m_newValue = 0;
731  obj0->SetAttribute("Source", IntegerValue(-1));
732  NS_TEST_ASSERT_MSG_EQ(m_newValue, -1, "Trace 0 did not fire as expected");
733 
734  //
735  // If we bug the trace source referred to by index '1' above, we should see
736  // the trace fire.
737  //
738  m_newValue = 0;
739  obj1->SetAttribute("Source", IntegerValue(-2));
740  NS_TEST_ASSERT_MSG_EQ(m_newValue, -2, "Trace 1 did not fire as expected");
741 
742  //
743  // If we bug the trace source referred to by index '2' which is skipped above,
744  // we should not see the trace fire.
745  //
746  m_newValue = 0;
747  obj2->SetAttribute("Source", IntegerValue(-3));
748  NS_TEST_ASSERT_MSG_EQ(m_newValue, 0, "Trace 2 fired unexpectedly");
749 
750  //
751  // If we bug the trace source referred to by index '3' above, we should see
752  // the trace fire.
753  //
754  m_newValue = 0;
755  obj3->SetAttribute("Source", IntegerValue(-4));
756  NS_TEST_ASSERT_MSG_EQ(m_newValue, -4, "Trace 3 did not fire as expected");
757 
758  //
759  // Do a trace connect (with context) to some of the sources.
760  //
761  Config::Connect("/NodeA/NodeB/NodesB/[0-1]|3/Source",
763 
764  //
765  // If we bug the trace source referred to by index '0' above, we should see
766  // the trace fire with the expected context path.
767  //
768  m_newValue = 0;
769  m_path = "";
770  obj0->SetAttribute("Source", IntegerValue(-1));
771  NS_TEST_ASSERT_MSG_EQ(m_newValue, -1, "Trace 0 did not fire as expected");
773  "/NodeA/NodeB/NodesB/0/Source",
774  "Trace 0 did not provide expected context");
775 
776  //
777  // If we bug the trace source referred to by index '1' above, we should see
778  // the trace fire with the expected context path.
779  //
780  m_newValue = 0;
781  m_path = "";
782  obj1->SetAttribute("Source", IntegerValue(-2));
783  NS_TEST_ASSERT_MSG_EQ(m_newValue, -2, "Trace 1 did not fire as expected");
785  "/NodeA/NodeB/NodesB/1/Source",
786  "Trace 1 did not provide expected context");
787 
788  //
789  // If we bug the trace source referred to by index '2' which is skipped above,
790  // we should not see the trace fire.
791  //
792  m_newValue = 0;
793  m_path = "";
794  obj2->SetAttribute("Source", IntegerValue(-3));
795  NS_TEST_ASSERT_MSG_EQ(m_newValue, 0, "Trace 2 fired unexpectedly");
796 
797  //
798  // If we bug the trace source referred to by index '3' above, we should see
799  // the trace fire with the expected context path.
800  //
801  m_newValue = 0;
802  m_path = "";
803  obj3->SetAttribute("Source", IntegerValue(-4));
804  NS_TEST_ASSERT_MSG_EQ(m_newValue, -4, "Trace 3 did not fire as expected");
806  "/NodeA/NodeB/NodesB/1/Source",
807  "Trace 1 did not provide expected context");
808 }
809 
819 {
820  public:
823 
826  {
827  }
828 
829  private:
830  void DoRun() override;
831 };
832 
834  : TestCase("Check that attributes of base class are searchable from paths including objects of "
835  "derived class")
836 {
837 }
838 
839 void
841 {
842  IntegerValue iv;
843  //
844  // Create a root namespace object that doesn't have attributes but
845  // whose parent class has 'NodeA' attribute
846  //
847  Ptr<DerivedConfigTestObject> root = CreateObject<DerivedConfigTestObject>();
849 
850  //
851  // Instantiate /NodeA
852  //
853  Ptr<DerivedConfigTestObject> a = CreateObject<DerivedConfigTestObject>();
854  root->SetNodeA(a);
855 
856  //
857  // BaseConfigObject has attribute X, but we aggregate DerivedConfigObject
858  // instead
859  //
860  Ptr<DerivedConfigObject> derived = CreateObject<DerivedConfigObject>();
861  a->AggregateObject(derived);
862  Config::Set("/NodeA/$DerivedConfigObject/X", IntegerValue(42));
863  derived->GetAttribute("X", iv);
864  NS_TEST_ASSERT_MSG_EQ(iv.Get(), 42, "Object Attribute \"X\" not settable in derived class");
865 }
866 
872 {
873  public:
875  ConfigTestSuite();
876 };
877 
879  : TestSuite("config")
880 {
885 }
886 
892 
893 } // namespace tests
894 
895 } // namespace ns3
Hold a signed integer type.
Definition: integer.h:45
int64_t Get() const
Definition: integer.cc:37
A base class which provides memory management and object aggregation.
Definition: object.h:89
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
~BaseConfigObject() override
Destructor.
int8_t m_x
X attribute target.
static TypeId GetTypeId()
Get the type ID.
An object with some attributes that we can play with using config.
void AddNodeB(Ptr< ConfigTestObject > b)
Add node B function.
void AddNodeA(Ptr< ConfigTestObject > a)
Add node A function.
Ptr< ConfigTestObject > m_nodeA
NodeA attribute target.
std::vector< Ptr< ConfigTestObject > > m_nodesA
NodesA attribute target.
TracedValue< int16_t > m_trace
Source TraceSource target.
void SetNodeB(Ptr< ConfigTestObject > b)
Set node b function.
int8_t GetB() const
Get node b function.
int8_t m_b
B attribute target.
std::vector< Ptr< ConfigTestObject > > m_nodesB
NodesB attribute target.
int8_t m_a
A attribute target.
int8_t GetA() const
Get node A function.
static TypeId GetTypeId()
Get the type ID.
void SetNodeA(Ptr< ConfigTestObject > a)
Set node A function.
Ptr< ConfigTestObject > m_nodeB
NodeB attribute target.
The Test Suite that glues all of the Test Cases together.
static TypeId GetTypeId()
Get the type ID.
~DerivedConfigObject() override
Destructor.
~DerivedConfigTestObject() override
Destructor.
static TypeId GetTypeId()
Get the type ID.
Test for the ability to deal configure with vectors of objects.
void DoRun() override
Implementation to actually run this TestCase.
~ObjectVectorConfigTestCase() override
Destructor.
Test for the ability to trace configure with vectors of objects.
void Trace(int16_t oldValue[[maybe_unused]], int16_t newValue)
Trace callback without context.
int16_t m_newValue
Flag to detect tracing result.
void TraceWithPath(std::string path, int16_t old[[maybe_unused]], int16_t newValue)
Trace callback with context path.
void DoRun() override
Implementation to actually run this TestCase.
Test for the ability to register and use a root namespace.
void DoRun() override
Implementation to actually run this TestCase.
~RootNamespaceConfigTestCase() override
Destructor.
Test for the ability to search attributes of parent classes when Resolver searches for attributes in ...
void DoRun() override
Implementation to actually run this TestCase.
Test for the ability to add an object under the root namespace.
void DoRun() override
Implementation to actually run this TestCase.
static ConfigTestSuite g_configTestSuite
ConfigTestSuite instance variable.
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:974
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:950
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:876
void RegisterRootNamespaceObject(Ptr< Object > obj)
Definition: config.cc:1005
#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:144
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Definition: integer.h:46
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Definition: object-vector.h:40
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:76