A Discrete-Event Network Simulator
API
attribute-test-suite.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 University of Washington
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 
18 #include "ns3/boolean.h"
19 #include "ns3/callback.h"
20 #include "ns3/config.h"
21 #include "ns3/double.h"
22 #include "ns3/enum.h"
23 #include "ns3/integer.h"
24 #include "ns3/nstime.h"
25 #include "ns3/object-factory.h"
26 #include "ns3/object-map.h"
27 #include "ns3/object-vector.h"
28 #include "ns3/object.h"
29 #include "ns3/pointer.h"
30 #include "ns3/random-variable-stream.h"
31 #include "ns3/string.h"
32 #include "ns3/test.h"
33 #include "ns3/trace-source-accessor.h"
34 #include "ns3/traced-value.h"
35 #include "ns3/uinteger.h"
36 
37 using namespace ns3;
38 
39 namespace ns3
40 {
41 
60 {
61  public:
63  {
64  }
65 
72  typedef void (*TracedValueCallback)(const ValueClassTest oldValue,
73  const ValueClassTest newValue);
74 };
75 
82 bool
83 operator!=(const ValueClassTest& a [[maybe_unused]], const ValueClassTest& b [[maybe_unused]])
84 {
85  return true;
86 }
87 
95 std::ostream&
96 operator<<(std::ostream& os, ValueClassTest v [[maybe_unused]])
97 {
98  return os;
99 }
100 
108 std::istream&
109 operator>>(std::istream& is, ValueClassTest& v [[maybe_unused]])
110 {
111  return is;
112 }
113 
116 
117 } // namespace ns3
118 
124 class Derived : public Object
125 {
126  public:
131  static TypeId GetTypeId()
132  {
133  static TypeId tid = TypeId("ns3::Derived").AddConstructor<Derived>().SetParent<Object>();
134  return tid;
135  }
136 
138  {
139  }
140 };
141 
143 
150 {
151  public:
153  enum Test_e
154  {
157  TEST_C
158  };
159 
161  enum class Test_ec
162  {
163  TEST_D,
164  TEST_E,
165  TEST_F
166  };
167 
172  static TypeId GetTypeId()
173  {
174  static TypeId tid =
175  TypeId("ns3::AttributeObjectTest")
177  .SetParent<Object>()
178  .HideFromDocumentation()
179  .AddAttribute("TestBoolName",
180  "help text",
181  BooleanValue(false),
184  .AddAttribute("TestBoolA",
185  "help text",
186  BooleanValue(false),
190  .AddAttribute("TestInt16",
191  "help text",
192  IntegerValue(-2),
194  MakeIntegerChecker<int16_t>())
195  .AddAttribute("TestInt16WithBounds",
196  "help text",
197  IntegerValue(-2),
199  MakeIntegerChecker<int16_t>(-5, 10))
200  .AddAttribute("TestInt16SetGet",
201  "help text",
202  IntegerValue(6),
205  MakeIntegerChecker<int16_t>())
206  .AddAttribute("TestUint8",
207  "help text",
208  UintegerValue(1),
210  MakeUintegerChecker<uint8_t>())
211  .AddAttribute("TestEnum",
212  "help text",
213  EnumValue(TEST_A),
214  MakeEnumAccessor<Test_e>(&AttributeObjectTest::m_enum),
215  MakeEnumChecker(TEST_A, "TestA", TEST_B, "TestB", TEST_C, "TestC"))
216  .AddAttribute("TestEnumSetGet",
217  "help text",
218  EnumValue(TEST_B),
219  MakeEnumAccessor<Test_e>(&AttributeObjectTest::DoSetEnum,
221  MakeEnumChecker(TEST_A, "TestA", TEST_B, "TestB", TEST_C, "TestC"))
222  .AddAttribute("TestEnumClass",
223  "help text",
224  EnumValue(Test_ec::TEST_D),
225  MakeEnumAccessor<Test_ec>(&AttributeObjectTest::m_enumclass),
226  MakeEnumChecker(Test_ec::TEST_D,
227  "TestD",
228  Test_ec::TEST_E,
229  "TestE",
230  Test_ec::TEST_F,
231  "TestF"))
232  .AddAttribute("TestEnumClassSetGet",
233  "help text",
234  EnumValue(Test_ec::TEST_E),
235  MakeEnumAccessor<Test_ec>(&AttributeObjectTest::DoSetEnumClass,
237  MakeEnumChecker(Test_ec::TEST_D,
238  "TestD",
239  Test_ec::TEST_E,
240  "TestE",
241  Test_ec::TEST_F,
242  "TestF"))
243  .AddAttribute("TestRandom",
244  "help text",
245  StringValue("ns3::ConstantRandomVariable[Constant=1.0]"),
247  MakePointerChecker<RandomVariableStream>())
248  .AddAttribute("TestFloat",
249  "help text",
250  DoubleValue(-1.1),
252  MakeDoubleChecker<float>())
253  .AddAttribute("TestVector1",
254  "help text",
257  MakeObjectVectorChecker<Derived>())
258  .AddAttribute("TestVector2",
259  "help text",
263  MakeObjectVectorChecker<Derived>())
264  .AddAttribute("TestMap1",
265  "help text",
266  ObjectMapValue(),
268  MakeObjectMapChecker<Derived>())
269  .AddAttribute("TestUnorderedMap",
270  "help text",
271  ObjectMapValue(),
273  MakeObjectMapChecker<Derived>())
274  .AddAttribute("IntegerTraceSource1",
275  "help text",
276  IntegerValue(-2),
278  MakeIntegerChecker<int8_t>())
279  .AddAttribute("IntegerTraceSource2",
280  "help text",
281  IntegerValue(-2),
284  MakeIntegerChecker<int8_t>())
285  .AddAttribute("UIntegerTraceSource",
286  "help text",
287  UintegerValue(2),
289  MakeIntegerChecker<uint8_t>())
290  .AddAttribute("DoubleTraceSource",
291  "help text",
292  DoubleValue(2),
294  MakeDoubleChecker<double>())
295  .AddAttribute("BoolTraceSource",
296  "help text",
297  BooleanValue(false),
300  .AddAttribute(
301  "EnumTraceSource",
302  "help text",
303  EnumValue(TEST_A),
304  MakeEnumAccessor<TracedValue<Test_e>>(&AttributeObjectTest::m_enumSrc),
305  MakeEnumChecker(TEST_A, "TestA"))
306  .AddAttribute("ValueClassSource",
307  "help text",
308  ValueClassTestValue(ValueClassTest()),
309  MakeValueClassTestAccessor(&AttributeObjectTest::m_valueSrc),
310  MakeValueClassTestChecker())
311  .AddTraceSource("Source1",
312  "help test",
314  "ns3::TracedValueCallback::Int8")
315  .AddTraceSource("Source2",
316  "help text",
318  "ns3::AttributeObjectTest::NumericTracedCallback")
319  .AddTraceSource("ValueSource",
320  "help text",
322  "ns3::ValueClassTest::TracedValueCallback")
323  .AddAttribute("Pointer",
324  "help text",
325  PointerValue(),
327  MakePointerChecker<Derived>())
328  .AddAttribute("PointerInitialized",
329  "help text",
330  StringValue("ns3::Derived"),
332  MakePointerChecker<Derived>())
333  .AddAttribute("PointerInitialized2",
334  "help text",
335  StringValue("ns3::Derived[]"),
337  MakePointerChecker<Derived>())
338  .AddAttribute("Callback",
339  "help text",
340  CallbackValue(),
343  .AddAttribute("TestTimeWithBounds",
344  "help text",
345  TimeValue(Seconds(-2)),
347  MakeTimeChecker(Seconds(-5), Seconds(10)))
348  .AddAttribute("TestDeprecated",
349  "help text",
350  BooleanValue(false),
354  "DEPRECATED test working.");
355 
356  return tid;
357  }
358 
360  {
361  }
362 
364  {
365  }
366 
369  {
370  m_vector1.push_back(CreateObject<Derived>());
371  }
372 
375  {
376  m_vector2.push_back(CreateObject<Derived>());
377  }
378 
383  void AddToMap1(uint32_t i)
384  {
385  m_map1.insert(std::pair<uint32_t, Ptr<Derived>>(i, CreateObject<Derived>()));
386  }
387 
392  void AddToUnorderedMap(uint64_t i)
393  {
394  m_unorderedMap.insert({i, CreateObject<Derived>()});
395  }
396 
401  void RemoveFromUnorderedMap(uint64_t i)
402  {
403  m_unorderedMap.erase(i);
404  }
405 
412  void InvokeCb(double a, int b, float c)
413  {
414  m_cb(a, b, c);
415  }
416 
421  void InvokeCbValue(int8_t a)
422  {
423  if (!m_cbValue.IsNull())
424  {
425  m_cbValue(a);
426  }
427  }
428 
429  private:
434  void DoSetTestA(bool v)
435  {
436  m_boolTestA = v;
437  }
438 
443  bool DoGetTestA() const
444  {
445  return m_boolTestA;
446  }
447 
452  int16_t DoGetInt16() const
453  {
454  return m_int16SetGet;
455  }
456 
461  void DoSetInt16(int16_t v)
462  {
463  m_int16SetGet = v;
464  }
465 
470  std::size_t DoGetVectorN() const
471  {
472  return m_vector2.size();
473  }
474 
480  Ptr<Derived> DoGetVector(std::size_t i) const
481  {
482  return m_vector2[i];
483  }
484 
490  bool DoSetIntSrc(int8_t v)
491  {
492  m_intSrc2 = v;
493  return true;
494  }
495 
500  int8_t DoGetIntSrc() const
501  {
502  return m_intSrc2;
503  }
504 
511  {
512  m_enumSetGet = v;
513  return true;
514  }
515 
521  {
522  return m_enumSetGet;
523  }
524 
531  {
532  m_enumClassSetGet = v;
533  return true;
534  }
535 
541  {
542  return m_enumClassSetGet;
543  }
544 
545  bool m_boolTestA;
546  bool m_boolTest;
548  int16_t m_int16;
550  int16_t m_int16SetGet;
551  uint8_t m_uint8;
552  float m_float;
558  std::vector<Ptr<Derived>> m_vector1;
559  std::vector<Ptr<Derived>> m_vector2;
560  std::map<uint32_t, Ptr<Derived>> m_map1;
561  std::unordered_map<uint64_t, Ptr<Derived>>
566 
568  typedef void (*NumericTracedCallback)(double, int, float);
579 };
580 
582 
589 template <typename T>
591 {
592  public:
597  AttributeTestCase(std::string description);
598  ~AttributeTestCase() override;
599 
600  private:
601  void DoRun() override;
610  bool CheckGetCodePaths(Ptr<Object> p,
611  std::string attributeName,
612  std::string expectedString,
613  T expectedValue);
614 };
615 
616 template <typename T>
618  : TestCase(description)
619 {
620 }
621 
622 template <typename T>
624 {
625 }
626 
627 template <typename T>
628 bool
630  std::string attributeName,
631  std::string expectedString,
632  T expectedValue)
633 {
634  StringValue stringValue;
635  T actualValue;
636 
637  //
638  // Get an Attribute value through its StringValue representation.
639  //
640  bool ok1 = p->GetAttributeFailSafe(attributeName, stringValue);
641  bool ok2 = stringValue.Get() == expectedString;
642 
643  //
644  // Get the existing boolean value through its particular type representation.
645  //
646  bool ok3 = p->GetAttributeFailSafe(attributeName, actualValue);
647  bool ok4 = expectedValue.Get() == actualValue.Get();
648 
649  return ok1 && ok2 && ok3 && ok4;
650 }
651 
652 // ===========================================================================
653 // The actual Attribute type test cases are specialized for each Attribute type
654 // ===========================================================================
655 template <>
656 void
658 {
659  auto p = CreateObject<AttributeObjectTest>();
660  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
661 
662  //
663  // Set the default value of the BooleanValue and create an object. The new
664  // default value should stick.
665  //
666  Config::SetDefault("ns3::AttributeObjectTest::TestBoolName", StringValue("true"));
667  p = CreateObject<AttributeObjectTest>();
668  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
669 
670  bool ok = CheckGetCodePaths(p, "TestBoolName", "true", BooleanValue(true));
671  NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
672 
673  std::string expected("Attribute 'TestDeprecated' is deprecated: DEPRECATED test working.\n");
674  // Temporarily redirect std::cerr to a stringstream
675  std::stringstream buffer;
676  std::streambuf* oldBuffer = std::cerr.rdbuf(buffer.rdbuf());
677  // Cause the deprecation warning to be sent to the stringstream
678  Config::SetDefault("ns3::AttributeObjectTest::TestDeprecated", BooleanValue(true));
679 
680  // Compare the obtained actual string with the expected string.
681  NS_TEST_ASSERT_MSG_EQ(buffer.str(), expected, "Deprecated attribute not working");
682  // Restore cerr to its original stream buffer
683  std::cerr.rdbuf(oldBuffer);
684 
685  //
686  // Set the default value of the BooleanValue the other way and create an object.
687  // The new default value should stick.
688  //
689  Config::SetDefaultFailSafe("ns3::AttributeObjectTest::TestBoolName", StringValue("false"));
690 
691  p = CreateObject<AttributeObjectTest>();
692  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
693 
694  ok = CheckGetCodePaths(p, "TestBoolName", "false", BooleanValue(false));
695  NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not et properly by default value");
696 
697  //
698  // Set the BooleanValue Attribute to true via SetAttributeFailSafe path.
699  //
700  ok = p->SetAttributeFailSafe("TestBoolName", StringValue("true"));
701  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() \"TestBoolName\" to true");
702 
703  ok = CheckGetCodePaths(p, "TestBoolName", "true", BooleanValue(true));
705  true,
706  "Attribute not set properly by SetAttributeFailSafe() via StringValue");
707 
708  //
709  // Set the BooleanValue to false via SetAttributeFailSafe path.
710  //
711  ok = p->SetAttributeFailSafe("TestBoolName", StringValue("false"));
712  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() \"TestBoolName\" to false");
713 
714  ok = CheckGetCodePaths(p, "TestBoolName", "false", BooleanValue(false));
716  true,
717  "Attribute not set properly by SetAttributeFailSafe() via StringValue");
718 
719  //
720  // Create an object using
721  //
722  p = CreateObject<AttributeObjectTest>();
723  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
724 
725  //
726  // The previous object-based tests checked access directly. Now check through
727  // setter and getter. The code here looks the same, but the underlying
728  // attribute is declared differently in the object. First make sure we can set
729  // to true.
730  //
731  ok = p->SetAttributeFailSafe("TestBoolA", StringValue("true"));
732  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() a boolean value to true");
733 
734  ok = CheckGetCodePaths(p, "TestBoolA", "true", BooleanValue(true));
736  ok,
737  true,
738  "Attribute not set properly by SetAttributeFailSafe() (getter/setter) via StringValue");
739 
740  //
741  // Now Set the BooleanValue to false via the setter.
742  //
743  ok = p->SetAttributeFailSafe("TestBoolA", StringValue("false"));
744  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() a boolean value to false");
745 
746  ok = CheckGetCodePaths(p, "TestBoolA", "false", BooleanValue(false));
748  ok,
749  true,
750  "Attribute not set properly by SetAttributeFailSafe() (getter/setter) via StringValue");
751 }
752 
753 template <>
754 void
756 {
757  auto p = CreateObject<AttributeObjectTest>();
758  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
759 
760  //
761  // When the object is first created, the Attribute should have the default
762  // value.
763  //
764  bool ok = CheckGetCodePaths(p, "TestInt16", "-2", IntegerValue(-2));
765  NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
766 
767  //
768  // Set the Attribute to a negative value through a StringValue.
769  //
770  ok = p->SetAttributeFailSafe("TestInt16", StringValue("-5"));
771  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via StringValue to -5");
772 
773  ok = CheckGetCodePaths(p, "TestInt16", "-5", IntegerValue(-5));
775  true,
776  "Attribute not set properly by SetAttributeFailSafe() via StringValue");
777 
778  //
779  // Set the Attribute to a positive value through a StringValue.
780  //
781  ok = p->SetAttributeFailSafe("TestInt16", StringValue("+2"));
782  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via StringValue to +2");
783 
784  ok = CheckGetCodePaths(p, "TestInt16", "2", IntegerValue(2));
786  true,
787  "Attribute not set properly by SetAttributeFailSafe() via StringValue");
788 
789  //
790  // Set the Attribute to the most negative value of the signed 16-bit range.
791  //
792  ok = p->SetAttributeFailSafe("TestInt16", StringValue("-32768"));
793  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via StringValue to -32768");
794 
795  ok = CheckGetCodePaths(p, "TestInt16", "-32768", IntegerValue(-32768));
797  ok,
798  true,
799  "Attribute not set properly by SetAttributeFailSafe() (most negative) via StringValue");
800 
801  //
802  // Try to set the Attribute past the most negative value of the signed 16-bit
803  // range and make sure the underlying attribute is unchanged.
804  //
805  ok = p->SetAttributeFailSafe("TestInt16", StringValue("-32769"));
807  false,
808  "Unexpectedly could SetAttributeFailSafe() via StringValue to -32769");
809 
810  ok = CheckGetCodePaths(p, "TestInt16", "-32768", IntegerValue(-32768));
811  NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
812 
813  //
814  // Set the Attribute to the most positive value of the signed 16-bit range.
815  //
816  ok = p->SetAttributeFailSafe("TestInt16", StringValue("32767"));
817  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via StringValue to 32767");
818 
819  ok = CheckGetCodePaths(p, "TestInt16", "32767", IntegerValue(32767));
821  ok,
822  true,
823  "Attribute not set properly by SetAttributeFailSafe() (most positive) via StringValue");
824 
825  //
826  // Try to set the Attribute past the most positive value of the signed 16-bit
827  // range and make sure the underlying attribute is unchanged.
828  //
829  ok = p->SetAttributeFailSafe("TestInt16", StringValue("32768"));
831  false,
832  "Unexpectedly could SetAttributeFailSafe() via StringValue to 32768");
833 
834  ok = CheckGetCodePaths(p, "TestInt16", "32767", IntegerValue(32767));
835  NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
836 
837  //
838  // Attributes can have limits other than the intrinsic limits of the
839  // underlying data types. These limits are specified in the Object.
840  //
841  ok = p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue(10));
842  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 10");
843 
844  ok = CheckGetCodePaths(p, "TestInt16WithBounds", "10", IntegerValue(10));
846  ok,
847  true,
848  "Attribute not set properly by SetAttributeFailSafe() (positive limit) via StringValue");
849 
850  //
851  // Set the Attribute past the positive limit.
852  //
853  ok = p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue(11));
855  false,
856  "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 11");
857 
858  ok = CheckGetCodePaths(p, "TestInt16WithBounds", "10", IntegerValue(10));
859  NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
860 
861  //
862  // Set the Attribute at the negative limit.
863  //
864  ok = p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue(-5));
865  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -5");
866 
867  ok = CheckGetCodePaths(p, "TestInt16WithBounds", "-5", IntegerValue(-5));
869  ok,
870  true,
871  "Attribute not set properly by SetAttributeFailSafe() (negative limit) via StringValue");
872 
873  //
874  // Set the Attribute past the negative limit.
875  //
876  ok = p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue(-6));
878  false,
879  "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -6");
880 
881  ok = CheckGetCodePaths(p, "TestInt16WithBounds", "-5", IntegerValue(-5));
882  NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
883 }
884 
885 template <>
886 void
888 {
889  auto p = CreateObject<AttributeObjectTest>();
890  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
891 
892  //
893  // When the object is first created, the Attribute should have the default
894  // value.
895  //
896  bool ok = CheckGetCodePaths(p, "TestUint8", "1", UintegerValue(1));
897  NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
898 
899  //
900  // Set the Attribute to zero.
901  //
902  ok = p->SetAttributeFailSafe("TestUint8", UintegerValue(0));
903  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to 0");
904 
905  ok = CheckGetCodePaths(p, "TestUint8", "0", UintegerValue(0));
907  true,
908  "Attribute not set properly by SetAttributeFailSafe() via StringValue");
909 
910  //
911  // Set the Attribute to the most positive value of the unsigned 8-bit range.
912  //
913  ok = p->SetAttributeFailSafe("TestUint8", UintegerValue(255));
914  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to 255");
915 
916  ok = CheckGetCodePaths(p, "TestUint8", "255", UintegerValue(255));
918  ok,
919  true,
920  "Attribute not set properly by SetAttributeFailSafe() (positive limit) via UintegerValue");
921 
922  //
923  // Try and set the Attribute past the most positive value of the unsigned
924  // 8-bit range.
925  //
926  ok = p->SetAttributeFailSafe("TestUint8", UintegerValue(256));
927  NS_TEST_ASSERT_MSG_EQ(ok, false, "Unexpectedly could SetAttributeFailSafe() to 256");
928 
929  ok = CheckGetCodePaths(p, "TestUint8", "255", UintegerValue(255));
930  NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
931 
932  //
933  // Set the Attribute to the most positive value of the unsigned 8-bit range
934  // through a StringValue.
935  //
936  ok = p->SetAttributeFailSafe("TestUint8", StringValue("255"));
937  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via StringValue to 255");
938 
939  ok = CheckGetCodePaths(p, "TestUint8", "255", UintegerValue(255));
941  true,
942  "Attribute not set properly by SetAttributeFailSafe() via StringValue");
943 
944  //
945  // Try and set the Attribute past the most positive value of the unsigned
946  // 8-bit range through a StringValue.
947  //
948  ok = p->SetAttributeFailSafe("TestUint8", StringValue("256"));
950  false,
951  "Unexpectedly could SetAttributeFailSafe() via StringValue to 256");
952 
953  ok = CheckGetCodePaths(p, "TestUint8", "255", UintegerValue(255));
954  NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
955 
956  //
957  // Try to set the Attribute to a negative StringValue.
958  //
959  ok = p->SetAttributeFailSafe("TestUint8", StringValue("-1"));
961  false,
962  "Unexpectedly could SetAttributeFailSafe() via StringValue to -1");
963 }
964 
965 template <>
966 void
968 {
969  auto p = CreateObject<AttributeObjectTest>();
970  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
971 
972  //
973  // When the object is first created, the Attribute should have the default
974  // value.
975  //
976  bool ok = CheckGetCodePaths(p, "TestFloat", "-1.1", DoubleValue(-1.1F));
977  NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
978 
979  //
980  // Set the Attribute.
981  //
982  ok = p->SetAttributeFailSafe("TestFloat", DoubleValue(2.3F));
983  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to 2.3");
984 
985  ok = CheckGetCodePaths(p, "TestFloat", "2.3", DoubleValue(2.3F));
987  true,
988  "Attribute not set properly by SetAttributeFailSafe() via DoubleValue");
989 }
990 
991 template <>
992 void
994 {
995  auto p = CreateObject<AttributeObjectTest>();
996  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
997 
998  //
999  // When the object is first created, the Attribute should have the default
1000  // value.
1001  //
1002  bool ok = CheckGetCodePaths(p, "TestEnum", "TestA", EnumValue(AttributeObjectTest::TEST_A));
1003  NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
1004 
1005  //
1006  // Set the Attribute using the EnumValue type.
1007  //
1008  ok = p->SetAttributeFailSafe("TestEnum", EnumValue(AttributeObjectTest::TEST_C));
1009  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to TEST_C");
1010 
1011  ok = CheckGetCodePaths(p, "TestEnum", "TestC", EnumValue(AttributeObjectTest::TEST_C));
1013  true,
1014  "Attribute not set properly by SetAttributeFailSafe() via EnumValue");
1015 
1016  //
1017  // When the object is first created, the Attribute should have the default
1018  // value.
1019  //
1020  ok = CheckGetCodePaths(p, "TestEnumSetGet", "TestB", EnumValue(AttributeObjectTest::TEST_B));
1021  NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
1022 
1023  //
1024  // Set the Attribute using the EnumValue type.
1025  //
1026  ok = p->SetAttributeFailSafe("TestEnumSetGet", EnumValue(AttributeObjectTest::TEST_C));
1027  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to TEST_C");
1028 
1029  ok = CheckGetCodePaths(p, "TestEnumSetGet", "TestC", EnumValue(AttributeObjectTest::TEST_C));
1031  true,
1032  "Attribute not set properly by SetAttributeFailSafe() via EnumValue");
1033 
1034  //
1035  // Set the Attribute using the StringValue type.
1036  //
1037  ok = p->SetAttributeFailSafe("TestEnum", StringValue("TestB"));
1038  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to TEST_B");
1039 
1040  ok = CheckGetCodePaths(p, "TestEnum", "TestB", EnumValue(AttributeObjectTest::TEST_B));
1042  true,
1043  "Attribute not set properly by SetAttributeFailSafe() via StringValue");
1044 
1045  //
1046  // Try to set the Attribute to a bogus enum using the StringValue type
1047  // throws a fatal error.
1048  //
1049  // ok = p->SetAttributeFailSafe ("TestEnum", StringValue ("TestD"));
1050  // NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() to TEST_D"); //
1051 
1052  ok = CheckGetCodePaths(p, "TestEnum", "TestB", EnumValue(AttributeObjectTest::TEST_B));
1053  NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
1054 
1055  //
1056  // Try to set the Attribute to a bogus enum using an integer implicit conversion
1057  // and make sure the underlying value doesn't change.
1058  //
1059  ok = p->SetAttributeFailSafe("TestEnum", EnumValue(5));
1060  NS_TEST_ASSERT_MSG_EQ(ok, false, "Unexpectedly could SetAttributeFailSafe() to 5");
1061 
1062  ok = CheckGetCodePaths(p, "TestEnum", "TestB", EnumValue(AttributeObjectTest::TEST_B));
1063  NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
1064 }
1065 
1066 template <>
1067 void
1069 {
1070  auto p = CreateObject<AttributeObjectTest>();
1071  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1072 
1073  //
1074  // When the object is first created, the Attribute should have the default
1075  // value.
1076  //
1077  bool ok = CheckGetCodePaths(p,
1078  "TestEnumClass",
1079  "TestD",
1081  NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
1082 
1083  //
1084  // Set the Attribute using the EnumValue type.
1085  //
1086  ok = p->SetAttributeFailSafe("TestEnumClass", EnumValue(AttributeObjectTest::Test_ec::TEST_F));
1087  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to TEST_F");
1088 
1089  ok = CheckGetCodePaths(p,
1090  "TestEnumClass",
1091  "TestF",
1094  true,
1095  "Attribute not set properly by SetAttributeFailSafe() via EnumValue");
1096 
1097  //
1098  // When the object is first created, the Attribute should have the default
1099  // value.
1100  //
1101  ok = CheckGetCodePaths(p,
1102  "TestEnumClassSetGet",
1103  "TestE",
1105  NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
1106 
1107  //
1108  // Set the Attribute using the EnumValue type.
1109  //
1110  ok = p->SetAttributeFailSafe("TestEnumClassSetGet",
1112  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to TEST_F");
1113 
1114  ok = CheckGetCodePaths(p,
1115  "TestEnumClassSetGet",
1116  "TestF",
1119  true,
1120  "Attribute not set properly by SetAttributeFailSafe() via EnumValue");
1121 
1122  //
1123  // Set the Attribute using the StringValue type.
1124  //
1125  ok = p->SetAttributeFailSafe("TestEnumClass", StringValue("TestE"));
1126  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to TEST_E");
1127 
1128  ok = CheckGetCodePaths(p,
1129  "TestEnumClass",
1130  "TestE",
1133  true,
1134  "Attribute not set properly by SetAttributeFailSafe() via StringValue");
1135 
1136  //
1137  // Try to set the Attribute to a bogus enum using the StringValue type
1138  // throws a fatal error.
1139  //
1140  // ok = p->SetAttributeFailSafe ("TestEnumClass", StringValue ("TestG"));
1141  // NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() to TEST_G"); //
1142 
1143  ok = CheckGetCodePaths(p,
1144  "TestEnumClass",
1145  "TestE",
1147  NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
1148 
1149  //
1150  // Try to set the Attribute to a bogus enum using an integer implicit conversion
1151  // and make sure the underlying value doesn't change.
1152  //
1153  ok = p->SetAttributeFailSafe("TestEnumClass", EnumValue(5));
1154  NS_TEST_ASSERT_MSG_EQ(ok, false, "Unexpectedly could SetAttributeFailSafe() to 5");
1155 
1156  ok = CheckGetCodePaths(p,
1157  "TestEnumClass",
1158  "TestE",
1160  NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
1161 }
1162 
1163 template <>
1164 void
1166 {
1167  auto p = CreateObject<AttributeObjectTest>();
1168  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1169 
1170  // The test vectors assume ns resolution
1171  Time::SetResolution(Time::NS);
1172 
1173  //
1174  // Set value
1175  //
1176  bool ok = p->SetAttributeFailSafe("TestTimeWithBounds", TimeValue(Seconds(5)));
1177  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via TimeValue to 5s");
1178 
1179  ok = CheckGetCodePaths(p, "TestTimeWithBounds", "+5e+09ns", TimeValue(Seconds(5)));
1181  true,
1182  "Attribute not set properly by SetAttributeFailSafe(5s) via TimeValue");
1183 
1184  ok = p->SetAttributeFailSafe("TestTimeWithBounds", StringValue("3s"));
1185  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via TimeValue to 3s");
1186 
1187  ok = CheckGetCodePaths(p, "TestTimeWithBounds", "+3e+09ns", TimeValue(Seconds(3)));
1189  true,
1190  "Attribute not set properly by SetAttributeFailSafe(3s) via StringValue");
1191 
1192  //
1193  // Attributes can have limits other than the intrinsic limits of the
1194  // underlying data types. These limits are specified in the Object.
1195  //
1196 
1197  //
1198  // Set the Attribute at the positive limit
1199  //
1200  ok = p->SetAttributeFailSafe("TestTimeWithBounds", TimeValue(Seconds(10)));
1201  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via TimeValue to 10s");
1202 
1203  ok = CheckGetCodePaths(p, "TestTimeWithBounds", "+1e+10ns", TimeValue(Seconds(10)));
1205  ok,
1206  true,
1207  "Attribute not set properly by SetAttributeFailSafe(10s [positive limit]) via StringValue");
1208 
1209  //
1210  // Set the Attribute past the positive limit.
1211  //
1212  ok = p->SetAttributeFailSafe("TestTimeWithBounds", TimeValue(Seconds(11)));
1214  false,
1215  "Unexpectedly could SetAttributeFailSafe() via TimeValue to 11s [greater "
1216  "than positive limit]");
1217 
1218  ok = CheckGetCodePaths(p, "TestTimeWithBounds", "+1e+10ns", TimeValue(Seconds(10)));
1219  NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
1220 
1221  //
1222  // Set the Attribute at the negative limit.
1223  //
1224  ok = p->SetAttributeFailSafe("TestTimeWithBounds", TimeValue(Seconds(-5)));
1225  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via TimeValue to -5s");
1226 
1227  ok = CheckGetCodePaths(p, "TestTimeWithBounds", "-5e+09ns", TimeValue(Seconds(-5)));
1229  ok,
1230  true,
1231  "Attribute not set properly by SetAttributeFailSafe(-5s [negative limit]) via StringValue");
1232 
1233  //
1234  // Set the Attribute past the negative limit.
1235  //
1236  ok = p->SetAttributeFailSafe("TestTimeWithBounds", TimeValue(Seconds(-6)));
1238  false,
1239  "Unexpectedly could SetAttributeFailSafe() via TimeValue to -6s");
1240 
1241  ok = CheckGetCodePaths(p, "TestTimeWithBounds", "-5e+09ns", TimeValue(Seconds(-5)));
1242  NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
1243 }
1244 
1251 {
1252  public:
1257  RandomVariableStreamAttributeTestCase(std::string description);
1258 
1260  {
1261  }
1262 
1267  void InvokeCbValue(int8_t a)
1268  {
1269  if (!m_cbValue.IsNull())
1270  {
1271  m_cbValue(a);
1272  }
1273  }
1274 
1275  private:
1276  void DoRun() override;
1277 
1280 
1285  void NotifyCallbackValue(int8_t a)
1286  {
1287  m_gotCbValue = a;
1288  }
1289 
1290  int16_t m_gotCbValue;
1291 };
1292 
1294  std::string description)
1295  : TestCase(description)
1296 {
1297 }
1298 
1299 void
1301 {
1302  auto p = CreateObject<AttributeObjectTest>();
1303  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1304 
1305  //
1306  // Try to set a UniformRandomVariable
1307  //
1308  bool ok = p->SetAttributeFailSafe("TestRandom",
1309  StringValue("ns3::UniformRandomVariable[Min=0.|Max=1.]"));
1310  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() a UniformRandomVariable");
1311 
1312  //
1313  // Try to set a <snicker> ConstantRandomVariable
1314  //
1315  ok = p->SetAttributeFailSafe("TestRandom",
1316  StringValue("ns3::ConstantRandomVariable[Constant=1.0]"));
1317  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() a ConstantRandomVariable");
1318 }
1319 
1328 {
1329  public:
1334  ObjectVectorAttributeTestCase(std::string description);
1335 
1337  {
1338  }
1339 
1340  private:
1341  void DoRun() override;
1342 };
1343 
1345  : TestCase(description)
1346 {
1347 }
1348 
1349 void
1351 {
1352  ObjectVectorValue vector;
1353 
1354  auto p = CreateObject<AttributeObjectTest>();
1355  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1356 
1357  //
1358  // When the object is first created, the Attribute should have no items in
1359  // the vector.
1360  //
1361  p->GetAttribute("TestVector1", vector);
1362  NS_TEST_ASSERT_MSG_EQ(vector.GetN(),
1363  0,
1364  "Initial count of ObjectVectorValue \"TestVector1\" should be zero");
1365 
1366  //
1367  // Adding to the attribute shouldn't affect the value we already have.
1368  //
1369  p->AddToVector1();
1371  vector.GetN(),
1372  0,
1373  "Initial count of ObjectVectorValue \"TestVector1\" should still be zero");
1374 
1375  //
1376  // Getting the attribute again should update the value.
1377  //
1378  p->GetAttribute("TestVector1", vector);
1379  NS_TEST_ASSERT_MSG_EQ(vector.GetN(),
1380  1,
1381  "ObjectVectorValue \"TestVector1\" should be incremented");
1382 
1383  //
1384  // Get the Object pointer from the value.
1385  //
1386  Ptr<Object> a = vector.Get(0);
1387  NS_TEST_ASSERT_MSG_NE(a, nullptr, "Ptr<Object> from VectorValue \"TestVector1\" is zero");
1388 
1389  //
1390  // Adding to the attribute shouldn't affect the value we already have.
1391  //
1392  p->AddToVector1();
1393  NS_TEST_ASSERT_MSG_EQ(vector.GetN(),
1394  1,
1395  "Count of ObjectVectorValue \"TestVector1\" should still be one");
1396 
1397  //
1398  // Getting the attribute again should update the value.
1399  //
1400  p->GetAttribute("TestVector1", vector);
1401  NS_TEST_ASSERT_MSG_EQ(vector.GetN(),
1402  2,
1403  "ObjectVectorValue \"TestVector1\" should be incremented");
1404 }
1405 
1412 {
1413  public:
1418  ObjectMapAttributeTestCase(std::string description);
1419 
1421  {
1422  }
1423 
1424  private:
1425  void DoRun() override;
1426 };
1427 
1429  : TestCase(description)
1430 {
1431 }
1432 
1433 void
1435 {
1436  ObjectMapValue map;
1437 
1438  auto p = CreateObject<AttributeObjectTest>();
1439  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1440 
1441  //
1442  // When the object is first created, the Attribute should have no items in
1443  // the vector.
1444  //
1445  p->GetAttribute("TestMap1", map);
1447  0,
1448  "Initial count of ObjectVectorValue \"TestMap1\" should be zero");
1449 
1450  //
1451  // Adding to the attribute shouldn't affect the value we already have.
1452  //
1453  p->AddToMap1(1);
1455  0,
1456  "Initial count of ObjectVectorValue \"TestMap1\" should still be zero");
1457 
1458  //
1459  // Getting the attribute again should update the value.
1460  //
1461  p->GetAttribute("TestMap1", map);
1462  NS_TEST_ASSERT_MSG_EQ(map.GetN(), 1, "ObjectVectorValue \"TestMap1\" should be incremented");
1463 
1464  //
1465  // Get the Object pointer from the value.
1466  //
1467  Ptr<Object> a = map.Get(1);
1468  NS_TEST_ASSERT_MSG_NE(a, nullptr, "Ptr<Object> from VectorValue \"TestMap1\" is zero");
1469 
1470  //
1471  // Adding to the attribute shouldn't affect the value we already have.
1472  //
1473  p->AddToMap1(2);
1475  1,
1476  "Count of ObjectVectorValue \"TestMap1\" should still be one");
1477 
1478  //
1479  // Getting the attribute again should update the value.
1480  //
1481  p->GetAttribute("TestMap1", map);
1482  NS_TEST_ASSERT_MSG_EQ(map.GetN(), 2, "ObjectVectorValue \"TestMap1\" should be incremented");
1483 
1484  //
1485  // Test that ObjectMapValue is iterable with an underlying unordered_map
1486  //
1487  ObjectMapValue unorderedMap;
1488  // Add objects at 1, 2, 3, 4
1489  p->AddToUnorderedMap(4);
1490  p->AddToUnorderedMap(2);
1491  p->AddToUnorderedMap(1);
1492  p->AddToUnorderedMap(3);
1493  // Remove object 2
1494  p->RemoveFromUnorderedMap(2);
1495  p->GetAttribute("TestUnorderedMap", unorderedMap);
1496  NS_TEST_ASSERT_MSG_EQ(unorderedMap.GetN(),
1497  3,
1498  "ObjectMapValue \"TestUnorderedMap\" should have three values");
1499  Ptr<Object> o1 = unorderedMap.Get(1);
1501  nullptr,
1502  "ObjectMapValue \"TestUnorderedMap\" should have value with key 1");
1503  Ptr<Object> o2 = unorderedMap.Get(2);
1505  nullptr,
1506  "ObjectMapValue \"TestUnorderedMap\" should not have value with key 2");
1507  auto it = unorderedMap.Begin();
1508  NS_TEST_ASSERT_MSG_EQ(it->first,
1509  1,
1510  "ObjectMapValue \"TestUnorderedMap\" should have a value with key 1");
1511  it++;
1512  NS_TEST_ASSERT_MSG_EQ(it->first,
1513  3,
1514  "ObjectMapValue \"TestUnorderedMap\" should have a value with key 3");
1515  it++;
1516  NS_TEST_ASSERT_MSG_EQ(it->first,
1517  4,
1518  "ObjectMapValue \"TestUnorderedMap\" should have a value with key 4");
1519 }
1520 
1528 {
1529  public:
1534  IntegerTraceSourceAttributeTestCase(std::string description);
1535 
1537  {
1538  }
1539 
1540  private:
1541  void DoRun() override;
1542 };
1543 
1545  : TestCase(description)
1546 {
1547 }
1548 
1549 void
1551 {
1552  IntegerValue iv;
1553 
1554  auto p = CreateObject<AttributeObjectTest>();
1555  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1556 
1557  //
1558  // When the object is first created, the Attribute should have the default
1559  // value.
1560  //
1561  p->GetAttribute("IntegerTraceSource1", iv);
1562  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -2, "Attribute not set properly by default value");
1563 
1564  //
1565  // Set the Attribute to a positive value through an IntegerValue.
1566  //
1567  bool ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(5));
1568  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 5");
1569 
1570  p->GetAttribute("IntegerTraceSource1", iv);
1572  5,
1573  "Attribute not set properly by SetAttributeFailSafe() via IntegerValue");
1574 
1575  //
1576  // Limits should work.
1577  //
1578  ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(127));
1579  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 127");
1580 
1581  ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(128));
1583  false,
1584  "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 128");
1585 
1586  ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(-128));
1587  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -128");
1588 
1589  ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(-129));
1591  false,
1592  "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -129");
1593 
1594  //
1595  // When the object is first created, the Attribute should have the default
1596  // value.
1597  //
1598  p->GetAttribute("IntegerTraceSource2", iv);
1599  NS_TEST_ASSERT_MSG_EQ(iv.Get(), -2, "Attribute not set properly by default value");
1600 
1601  //
1602  // Set the Attribute to a positive value through an IntegerValue.
1603  //
1604  ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue(5));
1605  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 5");
1606 
1607  p->GetAttribute("IntegerTraceSource2", iv);
1609  5,
1610  "Attribute not set properly by SetAttributeFailSafe() via IntegerValue");
1611 
1612  //
1613  // Limits should work.
1614  //
1615  ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue(127));
1616  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 127");
1617 
1618  ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue(128));
1620  false,
1621  "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 128");
1622 
1623  ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue(-128));
1624  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -128");
1625 
1626  ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue(-129));
1628  false,
1629  "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -129");
1630 }
1631 
1639 {
1640  public:
1645  IntegerTraceSourceTestCase(std::string description);
1646 
1648  {
1649  }
1650 
1651  private:
1652  void DoRun() override;
1653 
1659  void NotifySource1(int8_t old [[maybe_unused]], int8_t n)
1660  {
1661  m_got1 = n;
1662  }
1663 
1664  int64_t m_got1;
1665 };
1666 
1668  : TestCase(description)
1669 {
1670 }
1671 
1672 void
1674 {
1675  auto p = CreateObject<AttributeObjectTest>();
1676  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1677 
1678  //
1679  // Check to make sure changing an Attribute value triggers a trace callback
1680  // that sets a member variable.
1681  //
1682  m_got1 = 1234;
1683 
1684  bool ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(-1));
1685  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -1");
1686 
1687  //
1688  // Source1 is declared as a TraceSourceAccessor to m_intSrc1. This m_intSrc1
1689  // is also declared as an Integer Attribute. We just checked to make sure we
1690  // could set it using an IntegerValue through its IntegerTraceSource1 "persona."
1691  // We should also be able to hook a trace source to the underlying variable.
1692  //
1693  ok = p->TraceConnectWithoutContext(
1694  "Source1",
1697  true,
1698  "Could not TraceConnectWithoutContext() \"Source1\" to NodifySource1()");
1699 
1700  //
1701  // When we set the IntegerValue that now underlies both the Integer Attribute
1702  // and the trace source, the trace should fire and call NotifySource1 which
1703  // will set m_got1 to the new value.
1704  //
1705  ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(0));
1706  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 0");
1707 
1709  0,
1710  "Hitting a TracedValue does not cause trace callback to be called");
1711 
1712  //
1713  // Now disconnect from the trace source and ensure that the trace callback
1714  // is not called if the trace source is hit.
1715  //
1716  ok = p->TraceDisconnectWithoutContext(
1717  "Source1",
1720  true,
1721  "Could not TraceConnectWithoutContext() \"Source1\" to NodifySource1()");
1722 
1723  ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(1));
1724  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 1");
1725 
1727  0,
1728  "Hitting a TracedValue after disconnect still causes callback");
1729 }
1730 
1738 {
1739  public:
1744  TracedCallbackTestCase(std::string description);
1745 
1747  {
1748  }
1749 
1750  private:
1751  void DoRun() override;
1752 
1759  void NotifySource2(double a, int b [[maybe_unused]], float c [[maybe_unused]])
1760  {
1761  m_got2 = a;
1762  }
1763 
1764  double m_got2;
1765 };
1766 
1768  : TestCase(description)
1769 {
1770 }
1771 
1772 void
1774 {
1775  auto p = CreateObject<AttributeObjectTest>();
1776  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1777 
1778  //
1779  // Initialize the
1780  //
1781  m_got2 = 4.3;
1782 
1783  //
1784  // Invoke the callback that lies at the heart of this test. We have a
1785  // method InvokeCb() that just executes m_cb(). The variable m_cb is
1786  // declared as a TracedCallback<double, int, float>. This kind of beast
1787  // is like a callback but can call a list of targets. This list should
1788  // be empty so nothing should happen now. Specifically, m_got2 shouldn't
1789  // have changed.
1790  //
1791  p->InvokeCb(1.0, -5, 0.0);
1793  m_got2,
1794  4.3,
1795  "Invoking a newly created TracedCallback results in an unexpected callback");
1796 
1797  //
1798  // Now, wire the TracedCallback up to a trace sink. This sink will just set
1799  // m_got2 to the first argument.
1800  //
1801  bool ok =
1802  p->TraceConnectWithoutContext("Source2",
1804  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not TraceConnectWithoutContext() to NotifySource2");
1805 
1806  //
1807  // Now if we invoke the callback, the trace source should fire and m_got2
1808  // should be set in the trace sink.
1809  //
1810  p->InvokeCb(1.0, -5, 0.0);
1811  NS_TEST_ASSERT_MSG_EQ(m_got2, 1.0, "Invoking TracedCallback does not result in trace callback");
1812 
1813  //
1814  // Now, disconnect the trace sink and see what happens when we invoke the
1815  // callback again. Of course, the trace should not happen and m_got2
1816  // should remain unchanged.
1817  //
1818  ok = p->TraceDisconnectWithoutContext(
1819  "Source2",
1821  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not TraceDisconnectWithoutContext() from NotifySource2");
1822 
1823  p->InvokeCb(-1.0, -5, 0.0);
1825  m_got2,
1826  1.0,
1827  "Invoking disconnected TracedCallback unexpectedly results in trace callback");
1828 }
1829 
1837 {
1838  public:
1843  PointerAttributeTestCase(std::string description);
1844 
1846  {
1847  }
1848 
1849  private:
1850  void DoRun() override;
1851 
1858  void NotifySource2(double a, int b [[maybe_unused]], float c [[maybe_unused]])
1859  {
1860  m_got2 = a;
1861  }
1862 
1863  double m_got2;
1864 };
1865 
1867  : TestCase(description)
1868 {
1869 }
1870 
1871 void
1873 {
1874  auto p = CreateObject<AttributeObjectTest>();
1875  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1876 
1877  //
1878  // We have declared a PointerValue Attribute named "Pointer" with a pointer
1879  // checker of type Derived. This means that we should be able to pull out
1880  // a Ptr<Derived> with the initial value (which is 0).
1881  //
1882  PointerValue ptr;
1883  p->GetAttribute("Pointer", ptr);
1884  Ptr<Derived> derived = ptr.Get<Derived>();
1886  (bool)derived,
1887  false,
1888  "Unexpectedly found non-null pointer in newly initialized PointerValue Attribute");
1889 
1890  //
1891  // Now, lets create an Object of type Derived and set the local Ptr to point
1892  // to that object. We can then set the PointerValue Attribute to that Ptr.
1893  //
1894  derived = Create<Derived>();
1895  bool ok = p->SetAttributeFailSafe("Pointer", PointerValue(derived));
1897  true,
1898  "Could not SetAttributeFailSafe() a PointerValue of the correct type");
1899 
1900  //
1901  // Pull the value back out of the Attribute and make sure it points to the
1902  // correct object.
1903  //
1904  p->GetAttribute("Pointer", ptr);
1905  Ptr<Derived> stored = ptr.Get<Derived>();
1906  NS_TEST_ASSERT_MSG_EQ(stored,
1907  derived,
1908  "Retrieved Attribute does not match stored PointerValue");
1909 
1910  //
1911  // We should be able to use the Attribute Get() just like GetObject<type>,
1912  // So see if we can get a Ptr<Object> out of the Ptr<Derived> we stored.
1913  // This should be a pointer to the same physical memory since its the
1914  // same object.
1915  //
1916  p->GetAttribute("Pointer", ptr);
1917  Ptr<Object> storedBase = ptr.Get<Object>();
1918  NS_TEST_ASSERT_MSG_EQ(storedBase,
1919  stored,
1920  "Retrieved Ptr<Object> does not match stored Ptr<Derived>");
1921 
1922  //
1923  // If we try to Get() something that is unrelated to what we stored, we should
1924  // retrieve a 0.
1925  //
1926  p->GetAttribute("Pointer", ptr);
1928  NS_TEST_ASSERT_MSG_EQ((bool)x,
1929  false,
1930  "Unexpectedly retrieved unrelated Ptr<type> from stored Ptr<Derived>");
1931 
1932  //
1933  // Test whether the initialized pointers from two different objects
1934  // point to different Derived objects
1935  //
1936  p->GetAttribute("PointerInitialized", ptr);
1937  Ptr<Derived> storedPtr = ptr.Get<Derived>();
1938  Ptr<AttributeObjectTest> p2 = CreateObject<AttributeObjectTest>();
1939  PointerValue ptr2;
1940  p2->GetAttribute("PointerInitialized", ptr2);
1941  Ptr<Derived> storedPtr2 = ptr2.Get<Derived>();
1942  NS_TEST_ASSERT_MSG_NE(storedPtr,
1943  storedPtr2,
1944  "ptr and ptr2 both have PointerInitialized pointing to the same object");
1945  PointerValue ptr3;
1946  p2->GetAttribute("PointerInitialized", ptr3);
1947  Ptr<Derived> storedPtr3 = ptr3.Get<Derived>();
1948  NS_TEST_ASSERT_MSG_NE(storedPtr,
1949  storedPtr3,
1950  "ptr and ptr3 both have PointerInitialized pointing to the same object");
1951 
1952  //
1953  // Test whether object factory creates the objects properly
1954  //
1955  ObjectFactory factory;
1956  factory.SetTypeId("ns3::AttributeObjectTest");
1957  factory.Set("PointerInitialized", StringValue("ns3::Derived"));
1959  NS_TEST_ASSERT_MSG_NE(aotPtr, nullptr, "Unable to factory.Create() a AttributeObjectTest");
1961  NS_TEST_ASSERT_MSG_NE(aotPtr2, nullptr, "Unable to factory.Create() a AttributeObjectTest");
1962  NS_TEST_ASSERT_MSG_NE(aotPtr, aotPtr2, "factory object not creating unique objects");
1963  PointerValue ptr4;
1964  aotPtr->GetAttribute("PointerInitialized", ptr4);
1965  Ptr<Derived> storedPtr4 = ptr4.Get<Derived>();
1966  PointerValue ptr5;
1967  aotPtr2->GetAttribute("PointerInitialized", ptr5);
1968  Ptr<Derived> storedPtr5 = ptr5.Get<Derived>();
1969  NS_TEST_ASSERT_MSG_NE(storedPtr4,
1970  storedPtr5,
1971  "aotPtr and aotPtr2 are unique, but their Derived member is not");
1972 }
1973 
1980 {
1981  public:
1986  CallbackValueTestCase(std::string description);
1987 
1989  {
1990  }
1991 
1996  void InvokeCbValue(int8_t a)
1997  {
1998  if (!m_cbValue.IsNull())
1999  {
2000  m_cbValue(a);
2001  }
2002  }
2003 
2004  private:
2005  void DoRun() override;
2006 
2008 
2013  void NotifyCallbackValue(int8_t a)
2014  {
2015  m_gotCbValue = a;
2016  }
2017 
2018  int16_t m_gotCbValue;
2019 };
2020 
2022  : TestCase(description)
2023 {
2024 }
2025 
2026 void
2028 {
2029  auto p = CreateObject<AttributeObjectTest>();
2030  NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
2031 
2032  //
2033  // The member variable m_cbValue is declared as a Callback<void, int8_t>. The
2034  // Attribute named "Callback" also points to m_cbValue and allows us to set the
2035  // callback using that Attribute.
2036  //
2037  // NotifyCallbackValue is going to be the target of the callback and will just set
2038  // m_gotCbValue to its single parameter. This will be the parameter from the
2039  // callback invocation. The method InvokeCbValue() just invokes the m_cbValue
2040  // callback if it is non-null.
2041  //
2042  m_gotCbValue = 1;
2043 
2044  //
2045  // If we invoke the callback (which has not been set) nothing should happen.
2046  // Further, nothing should happen when we initialize the callback (it shouldn't
2047  // accidentally fire).
2048  //
2049  p->InvokeCbValue(2);
2051 
2052  NS_TEST_ASSERT_MSG_EQ(m_gotCbValue, 1, "Callback unexpectedly fired");
2053 
2054  bool ok = p->SetAttributeFailSafe("Callback", cbValue);
2055  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() a CallbackValue");
2056 
2057  //
2058  // Now that the callback has been set, invoking it should set m_gotCbValue.
2059  //
2060  p->InvokeCbValue(2);
2061  NS_TEST_ASSERT_MSG_EQ(m_gotCbValue, 2, "Callback Attribute set by CallbackValue did not fire");
2062 
2063  ok = p->SetAttributeFailSafe("Callback", CallbackValue(MakeNullCallback<void, int8_t>()));
2064  NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() a null CallbackValue");
2065 
2066  //
2067  // If the callback has been set to a null callback, it should no longer fire.
2068  //
2069  p->InvokeCbValue(3);
2071  2,
2072  "Callback Attribute set to null callback unexpectedly fired");
2073 }
2074 
2081 {
2082  public:
2084 };
2085 
2087  : TestSuite("attributes", UNIT)
2088 {
2089  AddTestCase(new AttributeTestCase<BooleanValue>("Check Attributes of type BooleanValue"),
2090  TestCase::QUICK);
2091  AddTestCase(new AttributeTestCase<IntegerValue>("Check Attributes of type IntegerValue"),
2092  TestCase::QUICK);
2093  AddTestCase(new AttributeTestCase<UintegerValue>("Check Attributes of type UintegerValue"),
2094  TestCase::QUICK);
2095  AddTestCase(new AttributeTestCase<DoubleValue>("Check Attributes of type DoubleValue"),
2096  TestCase::QUICK);
2098  "Check Attributes of type EnumValue"),
2099  TestCase::QUICK);
2101  "Check Attributes of type EnumValue (wrapping an enum class)"),
2102  TestCase::QUICK);
2103  AddTestCase(new AttributeTestCase<TimeValue>("Check Attributes of type TimeValue"),
2104  TestCase::QUICK);
2105  AddTestCase(
2106  new RandomVariableStreamAttributeTestCase("Check Attributes of type RandomVariableStream"),
2107  TestCase::QUICK);
2108  AddTestCase(new ObjectVectorAttributeTestCase("Check Attributes of type ObjectVectorValue"),
2109  TestCase::QUICK);
2110  AddTestCase(new ObjectMapAttributeTestCase("Check Attributes of type ObjectMapValue"),
2111  TestCase::QUICK);
2112  AddTestCase(new PointerAttributeTestCase("Check Attributes of type PointerValue"),
2113  TestCase::QUICK);
2114  AddTestCase(new CallbackValueTestCase("Check Attributes of type CallbackValue"),
2115  TestCase::QUICK);
2117  "Ensure TracedValue<uint8_t> can be set like IntegerValue"),
2118  TestCase::QUICK);
2119  AddTestCase(
2120  new IntegerTraceSourceTestCase("Ensure TracedValue<uint8_t> also works as trace source"),
2121  TestCase::QUICK);
2123  "Ensure TracedCallback<double, int, float> works as trace source"),
2124  TestCase::QUICK);
2125 }
2126 
static AttributesTestSuite g_attributesTestSuite
Static variable for test initialization.
Class used to check attributes.
std::size_t DoGetVectorN() const
Get the length of m_vector2.
bool DoSetIntSrc(int8_t v)
Set the m_intSrc2 value.
bool m_boolTest
Boolean test.
std::unordered_map< uint64_t, Ptr< Derived > > m_unorderedMap
Unordered map of uint64_t, derived objects.
void AddToVector2()
Add an object to the second vector.
std::map< uint32_t, Ptr< Derived > > m_map1
Map of uint32_t, derived objects.
int16_t m_int16SetGet
16-bit integer set-get.
Test_e DoGetEnum() const
Get the m_enumSetGet value.
bool DoGetTestA() const
Get the m_boolTestA value.
Test_ec m_enumClassSetGet
Enum class set-get.
void InvokeCb(double a, int b, float c)
Invoke the m_cb callback.
Ptr< Derived > DoGetVector(std::size_t i) const
Get the i-th item of m_vector2.
Test_ec m_enumclass
Enum class.
Ptr< RandomVariableStream > m_random
Random number generator.
bool m_boolTestA
Boolean test A.
int16_t m_int16
16-bit integer.
void AddToUnorderedMap(uint64_t i)
Adds an object to the unordered map.
static TypeId GetTypeId()
Get the type ID.
std::vector< Ptr< Derived > > m_vector1
First vector of derived objects.
Callback< void, int8_t > m_cbValue
Callback accepting an integer.
void InvokeCbValue(int8_t a)
Invoke the m_cbValue callback.
TracedValue< double > m_doubleSrc
double Traced value.
bool m_boolTestDeprecated
Boolean test deprecated.
void AddToMap1(uint32_t i)
Adds an object to the first map.
Test_ec DoGetEnumClass() const
Get the m_enumClassSetGet value.
TracedCallback< double, int, float > m_cb
TracedCallback (double, int, float).
bool DoSetEnumClass(Test_ec v)
Set the m_enumClassSetGet value.
Ptr< Derived > m_ptr
Pointer to Derived class.
int16_t m_int16WithBounds
16-bit integer with bounds.
TracedValue< int8_t > m_intSrc1
First int8_t Traced value.
TracedValue< Test_e > m_enumSrc
enum Traced value.
Ptr< Derived > m_ptrInitialized
Pointer to Derived class.
void AddToVector1()
Add an object to the first vector.
Ptr< Derived > m_ptrInitialized2
Pointer to Derived class.
int16_t DoGetInt16() const
Get the m_int16SetGet value.
TracedValue< ValueClassTest > m_valueSrc
ValueClassTest Traced value.
void DoSetTestA(bool v)
Set the m_boolTestA value.
TracedValue< uint8_t > m_uintSrc
uint8_t Traced value.
TracedValue< bool > m_boolSrc
bool Traced value.
TracedValue< int8_t > m_intSrc2
Second int8_t Traced value.
Test_e m_enumSetGet
Enum set-get.
Time m_timeWithBounds
Time with bounds.
int8_t DoGetIntSrc() const
Get the m_intSrc2 value.
uint8_t m_uint8
8-bit integer.
std::vector< Ptr< Derived > > m_vector2
Second vector of derived objects.
bool DoSetEnum(Test_e v)
Set the m_enumSetGet value.
void RemoveFromUnorderedMap(uint64_t i)
Remove an object from the first map.
void DoSetInt16(int16_t v)
Set the m_int16SetGet value.
Test case template used for generic Attribute Value types – used to make sure that Attributes work as...
bool CheckGetCodePaths(Ptr< Object > p, std::string attributeName, std::string expectedString, T expectedValue)
Check the attribute path and value.
AttributeTestCase(std::string description)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
The attributes Test Suite.
Test the Attributes of type CallbackValue.
CallbackValueTestCase(std::string description)
Constructor.
void NotifyCallbackValue(int8_t a)
Function invoked when the callback is fired.
void DoRun() override
Implementation to actually run this TestCase.
void InvokeCbValue(int8_t a)
Function to invoke the callback.
Callback< void, int8_t > m_cbValue
The callback.
int16_t m_gotCbValue
Value used to verify that source 2 was called.
Simple class derived from ns3::Object, used to check attribute constructors.
static TypeId GetTypeId()
Get the type ID.
Trace sources with value semantics can be used like Attributes, make sure we can use them that way.
IntegerTraceSourceAttributeTestCase(std::string description)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
Trace sources used like Attributes must also work as trace sources, make sure we can use them that wa...
int64_t m_got1
Value used to verify that source 1 was called.
void NotifySource1(int8_t old[[maybe_unused]], int8_t n)
Notify the call of source 1.
IntegerTraceSourceTestCase(std::string description)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
Test case for Object Map Attributes.
ObjectMapAttributeTestCase(std::string description)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
Test case for Object Vector Attributes.
ObjectVectorAttributeTestCase(std::string description)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
Smart pointers (Ptr) are central to our architecture, so they must work as attributes.
void DoRun() override
Implementation to actually run this TestCase.
void NotifySource2(double a, int b[[maybe_unused]], float c[[maybe_unused]])
Notify the call of source 2.
double m_got2
Value used to verify that source 2 was called.
PointerAttributeTestCase(std::string description)
Constructor.
Test the Attributes of type RandomVariableStream.
void InvokeCbValue(int8_t a)
Invoke the m_cbValue.
Callback< void, int8_t > m_cbValue
Callback used in the test.
void DoRun() override
Implementation to actually run this TestCase.
void NotifyCallbackValue(int8_t a)
Function called when the callback is used.
RandomVariableStreamAttributeTestCase(std::string description)
Constructor.
int16_t m_gotCbValue
Value used to verify that the callback has been invoked.
Trace sources used like Attributes must also work as trace sources, make sure we can use them that wa...
void NotifySource2(double a, int b[[maybe_unused]], float c[[maybe_unused]])
Notify the call of source 2.
TracedCallbackTestCase(std::string description)
Constructor.
double m_got2
Value used to verify that source 2 was called.
void DoRun() override
Implementation to actually run this TestCase.
bool IsNull() const
Check for null implementation.
Definition: callback.h:569
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Hold variables of type enum.
Definition: enum.h:62
Hold a signed integer type.
Definition: integer.h:45
int64_t Get() const
Definition: integer.cc:37
bool GetAttributeFailSafe(std::string name, AttributeValue &value) const
Get the value of an attribute without raising errors.
Definition: object-base.cc:281
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void Set(const std::string &name, const AttributeValue &value, Args &&... args)
Set an attribute to be set during construction.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
A base class which provides memory management and object aggregation.
Definition: object.h:89
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
Container for a set of ns3::Object pointers.
std::size_t GetN() const
Get the number of Objects.
Iterator Begin() const
Get an iterator to the first Object.
Ptr< Object > Get(std::size_t i) const
Get a specific Object.
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Ptr< T > Get() const
Definition: pointer.h:202
Hold variables of type string.
Definition: string.h:56
std::string Get() const
Definition: string.cc:31
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
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
TypeId AddConstructor()
Record in this TypeId the fact that the default constructor is accessible.
Definition: type-id.h:651
@ DEPRECATED
Attribute or trace source is deprecated; user is warned.
Definition: type-id.h:75
Hold an unsigned integer type.
Definition: uinteger.h:45
Test class for TracedValue callbacks attributes.
void(* TracedValueCallback)(const ValueClassTest oldValue, const ValueClassTest newValue)
TracedValue callback signature for ValueClassTest.
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
bool SetDefaultFailSafe(std::string fullName, const AttributeValue &value)
Definition: config.cc:900
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
#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
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Definition: test.h:564
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
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.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
Ptr< const AttributeAccessor > MakeCallbackAccessor(T1 a1)
Definition: callback.h:844
bool operator!=(Callback< R, Args... > a, Callback< R, Args... > b)
Inequality test.
Definition: callback.h:678
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
ATTRIBUTE_HELPER_HEADER(ValueClassTest)
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Definition: integer.h:46
ObjectPtrContainerValue ObjectMapValue
ObjectMapValue is an alias for ObjectPtrContainerValue.
Definition: object-map.h:40
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
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:194
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
ATTRIBUTE_HELPER_CPP(ValueClassTest)
Ptr< const AttributeChecker > MakeCallbackChecker()
Definition: callback.cc:82
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:183
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159
Ptr< const AttributeAccessor > MakeObjectMapAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-map.h:76