A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
attribute-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 University of Washington
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#include "ns3/boolean.h"
8#include "ns3/callback.h"
9#include "ns3/config.h"
10#include "ns3/double.h"
11#include "ns3/enum.h"
12#include "ns3/integer.h"
13#include "ns3/nstime.h"
14#include "ns3/object-factory.h"
15#include "ns3/object-map.h"
16#include "ns3/object-vector.h"
17#include "ns3/object.h"
18#include "ns3/pointer.h"
19#include "ns3/random-variable-stream.h"
20#include "ns3/string.h"
21#include "ns3/test.h"
22#include "ns3/trace-source-accessor.h"
23#include "ns3/traced-value.h"
24#include "ns3/uinteger.h"
25
26using namespace ns3;
27
28namespace ns3
29{
30
31/**
32 * \file
33 * \ingroup attribute-tests
34 * Attribute test suite
35 */
36
37/**
38 * \ingroup core-tests
39 * \defgroup attribute-tests Attribute tests
40 */
41
42/**
43 * \ingroup attribute-tests
44 *
45 * Test class for TracedValue callbacks attributes.
46 * \see attribute_ValueClassTest
47 */
49{
50 public:
52 {
53 }
54
55 /**
56 * TracedValue callback signature for ValueClassTest
57 *
58 * \param [in] oldValue original value of the traced variable
59 * \param [in] newValue new value of the traced variable
60 */
61 typedef void (*TracedValueCallback)(const ValueClassTest oldValue,
62 const ValueClassTest newValue);
63};
64
65/**
66 * Operator not equal.
67 * \param a The left operand.
68 * \param b The right operand.
69 * \return always true.
70 */
71bool
72operator!=(const ValueClassTest& a [[maybe_unused]], const ValueClassTest& b [[maybe_unused]])
73{
74 return true;
75}
76
77/**
78 * \brief Stream insertion operator.
79 *
80 * \param [in] os The reference to the output stream.
81 * \param [in] v The ValueClassTest object.
82 * \returns The reference to the output stream.
83 */
84std::ostream&
85operator<<(std::ostream& os, ValueClassTest v [[maybe_unused]])
86{
87 return os;
88}
89
90/**
91 * \brief Stream extraction operator.
92 *
93 * \param [in] is The reference to the input stream.
94 * \param [out] v The ValueClassTest object.
95 * \returns The reference to the input stream.
96 */
97std::istream&
98operator>>(std::istream& is, ValueClassTest& v [[maybe_unused]])
99{
100 return is;
101}
102
105
106} // namespace ns3
107
108/**
109 * \ingroup attribute-tests
110 *
111 * Simple class derived from ns3::Object, used to check attribute constructors.
112 */
113class Derived : public Object
114{
115 public:
116 /**
117 * \brief Get the type ID.
118 * \return The object TypeId.
119 */
121 {
122 static TypeId tid = TypeId("ns3::Derived").AddConstructor<Derived>().SetParent<Object>();
123 return tid;
124 }
125
127 {
128 }
129};
130
132
133/**
134 * \ingroup attribute-tests
135 *
136 * Class used to check attributes.
137 */
139{
140 public:
141 /// Test enumerator.
143 {
144 TEST_A, //!< Test value A.
145 TEST_B, //!< Test value B.
146 TEST_C //!< Test value C.
147 };
148
149 /// Test enumerator.
150 enum class Test_ec
151 {
152 TEST_D, //!< Test value D.
153 TEST_E, //!< Test value E.
154 TEST_F //!< Test value F.
155 };
156
157 /**
158 * \brief Get the type ID.
159 * \return The object TypeId.
160 */
162 {
163 static TypeId tid =
164 TypeId("ns3::AttributeObjectTest")
166 .SetParent<Object>()
167 .HideFromDocumentation()
168 .AddAttribute("TestBoolName",
169 "help text",
170 BooleanValue(false),
173 .AddAttribute("TestBoolA",
174 "help text",
175 BooleanValue(false),
179 .AddAttribute("TestInt16",
180 "help text",
181 IntegerValue(-2),
184 .AddAttribute("TestInt16WithBounds",
185 "help text",
186 IntegerValue(-2),
189 .AddAttribute("TestInt16SetGet",
190 "help text",
191 IntegerValue(6),
195 .AddAttribute("TestUint8",
196 "help text",
197 UintegerValue(1),
200 .AddAttribute("TestEnum",
201 "help text",
204 MakeEnumChecker(TEST_A, "TestA", TEST_B, "TestB", TEST_C, "TestC"))
205 .AddAttribute("TestEnumSetGet",
206 "help text",
210 MakeEnumChecker(TEST_A, "TestA", TEST_B, "TestB", TEST_C, "TestC"))
211 .AddAttribute("TestEnumClass",
212 "help text",
216 "TestD",
218 "TestE",
220 "TestF"))
221 .AddAttribute("TestEnumClassSetGet",
222 "help text",
227 "TestD",
229 "TestE",
231 "TestF"))
232 .AddAttribute("TestRandom",
233 "help text",
234 StringValue("ns3::ConstantRandomVariable[Constant=1.0]"),
237 .AddAttribute("TestFloat",
238 "help text",
239 DoubleValue(-1.1),
242 .AddAttribute("TestVector1",
243 "help text",
247 .AddAttribute("TestVector2",
248 "help text",
253 .AddAttribute("TestMap1",
254 "help text",
258 .AddAttribute("TestUnorderedMap",
259 "help text",
263 .AddAttribute("IntegerTraceSource1",
264 "help text",
265 IntegerValue(-2),
268 .AddAttribute("IntegerTraceSource2",
269 "help text",
270 IntegerValue(-2),
274 .AddAttribute("UIntegerTraceSource",
275 "help text",
276 UintegerValue(2),
279 .AddAttribute("DoubleTraceSource",
280 "help text",
281 DoubleValue(2),
284 .AddAttribute("BoolTraceSource",
285 "help text",
286 BooleanValue(false),
289 .AddAttribute(
290 "EnumTraceSource",
291 "help text",
294 MakeEnumChecker(TEST_A, "TestA"))
295 .AddAttribute("ValueClassSource",
296 "help text",
300 .AddTraceSource("Source1",
301 "help test",
303 "ns3::TracedValueCallback::Int8")
304 .AddTraceSource("Source2",
305 "help text",
307 "ns3::AttributeObjectTest::NumericTracedCallback")
308 .AddTraceSource("ValueSource",
309 "help text",
311 "ns3::ValueClassTest::TracedValueCallback")
312 .AddAttribute("Pointer",
313 "help text",
314 PointerValue(),
317 .AddAttribute("PointerInitialized",
318 "help text",
319 StringValue("ns3::Derived"),
322 .AddAttribute("PointerInitialized2",
323 "help text",
324 StringValue("ns3::Derived[]"),
327 .AddAttribute("Callback",
328 "help text",
332 .AddAttribute("TestTimeWithBounds",
333 "help text",
334 TimeValue(Seconds(-2)),
337 .AddAttribute("TestDeprecated",
338 "help text",
339 BooleanValue(false),
343 "DEPRECATED test working.");
344
345 return tid;
346 }
347
349 {
350 }
351
353 {
354 }
355
356 /// Add an object to the first vector.
358 {
359 m_vector1.push_back(CreateObject<Derived>());
360 }
361
362 /// Add an object to the second vector.
364 {
365 m_vector2.push_back(CreateObject<Derived>());
366 }
367
368 /**
369 * Adds an object to the first map.
370 * \param i The index to assign to the object.
371 */
373 {
374 m_map1.insert(std::pair<uint32_t, Ptr<Derived>>(i, CreateObject<Derived>()));
375 }
376
377 /**
378 * Adds an object to the unordered map.
379 * \param i The index to assign to the object.
380 */
381 void AddToUnorderedMap(uint64_t i)
382 {
384 }
385
386 /**
387 * Remove an object from the first map.
388 * \param i The index to assign to the object.
389 */
390 void RemoveFromUnorderedMap(uint64_t i)
391 {
392 m_unorderedMap.erase(i);
393 }
394
395 /**
396 * Invoke the m_cb callback.
397 * \param a The first argument of the callback.
398 * \param b The second argument of the callback.
399 * \param c The third argument of the callback.
400 */
401 void InvokeCb(double a, int b, float c)
402 {
403 m_cb(a, b, c);
404 }
405
406 /**
407 * Invoke the m_cbValue callback.
408 * \param a The argument of the callback.
409 */
411 {
412 if (!m_cbValue.IsNull())
413 {
414 m_cbValue(a);
415 }
416 }
417
418 private:
419 /**
420 * Set the m_boolTestA value.
421 * \param v The value to set.
422 */
423 void DoSetTestA(bool v)
424 {
425 m_boolTestA = v;
426 }
427
428 /**
429 * Get the m_boolTestA value.
430 * \return the value of m_boolTestA.
431 */
432 bool DoGetTestA() const
433 {
434 return m_boolTestA;
435 }
436
437 /**
438 * Get the m_int16SetGet value.
439 * \return the value of m_int16SetGet.
440 */
441 int16_t DoGetInt16() const
442 {
443 return m_int16SetGet;
444 }
445
446 /**
447 * Set the m_int16SetGet value.
448 * \param v The value to set.
449 */
450 void DoSetInt16(int16_t v)
451 {
452 m_int16SetGet = v;
453 }
454
455 /**
456 * Get the length of m_vector2.
457 * \return the vector size.
458 */
459 std::size_t DoGetVectorN() const
460 {
461 return m_vector2.size();
462 }
463
464 /**
465 * Get the i-th item of m_vector2.
466 * \param i The index of the element to get.
467 * \return i-th item of m_vector2.
468 */
469 Ptr<Derived> DoGetVector(std::size_t i) const
470 {
471 return m_vector2[i];
472 }
473
474 /**
475 * Set the m_intSrc2 value.
476 * \param v The value to set.
477 * \return true.
478 */
480 {
481 m_intSrc2 = v;
482 return true;
483 }
484
485 /**
486 * Get the m_intSrc2 value.
487 * \return the value of m_intSrc2.
488 */
490 {
491 return m_intSrc2;
492 }
493
494 /**
495 * Set the m_enumSetGet value.
496 * \param v The value to set.
497 * \return true.
498 */
500 {
501 m_enumSetGet = v;
502 return true;
503 }
504
505 /**
506 * Get the m_enumSetGet value.
507 * \return the value of m_enumSetGet.
508 */
510 {
511 return m_enumSetGet;
512 }
513
514 /**
515 * Set the m_enumClassSetGet value.
516 * \param v The value to set.
517 * \return true.
518 */
520 {
522 return true;
523 }
524
525 /**
526 * Get the m_enumClassSetGet value.
527 * \return the value of m_enumSetGet.
528 */
530 {
531 return m_enumClassSetGet;
532 }
533
534 bool m_boolTestA; //!< Boolean test A.
535 bool m_boolTest; //!< Boolean test.
536 bool m_boolTestDeprecated; //!< Boolean test deprecated.
537 int16_t m_int16; //!< 16-bit integer.
538 int16_t m_int16WithBounds; //!< 16-bit integer with bounds.
539 int16_t m_int16SetGet; //!< 16-bit integer set-get.
540 uint8_t m_uint8; //!< 8-bit integer.
541 float m_float; //!< float.
542 Test_e m_enum; //!< Enum.
543 Test_e m_enumSetGet; //!< Enum set-get.
544 Test_ec m_enumclass; //!< Enum class.
545 Test_ec m_enumClassSetGet; //!< Enum class set-get.
546 Ptr<RandomVariableStream> m_random; //!< Random number generator.
547 std::vector<Ptr<Derived>> m_vector1; //!< First vector of derived objects.
548 std::vector<Ptr<Derived>> m_vector2; //!< Second vector of derived objects.
549 std::map<uint32_t, Ptr<Derived>> m_map1; //!< Map of uint32_t, derived objects.
550 std::unordered_map<uint64_t, Ptr<Derived>>
551 m_unorderedMap; //!< Unordered map of uint64_t, derived objects.
552 Callback<void, int8_t> m_cbValue; //!< Callback accepting an integer.
553 TracedValue<int8_t> m_intSrc1; //!< First int8_t Traced value.
554 TracedValue<int8_t> m_intSrc2; //!< Second int8_t Traced value.
555
556 /// Traced callbacks for (double, int, float) values.
557 typedef void (*NumericTracedCallback)(double, int, float);
558 TracedCallback<double, int, float> m_cb; //!< TracedCallback (double, int, float).
559 TracedValue<ValueClassTest> m_valueSrc; //!< ValueClassTest Traced value.
560 Ptr<Derived> m_ptr; //!< Pointer to Derived class.
561 Ptr<Derived> m_ptrInitialized; //!< Pointer to Derived class.
562 Ptr<Derived> m_ptrInitialized2; //!< Pointer to Derived class.
563 TracedValue<uint8_t> m_uintSrc; //!< uint8_t Traced value.
564 TracedValue<Test_e> m_enumSrc; //!< enum Traced value.
565 TracedValue<double> m_doubleSrc; //!< double Traced value.
566 TracedValue<bool> m_boolSrc; //!< bool Traced value.
567 Time m_timeWithBounds; //!< Time with bounds
568};
569
571
572/**
573 * \ingroup attribute-tests
574 *
575 * \brief Test case template used for generic Attribute Value types -- used to make
576 * sure that Attributes work as expected.
577 */
578template <typename T>
580{
581 public:
582 /**
583 * Constructor.
584 * \param description The TestCase description.
585 */
586 AttributeTestCase(std::string description);
587 ~AttributeTestCase() override;
588
589 private:
590 void DoRun() override;
591 /**
592 * Check the attribute path and value.
593 * \param p The object to test.
594 * \param attributeName The attribute name.
595 * \param expectedString The expected attribute name.
596 * \param expectedValue The expected attribute value.
597 * \return true if everything is as expected.
598 */
600 std::string attributeName,
601 std::string expectedString,
602 T expectedValue);
603};
604
605template <typename T>
607 : TestCase(description)
608{
609}
610
611template <typename T>
615
616template <typename T>
617bool
619 std::string attributeName,
620 std::string expectedString,
621 T expectedValue)
622{
623 StringValue stringValue;
624 T actualValue;
625
626 //
627 // Get an Attribute value through its StringValue representation.
628 //
629 bool ok1 = p->GetAttributeFailSafe(attributeName, stringValue);
630 bool ok2 = stringValue.Get() == expectedString;
631
632 //
633 // Get the existing boolean value through its particular type representation.
634 //
635 bool ok3 = p->GetAttributeFailSafe(attributeName, actualValue);
636 bool ok4 = expectedValue.Get() == actualValue.Get();
637
638 return ok1 && ok2 && ok3 && ok4;
639}
640
641// ===========================================================================
642// The actual Attribute type test cases are specialized for each Attribute type
643// ===========================================================================
644template <>
645void
647{
649 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
650
651 //
652 // Set the default value of the BooleanValue and create an object. The new
653 // default value should stick.
654 //
655 Config::SetDefault("ns3::AttributeObjectTest::TestBoolName", StringValue("true"));
657 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
658
659 bool ok = CheckGetCodePaths(p, "TestBoolName", "true", BooleanValue(true));
660 NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
661
662 std::string expected("Attribute 'TestDeprecated' is deprecated: DEPRECATED test working.\n");
663 // Temporarily redirect std::cerr to a stringstream
664 std::stringstream buffer;
665 std::streambuf* oldBuffer = std::cerr.rdbuf(buffer.rdbuf());
666 // Cause the deprecation warning to be sent to the stringstream
667 Config::SetDefault("ns3::AttributeObjectTest::TestDeprecated", BooleanValue(true));
668
669 // Compare the obtained actual string with the expected string.
670 NS_TEST_ASSERT_MSG_EQ(buffer.str(), expected, "Deprecated attribute not working");
671 // Restore cerr to its original stream buffer
672 std::cerr.rdbuf(oldBuffer);
673
674 //
675 // Set the default value of the BooleanValue the other way and create an object.
676 // The new default value should stick.
677 //
678 Config::SetDefaultFailSafe("ns3::AttributeObjectTest::TestBoolName", StringValue("false"));
679
681 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
682
683 ok = CheckGetCodePaths(p, "TestBoolName", "false", BooleanValue(false));
684 NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not et properly by default value");
685
686 //
687 // Set the BooleanValue Attribute to true via SetAttributeFailSafe path.
688 //
689 ok = p->SetAttributeFailSafe("TestBoolName", StringValue("true"));
690 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() \"TestBoolName\" to true");
691
692 ok = CheckGetCodePaths(p, "TestBoolName", "true", BooleanValue(true));
694 true,
695 "Attribute not set properly by SetAttributeFailSafe() via StringValue");
696
697 //
698 // Set the BooleanValue to false via SetAttributeFailSafe path.
699 //
700 ok = p->SetAttributeFailSafe("TestBoolName", StringValue("false"));
701 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() \"TestBoolName\" to false");
702
703 ok = CheckGetCodePaths(p, "TestBoolName", "false", BooleanValue(false));
705 true,
706 "Attribute not set properly by SetAttributeFailSafe() via StringValue");
707
708 //
709 // Create an object using
710 //
712 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
713
714 //
715 // The previous object-based tests checked access directly. Now check through
716 // setter and getter. The code here looks the same, but the underlying
717 // attribute is declared differently in the object. First make sure we can set
718 // to true.
719 //
720 ok = p->SetAttributeFailSafe("TestBoolA", StringValue("true"));
721 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() a boolean value to true");
722
723 ok = CheckGetCodePaths(p, "TestBoolA", "true", BooleanValue(true));
725 ok,
726 true,
727 "Attribute not set properly by SetAttributeFailSafe() (getter/setter) via StringValue");
728
729 //
730 // Now Set the BooleanValue to false via the setter.
731 //
732 ok = p->SetAttributeFailSafe("TestBoolA", StringValue("false"));
733 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() a boolean value to false");
734
735 ok = CheckGetCodePaths(p, "TestBoolA", "false", BooleanValue(false));
737 ok,
738 true,
739 "Attribute not set properly by SetAttributeFailSafe() (getter/setter) via StringValue");
740}
741
742template <>
743void
745{
747 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
748
749 //
750 // When the object is first created, the Attribute should have the default
751 // value.
752 //
753 bool ok = CheckGetCodePaths(p, "TestInt16", "-2", IntegerValue(-2));
754 NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
755
756 //
757 // Set the Attribute to a negative value through a StringValue.
758 //
759 ok = p->SetAttributeFailSafe("TestInt16", StringValue("-5"));
760 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via StringValue to -5");
761
762 ok = CheckGetCodePaths(p, "TestInt16", "-5", IntegerValue(-5));
764 true,
765 "Attribute not set properly by SetAttributeFailSafe() via StringValue");
766
767 //
768 // Set the Attribute to a positive value through a StringValue.
769 //
770 ok = p->SetAttributeFailSafe("TestInt16", StringValue("+2"));
771 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via StringValue to +2");
772
773 ok = CheckGetCodePaths(p, "TestInt16", "2", IntegerValue(2));
775 true,
776 "Attribute not set properly by SetAttributeFailSafe() via StringValue");
777
778 //
779 // Set the Attribute to the most negative value of the signed 16-bit range.
780 //
781 ok = p->SetAttributeFailSafe("TestInt16", StringValue("-32768"));
782 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via StringValue to -32768");
783
784 ok = CheckGetCodePaths(p, "TestInt16", "-32768", IntegerValue(-32768));
786 ok,
787 true,
788 "Attribute not set properly by SetAttributeFailSafe() (most negative) via StringValue");
789
790 //
791 // Try to set the Attribute past the most negative value of the signed 16-bit
792 // range and make sure the underlying attribute is unchanged.
793 //
794 ok = p->SetAttributeFailSafe("TestInt16", StringValue("-32769"));
796 false,
797 "Unexpectedly could SetAttributeFailSafe() via StringValue to -32769");
798
799 ok = CheckGetCodePaths(p, "TestInt16", "-32768", IntegerValue(-32768));
800 NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
801
802 //
803 // Set the Attribute to the most positive value of the signed 16-bit range.
804 //
805 ok = p->SetAttributeFailSafe("TestInt16", StringValue("32767"));
806 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via StringValue to 32767");
807
808 ok = CheckGetCodePaths(p, "TestInt16", "32767", IntegerValue(32767));
810 ok,
811 true,
812 "Attribute not set properly by SetAttributeFailSafe() (most positive) via StringValue");
813
814 //
815 // Try to set the Attribute past the most positive value of the signed 16-bit
816 // range and make sure the underlying attribute is unchanged.
817 //
818 ok = p->SetAttributeFailSafe("TestInt16", StringValue("32768"));
820 false,
821 "Unexpectedly could SetAttributeFailSafe() via StringValue to 32768");
822
823 ok = CheckGetCodePaths(p, "TestInt16", "32767", IntegerValue(32767));
824 NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
825
826 //
827 // Attributes can have limits other than the intrinsic limits of the
828 // underlying data types. These limits are specified in the Object.
829 //
830 ok = p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue(10));
831 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 10");
832
833 ok = CheckGetCodePaths(p, "TestInt16WithBounds", "10", IntegerValue(10));
835 ok,
836 true,
837 "Attribute not set properly by SetAttributeFailSafe() (positive limit) via StringValue");
838
839 //
840 // Set the Attribute past the positive limit.
841 //
842 ok = p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue(11));
844 false,
845 "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 11");
846
847 ok = CheckGetCodePaths(p, "TestInt16WithBounds", "10", IntegerValue(10));
848 NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
849
850 //
851 // Set the Attribute at the negative limit.
852 //
853 ok = p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue(-5));
854 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -5");
855
856 ok = CheckGetCodePaths(p, "TestInt16WithBounds", "-5", IntegerValue(-5));
858 ok,
859 true,
860 "Attribute not set properly by SetAttributeFailSafe() (negative limit) via StringValue");
861
862 //
863 // Set the Attribute past the negative limit.
864 //
865 ok = p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue(-6));
867 false,
868 "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -6");
869
870 ok = CheckGetCodePaths(p, "TestInt16WithBounds", "-5", IntegerValue(-5));
871 NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
872}
873
874template <>
875void
877{
879 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
880
881 //
882 // When the object is first created, the Attribute should have the default
883 // value.
884 //
885 bool ok = CheckGetCodePaths(p, "TestUint8", "1", UintegerValue(1));
886 NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
887
888 //
889 // Set the Attribute to zero.
890 //
891 ok = p->SetAttributeFailSafe("TestUint8", UintegerValue(0));
892 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to 0");
893
894 ok = CheckGetCodePaths(p, "TestUint8", "0", UintegerValue(0));
896 true,
897 "Attribute not set properly by SetAttributeFailSafe() via StringValue");
898
899 //
900 // Set the Attribute to the most positive value of the unsigned 8-bit range.
901 //
902 ok = p->SetAttributeFailSafe("TestUint8", UintegerValue(255));
903 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to 255");
904
905 ok = CheckGetCodePaths(p, "TestUint8", "255", UintegerValue(255));
907 ok,
908 true,
909 "Attribute not set properly by SetAttributeFailSafe() (positive limit) via UintegerValue");
910
911 //
912 // Try and set the Attribute past the most positive value of the unsigned
913 // 8-bit range.
914 //
915 ok = p->SetAttributeFailSafe("TestUint8", UintegerValue(256));
916 NS_TEST_ASSERT_MSG_EQ(ok, false, "Unexpectedly could SetAttributeFailSafe() to 256");
917
918 ok = CheckGetCodePaths(p, "TestUint8", "255", UintegerValue(255));
919 NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
920
921 //
922 // Set the Attribute to the most positive value of the unsigned 8-bit range
923 // through a StringValue.
924 //
925 ok = p->SetAttributeFailSafe("TestUint8", StringValue("255"));
926 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via StringValue to 255");
927
928 ok = CheckGetCodePaths(p, "TestUint8", "255", UintegerValue(255));
930 true,
931 "Attribute not set properly by SetAttributeFailSafe() via StringValue");
932
933 //
934 // Try and set the Attribute past the most positive value of the unsigned
935 // 8-bit range through a StringValue.
936 //
937 ok = p->SetAttributeFailSafe("TestUint8", StringValue("256"));
939 false,
940 "Unexpectedly could SetAttributeFailSafe() via StringValue to 256");
941
942 ok = CheckGetCodePaths(p, "TestUint8", "255", UintegerValue(255));
943 NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
944
945 //
946 // Try to set the Attribute to a negative StringValue.
947 //
948 ok = p->SetAttributeFailSafe("TestUint8", StringValue("-1"));
950 false,
951 "Unexpectedly could SetAttributeFailSafe() via StringValue to -1");
952}
953
954template <>
955void
957{
959 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
960
961 //
962 // When the object is first created, the Attribute should have the default
963 // value.
964 //
965 bool ok = CheckGetCodePaths(p, "TestFloat", "-1.1", DoubleValue(-1.1F));
966 NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
967
968 //
969 // Set the Attribute.
970 //
971 ok = p->SetAttributeFailSafe("TestFloat", DoubleValue(2.3F));
972 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to 2.3");
973
974 ok = CheckGetCodePaths(p, "TestFloat", "2.3", DoubleValue(2.3F));
976 true,
977 "Attribute not set properly by SetAttributeFailSafe() via DoubleValue");
978}
979
980template <>
981void
983{
985 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
986
987 //
988 // When the object is first created, the Attribute should have the default
989 // value.
990 //
991 bool ok = CheckGetCodePaths(p, "TestEnum", "TestA", EnumValue(AttributeObjectTest::TEST_A));
992 NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
993
994 //
995 // Set the Attribute using the EnumValue type.
996 //
997 ok = p->SetAttributeFailSafe("TestEnum", EnumValue(AttributeObjectTest::TEST_C));
998 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to TEST_C");
999
1000 ok = CheckGetCodePaths(p, "TestEnum", "TestC", EnumValue(AttributeObjectTest::TEST_C));
1002 true,
1003 "Attribute not set properly by SetAttributeFailSafe() via EnumValue");
1004
1005 //
1006 // When the object is first created, the Attribute should have the default
1007 // value.
1008 //
1009 ok = CheckGetCodePaths(p, "TestEnumSetGet", "TestB", EnumValue(AttributeObjectTest::TEST_B));
1010 NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
1011
1012 //
1013 // Set the Attribute using the EnumValue type.
1014 //
1015 ok = p->SetAttributeFailSafe("TestEnumSetGet", EnumValue(AttributeObjectTest::TEST_C));
1016 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to TEST_C");
1017
1018 ok = CheckGetCodePaths(p, "TestEnumSetGet", "TestC", EnumValue(AttributeObjectTest::TEST_C));
1020 true,
1021 "Attribute not set properly by SetAttributeFailSafe() via EnumValue");
1022
1023 //
1024 // Set the Attribute using the StringValue type.
1025 //
1026 ok = p->SetAttributeFailSafe("TestEnum", StringValue("TestB"));
1027 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to TEST_B");
1028
1029 ok = CheckGetCodePaths(p, "TestEnum", "TestB", EnumValue(AttributeObjectTest::TEST_B));
1031 true,
1032 "Attribute not set properly by SetAttributeFailSafe() via StringValue");
1033
1034 //
1035 // Try to set the Attribute to a bogus enum using the StringValue type
1036 // throws a fatal error.
1037 //
1038 // ok = p->SetAttributeFailSafe ("TestEnum", StringValue ("TestD"));
1039 // NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() to TEST_D"); //
1040
1041 ok = CheckGetCodePaths(p, "TestEnum", "TestB", EnumValue(AttributeObjectTest::TEST_B));
1042 NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
1043
1044 //
1045 // Try to set the Attribute to a bogus enum using an integer implicit conversion
1046 // and make sure the underlying value doesn't change.
1047 //
1048 ok = p->SetAttributeFailSafe("TestEnum", EnumValue(5));
1049 NS_TEST_ASSERT_MSG_EQ(ok, false, "Unexpectedly could SetAttributeFailSafe() to 5");
1050
1051 ok = CheckGetCodePaths(p, "TestEnum", "TestB", EnumValue(AttributeObjectTest::TEST_B));
1052 NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
1053}
1054
1055template <>
1056void
1058{
1060 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1061
1062 //
1063 // When the object is first created, the Attribute should have the default
1064 // value.
1065 //
1066 bool ok = CheckGetCodePaths(p,
1067 "TestEnumClass",
1068 "TestD",
1070 NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
1071
1072 //
1073 // Set the Attribute using the EnumValue type.
1074 //
1075 ok = p->SetAttributeFailSafe("TestEnumClass", EnumValue(AttributeObjectTest::Test_ec::TEST_F));
1076 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to TEST_F");
1077
1078 ok = CheckGetCodePaths(p,
1079 "TestEnumClass",
1080 "TestF",
1083 true,
1084 "Attribute not set properly by SetAttributeFailSafe() via EnumValue");
1085
1086 //
1087 // When the object is first created, the Attribute should have the default
1088 // value.
1089 //
1090 ok = CheckGetCodePaths(p,
1091 "TestEnumClassSetGet",
1092 "TestE",
1094 NS_TEST_ASSERT_MSG_EQ(ok, true, "Attribute not set properly by default value");
1095
1096 //
1097 // Set the Attribute using the EnumValue type.
1098 //
1099 ok = p->SetAttributeFailSafe("TestEnumClassSetGet",
1101 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to TEST_F");
1102
1103 ok = CheckGetCodePaths(p,
1104 "TestEnumClassSetGet",
1105 "TestF",
1108 true,
1109 "Attribute not set properly by SetAttributeFailSafe() via EnumValue");
1110
1111 //
1112 // Set the Attribute using the StringValue type.
1113 //
1114 ok = p->SetAttributeFailSafe("TestEnumClass", StringValue("TestE"));
1115 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() to TEST_E");
1116
1117 ok = CheckGetCodePaths(p,
1118 "TestEnumClass",
1119 "TestE",
1122 true,
1123 "Attribute not set properly by SetAttributeFailSafe() via StringValue");
1124
1125 //
1126 // Try to set the Attribute to a bogus enum using the StringValue type
1127 // throws a fatal error.
1128 //
1129 // ok = p->SetAttributeFailSafe ("TestEnumClass", StringValue ("TestG"));
1130 // NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() to TEST_G"); //
1131
1132 ok = CheckGetCodePaths(p,
1133 "TestEnumClass",
1134 "TestE",
1136 NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
1137
1138 //
1139 // Try to set the Attribute to a bogus enum using an integer implicit conversion
1140 // and make sure the underlying value doesn't change.
1141 //
1142 ok = p->SetAttributeFailSafe("TestEnumClass", EnumValue(5));
1143 NS_TEST_ASSERT_MSG_EQ(ok, false, "Unexpectedly could SetAttributeFailSafe() to 5");
1144
1145 ok = CheckGetCodePaths(p,
1146 "TestEnumClass",
1147 "TestE",
1149 NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
1150}
1151
1152template <>
1153void
1155{
1157 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1158
1159 // The test vectors assume ns resolution
1161
1162 //
1163 // Set value
1164 //
1165 bool ok = p->SetAttributeFailSafe("TestTimeWithBounds", TimeValue(Seconds(5)));
1166 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via TimeValue to 5s");
1167
1168 ok = CheckGetCodePaths(p, "TestTimeWithBounds", "+5e+09ns", TimeValue(Seconds(5)));
1170 true,
1171 "Attribute not set properly by SetAttributeFailSafe(5s) via TimeValue");
1172
1173 ok = p->SetAttributeFailSafe("TestTimeWithBounds", StringValue("3s"));
1174 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via TimeValue to 3s");
1175
1176 ok = CheckGetCodePaths(p, "TestTimeWithBounds", "+3e+09ns", TimeValue(Seconds(3)));
1178 true,
1179 "Attribute not set properly by SetAttributeFailSafe(3s) via StringValue");
1180
1181 //
1182 // Attributes can have limits other than the intrinsic limits of the
1183 // underlying data types. These limits are specified in the Object.
1184 //
1185
1186 //
1187 // Set the Attribute at the positive limit
1188 //
1189 ok = p->SetAttributeFailSafe("TestTimeWithBounds", TimeValue(Seconds(10)));
1190 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via TimeValue to 10s");
1191
1192 ok = CheckGetCodePaths(p, "TestTimeWithBounds", "+1e+10ns", TimeValue(Seconds(10)));
1194 ok,
1195 true,
1196 "Attribute not set properly by SetAttributeFailSafe(10s [positive limit]) via StringValue");
1197
1198 //
1199 // Set the Attribute past the positive limit.
1200 //
1201 ok = p->SetAttributeFailSafe("TestTimeWithBounds", TimeValue(Seconds(11)));
1203 false,
1204 "Unexpectedly could SetAttributeFailSafe() via TimeValue to 11s [greater "
1205 "than positive limit]");
1206
1207 ok = CheckGetCodePaths(p, "TestTimeWithBounds", "+1e+10ns", TimeValue(Seconds(10)));
1208 NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
1209
1210 //
1211 // Set the Attribute at the negative limit.
1212 //
1213 ok = p->SetAttributeFailSafe("TestTimeWithBounds", TimeValue(Seconds(-5)));
1214 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via TimeValue to -5s");
1215
1216 ok = CheckGetCodePaths(p, "TestTimeWithBounds", "-5e+09ns", TimeValue(Seconds(-5)));
1218 ok,
1219 true,
1220 "Attribute not set properly by SetAttributeFailSafe(-5s [negative limit]) via StringValue");
1221
1222 //
1223 // Set the Attribute past the negative limit.
1224 //
1225 ok = p->SetAttributeFailSafe("TestTimeWithBounds", TimeValue(Seconds(-6)));
1227 false,
1228 "Unexpectedly could SetAttributeFailSafe() via TimeValue to -6s");
1229
1230 ok = CheckGetCodePaths(p, "TestTimeWithBounds", "-5e+09ns", TimeValue(Seconds(-5)));
1231 NS_TEST_ASSERT_MSG_EQ(ok, true, "Error in SetAttributeFailSafe() but value changes");
1232}
1233
1234/**
1235 * \ingroup attribute-tests
1236 *
1237 * Test the Attributes of type RandomVariableStream.
1238 */
1240{
1241 public:
1242 /**
1243 * Constructor.
1244 * \param description The TestCase description.
1245 */
1246 RandomVariableStreamAttributeTestCase(std::string description);
1247
1251
1252 /**
1253 * Invoke the m_cbValue.
1254 * \param a The value to use on the callback.
1255 */
1257 {
1258 if (!m_cbValue.IsNull())
1259 {
1260 m_cbValue(a);
1261 }
1262 }
1263
1264 private:
1265 void DoRun() override;
1266
1267 /// Callback used in the test.
1269
1270 /**
1271 * Function called when the callback is used.
1272 * \param a The value of the callback.
1273 */
1275 {
1276 m_gotCbValue = a;
1277 }
1278
1279 int16_t m_gotCbValue; //!< Value used to verify that the callback has been invoked.
1280};
1281
1283 std::string description)
1284 : TestCase(description)
1285{
1286}
1287
1288void
1290{
1292 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1293
1294 //
1295 // Try to set a UniformRandomVariable
1296 //
1297 bool ok = p->SetAttributeFailSafe("TestRandom",
1298 StringValue("ns3::UniformRandomVariable[Min=0.|Max=1.]"));
1299 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() a UniformRandomVariable");
1300
1301 //
1302 // Try to set a <snicker> ConstantRandomVariable
1303 //
1304 ok = p->SetAttributeFailSafe("TestRandom",
1305 StringValue("ns3::ConstantRandomVariable[Constant=1.0]"));
1306 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() a ConstantRandomVariable");
1307}
1308
1309/**
1310 * \ingroup attribute-tests
1311 *
1312 * \brief Test case for Object Vector Attributes.
1313 *
1314 * Generic nature is pretty much lost here, so we just break the class out.
1315 */
1317{
1318 public:
1319 /**
1320 * Constructor.
1321 * \param description The TestCase description.
1322 */
1323 ObjectVectorAttributeTestCase(std::string description);
1324
1326 {
1327 }
1328
1329 private:
1330 void DoRun() override;
1331};
1332
1334 : TestCase(description)
1335{
1336}
1337
1338void
1340{
1341 ObjectVectorValue vector;
1342
1344 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1345
1346 //
1347 // When the object is first created, the Attribute should have no items in
1348 // the vector.
1349 //
1350 p->GetAttribute("TestVector1", vector);
1351 NS_TEST_ASSERT_MSG_EQ(vector.GetN(),
1352 0,
1353 "Initial count of ObjectVectorValue \"TestVector1\" should be zero");
1354
1355 //
1356 // Adding to the attribute shouldn't affect the value we already have.
1357 //
1358 p->AddToVector1();
1360 vector.GetN(),
1361 0,
1362 "Initial count of ObjectVectorValue \"TestVector1\" should still be zero");
1363
1364 //
1365 // Getting the attribute again should update the value.
1366 //
1367 p->GetAttribute("TestVector1", vector);
1368 NS_TEST_ASSERT_MSG_EQ(vector.GetN(),
1369 1,
1370 "ObjectVectorValue \"TestVector1\" should be incremented");
1371
1372 //
1373 // Get the Object pointer from the value.
1374 //
1375 Ptr<Object> a = vector.Get(0);
1376 NS_TEST_ASSERT_MSG_NE(a, nullptr, "Ptr<Object> from VectorValue \"TestVector1\" is zero");
1377
1378 //
1379 // Adding to the attribute shouldn't affect the value we already have.
1380 //
1381 p->AddToVector1();
1382 NS_TEST_ASSERT_MSG_EQ(vector.GetN(),
1383 1,
1384 "Count of ObjectVectorValue \"TestVector1\" should still be one");
1385
1386 //
1387 // Getting the attribute again should update the value.
1388 //
1389 p->GetAttribute("TestVector1", vector);
1390 NS_TEST_ASSERT_MSG_EQ(vector.GetN(),
1391 2,
1392 "ObjectVectorValue \"TestVector1\" should be incremented");
1393}
1394
1395/**
1396 * \ingroup attribute-tests
1397 *
1398 * \brief Test case for Object Map Attributes.
1399 */
1401{
1402 public:
1403 /**
1404 * Constructor.
1405 * \param description The TestCase description.
1406 */
1407 ObjectMapAttributeTestCase(std::string description);
1408
1410 {
1411 }
1412
1413 private:
1414 void DoRun() override;
1415};
1416
1418 : TestCase(description)
1419{
1420}
1421
1422void
1424{
1425 ObjectMapValue map;
1426
1428 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1429
1430 //
1431 // When the object is first created, the Attribute should have no items in
1432 // the vector.
1433 //
1434 p->GetAttribute("TestMap1", map);
1436 0,
1437 "Initial count of ObjectVectorValue \"TestMap1\" should be zero");
1438
1439 //
1440 // Adding to the attribute shouldn't affect the value we already have.
1441 //
1442 p->AddToMap1(1);
1444 0,
1445 "Initial count of ObjectVectorValue \"TestMap1\" should still be zero");
1446
1447 //
1448 // Getting the attribute again should update the value.
1449 //
1450 p->GetAttribute("TestMap1", map);
1451 NS_TEST_ASSERT_MSG_EQ(map.GetN(), 1, "ObjectVectorValue \"TestMap1\" should be incremented");
1452
1453 //
1454 // Get the Object pointer from the value.
1455 //
1456 Ptr<Object> a = map.Get(1);
1457 NS_TEST_ASSERT_MSG_NE(a, nullptr, "Ptr<Object> from VectorValue \"TestMap1\" is zero");
1458
1459 //
1460 // Adding to the attribute shouldn't affect the value we already have.
1461 //
1462 p->AddToMap1(2);
1464 1,
1465 "Count of ObjectVectorValue \"TestMap1\" should still be one");
1466
1467 //
1468 // Getting the attribute again should update the value.
1469 //
1470 p->GetAttribute("TestMap1", map);
1471 NS_TEST_ASSERT_MSG_EQ(map.GetN(), 2, "ObjectVectorValue \"TestMap1\" should be incremented");
1472
1473 //
1474 // Test that ObjectMapValue is iterable with an underlying unordered_map
1475 //
1476 ObjectMapValue unorderedMap;
1477 // Add objects at 1, 2, 3, 4
1478 p->AddToUnorderedMap(4);
1479 p->AddToUnorderedMap(2);
1480 p->AddToUnorderedMap(1);
1481 p->AddToUnorderedMap(3);
1482 // Remove object 2
1483 p->RemoveFromUnorderedMap(2);
1484 p->GetAttribute("TestUnorderedMap", unorderedMap);
1485 NS_TEST_ASSERT_MSG_EQ(unorderedMap.GetN(),
1486 3,
1487 "ObjectMapValue \"TestUnorderedMap\" should have three values");
1488 Ptr<Object> o1 = unorderedMap.Get(1);
1490 nullptr,
1491 "ObjectMapValue \"TestUnorderedMap\" should have value with key 1");
1492 Ptr<Object> o2 = unorderedMap.Get(2);
1494 nullptr,
1495 "ObjectMapValue \"TestUnorderedMap\" should not have value with key 2");
1496 auto it = unorderedMap.Begin();
1497 NS_TEST_ASSERT_MSG_EQ(it->first,
1498 1,
1499 "ObjectMapValue \"TestUnorderedMap\" should have a value with key 1");
1500 it++;
1501 NS_TEST_ASSERT_MSG_EQ(it->first,
1502 3,
1503 "ObjectMapValue \"TestUnorderedMap\" should have a value with key 3");
1504 it++;
1505 NS_TEST_ASSERT_MSG_EQ(it->first,
1506 4,
1507 "ObjectMapValue \"TestUnorderedMap\" should have a value with key 4");
1508}
1509
1510/**
1511 * \ingroup attribute-tests
1512 *
1513 * \brief Trace sources with value semantics can be used like Attributes,
1514 * make sure we can use them that way.
1515 */
1517{
1518 public:
1519 /**
1520 * Constructor.
1521 * \param description The TestCase description.
1522 */
1523 IntegerTraceSourceAttributeTestCase(std::string description);
1524
1528
1529 private:
1530 void DoRun() override;
1531};
1532
1534 : TestCase(description)
1535{
1536}
1537
1538void
1540{
1541 IntegerValue iv;
1542
1544 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1545
1546 //
1547 // When the object is first created, the Attribute should have the default
1548 // value.
1549 //
1550 p->GetAttribute("IntegerTraceSource1", iv);
1551 NS_TEST_ASSERT_MSG_EQ(iv.Get(), -2, "Attribute not set properly by default value");
1552
1553 //
1554 // Set the Attribute to a positive value through an IntegerValue.
1555 //
1556 bool ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(5));
1557 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 5");
1558
1559 p->GetAttribute("IntegerTraceSource1", iv);
1561 5,
1562 "Attribute not set properly by SetAttributeFailSafe() via IntegerValue");
1563
1564 //
1565 // Limits should work.
1566 //
1567 ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(127));
1568 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 127");
1569
1570 ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(128));
1572 false,
1573 "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 128");
1574
1575 ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(-128));
1576 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -128");
1577
1578 ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(-129));
1580 false,
1581 "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -129");
1582
1583 //
1584 // When the object is first created, the Attribute should have the default
1585 // value.
1586 //
1587 p->GetAttribute("IntegerTraceSource2", iv);
1588 NS_TEST_ASSERT_MSG_EQ(iv.Get(), -2, "Attribute not set properly by default value");
1589
1590 //
1591 // Set the Attribute to a positive value through an IntegerValue.
1592 //
1593 ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue(5));
1594 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 5");
1595
1596 p->GetAttribute("IntegerTraceSource2", iv);
1598 5,
1599 "Attribute not set properly by SetAttributeFailSafe() via IntegerValue");
1600
1601 //
1602 // Limits should work.
1603 //
1604 ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue(127));
1605 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 127");
1606
1607 ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue(128));
1609 false,
1610 "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 128");
1611
1612 ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue(-128));
1613 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -128");
1614
1615 ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue(-129));
1617 false,
1618 "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -129");
1619}
1620
1621/**
1622 * \ingroup attribute-tests
1623 *
1624 * \brief Trace sources used like Attributes must also work as trace sources,
1625 * make sure we can use them that way.
1626 */
1628{
1629 public:
1630 /**
1631 * Constructor.
1632 * \param description The TestCase description.
1633 */
1634 IntegerTraceSourceTestCase(std::string description);
1635
1637 {
1638 }
1639
1640 private:
1641 void DoRun() override;
1642
1643 /**
1644 * Notify the call of source 1.
1645 * \param old First value.
1646 * \param n Second value.
1647 */
1648 void NotifySource1(int8_t old [[maybe_unused]], int8_t n)
1649 {
1650 m_got1 = n;
1651 }
1652
1653 int64_t m_got1; //!< Value used to verify that source 1 was called.
1654};
1655
1657 : TestCase(description)
1658{
1659}
1660
1661void
1663{
1665 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1666
1667 //
1668 // Check to make sure changing an Attribute value triggers a trace callback
1669 // that sets a member variable.
1670 //
1671 m_got1 = 1234;
1672
1673 bool ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(-1));
1674 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -1");
1675
1676 //
1677 // Source1 is declared as a TraceSourceAccessor to m_intSrc1. This m_intSrc1
1678 // is also declared as an Integer Attribute. We just checked to make sure we
1679 // could set it using an IntegerValue through its IntegerTraceSource1 "persona."
1680 // We should also be able to hook a trace source to the underlying variable.
1681 //
1682 ok = p->TraceConnectWithoutContext(
1683 "Source1",
1686 true,
1687 "Could not TraceConnectWithoutContext() \"Source1\" to NodifySource1()");
1688
1689 //
1690 // When we set the IntegerValue that now underlies both the Integer Attribute
1691 // and the trace source, the trace should fire and call NotifySource1 which
1692 // will set m_got1 to the new value.
1693 //
1694 ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(0));
1695 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 0");
1696
1698 0,
1699 "Hitting a TracedValue does not cause trace callback to be called");
1700
1701 //
1702 // Now disconnect from the trace source and ensure that the trace callback
1703 // is not called if the trace source is hit.
1704 //
1705 ok = p->TraceDisconnectWithoutContext(
1706 "Source1",
1709 true,
1710 "Could not TraceConnectWithoutContext() \"Source1\" to NodifySource1()");
1711
1712 ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue(1));
1713 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 1");
1714
1716 0,
1717 "Hitting a TracedValue after disconnect still causes callback");
1718}
1719
1720/**
1721 * \ingroup attribute-tests
1722 *
1723 * \brief Trace sources used like Attributes must also work as trace sources,
1724 * make sure we can use them that way.
1725 */
1727{
1728 public:
1729 /**
1730 * Constructor.
1731 * \param description The TestCase description.
1732 */
1733 TracedCallbackTestCase(std::string description);
1734
1736 {
1737 }
1738
1739 private:
1740 void DoRun() override;
1741
1742 /**
1743 * Notify the call of source 2.
1744 * \param a First value.
1745 * \param b Second value.
1746 * \param c Third value.
1747 */
1748 void NotifySource2(double a, int b [[maybe_unused]], float c [[maybe_unused]])
1749 {
1750 m_got2 = a;
1751 }
1752
1753 double m_got2; //!< Value used to verify that source 2 was called.
1754};
1755
1757 : TestCase(description)
1758{
1759}
1760
1761void
1763{
1765 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1766
1767 //
1768 // Initialize the
1769 //
1770 m_got2 = 4.3;
1771
1772 //
1773 // Invoke the callback that lies at the heart of this test. We have a
1774 // method InvokeCb() that just executes m_cb(). The variable m_cb is
1775 // declared as a TracedCallback<double, int, float>. This kind of beast
1776 // is like a callback but can call a list of targets. This list should
1777 // be empty so nothing should happen now. Specifically, m_got2 shouldn't
1778 // have changed.
1779 //
1780 p->InvokeCb(1.0, -5, 0.0);
1782 m_got2,
1783 4.3,
1784 "Invoking a newly created TracedCallback results in an unexpected callback");
1785
1786 //
1787 // Now, wire the TracedCallback up to a trace sink. This sink will just set
1788 // m_got2 to the first argument.
1789 //
1790 bool ok =
1791 p->TraceConnectWithoutContext("Source2",
1793 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not TraceConnectWithoutContext() to NotifySource2");
1794
1795 //
1796 // Now if we invoke the callback, the trace source should fire and m_got2
1797 // should be set in the trace sink.
1798 //
1799 p->InvokeCb(1.0, -5, 0.0);
1800 NS_TEST_ASSERT_MSG_EQ(m_got2, 1.0, "Invoking TracedCallback does not result in trace callback");
1801
1802 //
1803 // Now, disconnect the trace sink and see what happens when we invoke the
1804 // callback again. Of course, the trace should not happen and m_got2
1805 // should remain unchanged.
1806 //
1807 ok = p->TraceDisconnectWithoutContext(
1808 "Source2",
1810 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not TraceDisconnectWithoutContext() from NotifySource2");
1811
1812 p->InvokeCb(-1.0, -5, 0.0);
1814 m_got2,
1815 1.0,
1816 "Invoking disconnected TracedCallback unexpectedly results in trace callback");
1817}
1818
1819/**
1820 * \ingroup attribute-tests
1821 *
1822 * \brief Smart pointers (Ptr) are central to our architecture, so they
1823 * must work as attributes.
1824 */
1826{
1827 public:
1828 /**
1829 * Constructor.
1830 * \param description The TestCase description.
1831 */
1832 PointerAttributeTestCase(std::string description);
1833
1835 {
1836 }
1837
1838 private:
1839 void DoRun() override;
1840
1841 /**
1842 * Notify the call of source 2.
1843 * \param a First value.
1844 * \param b Second value.
1845 * \param c Third value.
1846 */
1847 void NotifySource2(double a, int b [[maybe_unused]], float c [[maybe_unused]])
1848 {
1849 m_got2 = a;
1850 }
1851
1852 double m_got2; //!< Value used to verify that source 2 was called.
1853};
1854
1856 : TestCase(description)
1857{
1858}
1859
1860void
1862{
1864 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
1865
1866 //
1867 // We have declared a PointerValue Attribute named "Pointer" with a pointer
1868 // checker of type Derived. This means that we should be able to pull out
1869 // a Ptr<Derived> with the initial value (which is 0).
1870 //
1871 PointerValue ptr;
1872 p->GetAttribute("Pointer", ptr);
1873 Ptr<Derived> derived = ptr.Get<Derived>();
1875 (bool)derived,
1876 false,
1877 "Unexpectedly found non-null pointer in newly initialized PointerValue Attribute");
1878
1879 //
1880 // Now, lets create an Object of type Derived and set the local Ptr to point
1881 // to that object. We can then set the PointerValue Attribute to that Ptr.
1882 //
1883 derived = Create<Derived>();
1884 bool ok = p->SetAttributeFailSafe("Pointer", PointerValue(derived));
1886 true,
1887 "Could not SetAttributeFailSafe() a PointerValue of the correct type");
1888
1889 //
1890 // Pull the value back out of the Attribute and make sure it points to the
1891 // correct object.
1892 //
1893 p->GetAttribute("Pointer", ptr);
1894 Ptr<Derived> stored = ptr.Get<Derived>();
1895 NS_TEST_ASSERT_MSG_EQ(stored,
1896 derived,
1897 "Retrieved Attribute does not match stored PointerValue");
1898
1899 //
1900 // We should be able to use the Attribute Get() just like GetObject<type>,
1901 // So see if we can get a Ptr<Object> out of the Ptr<Derived> we stored.
1902 // This should be a pointer to the same physical memory since its the
1903 // same object.
1904 //
1905 p->GetAttribute("Pointer", ptr);
1906 Ptr<Object> storedBase = ptr.Get<Object>();
1907 NS_TEST_ASSERT_MSG_EQ(storedBase,
1908 stored,
1909 "Retrieved Ptr<Object> does not match stored Ptr<Derived>");
1910
1911 //
1912 // If we try to Get() something that is unrelated to what we stored, we should
1913 // retrieve a 0.
1914 //
1915 p->GetAttribute("Pointer", ptr);
1917 NS_TEST_ASSERT_MSG_EQ((bool)x,
1918 false,
1919 "Unexpectedly retrieved unrelated Ptr<type> from stored Ptr<Derived>");
1920
1921 //
1922 // Test whether the initialized pointers from two different objects
1923 // point to different Derived objects
1924 //
1925 p->GetAttribute("PointerInitialized", ptr);
1926 Ptr<Derived> storedPtr = ptr.Get<Derived>();
1928 PointerValue ptr2;
1929 p2->GetAttribute("PointerInitialized", ptr2);
1930 Ptr<Derived> storedPtr2 = ptr2.Get<Derived>();
1931 NS_TEST_ASSERT_MSG_NE(storedPtr,
1932 storedPtr2,
1933 "ptr and ptr2 both have PointerInitialized pointing to the same object");
1934 PointerValue ptr3;
1935 p2->GetAttribute("PointerInitialized", ptr3);
1936 Ptr<Derived> storedPtr3 = ptr3.Get<Derived>();
1937 NS_TEST_ASSERT_MSG_NE(storedPtr,
1938 storedPtr3,
1939 "ptr and ptr3 both have PointerInitialized pointing to the same object");
1940
1941 //
1942 // Test whether object factory creates the objects properly
1943 //
1944 ObjectFactory factory;
1945 factory.SetTypeId("ns3::AttributeObjectTest");
1946 factory.Set("PointerInitialized", StringValue("ns3::Derived"));
1948 NS_TEST_ASSERT_MSG_NE(aotPtr, nullptr, "Unable to factory.Create() a AttributeObjectTest");
1950 NS_TEST_ASSERT_MSG_NE(aotPtr2, nullptr, "Unable to factory.Create() a AttributeObjectTest");
1951 NS_TEST_ASSERT_MSG_NE(aotPtr, aotPtr2, "factory object not creating unique objects");
1952 PointerValue ptr4;
1953 aotPtr->GetAttribute("PointerInitialized", ptr4);
1954 Ptr<Derived> storedPtr4 = ptr4.Get<Derived>();
1955 PointerValue ptr5;
1956 aotPtr2->GetAttribute("PointerInitialized", ptr5);
1957 Ptr<Derived> storedPtr5 = ptr5.Get<Derived>();
1958 NS_TEST_ASSERT_MSG_NE(storedPtr4,
1959 storedPtr5,
1960 "aotPtr and aotPtr2 are unique, but their Derived member is not");
1961}
1962
1963/**
1964 * \ingroup attribute-tests
1965 *
1966 * \brief Test the Attributes of type CallbackValue.
1967 */
1969{
1970 public:
1971 /**
1972 * Constructor.
1973 * \param description The TestCase description.
1974 */
1975 CallbackValueTestCase(std::string description);
1976
1978 {
1979 }
1980
1981 /**
1982 * Function to invoke the callback.
1983 * \param a The value.
1984 */
1986 {
1987 if (!m_cbValue.IsNull())
1988 {
1989 m_cbValue(a);
1990 }
1991 }
1992
1993 private:
1994 void DoRun() override;
1995
1997
1998 /**
1999 * Function invoked when the callback is fired.
2000 * \param a The value.
2001 */
2003 {
2004 m_gotCbValue = a;
2005 }
2006
2007 int16_t m_gotCbValue; //!< Value used to verify that source 2 was called.
2008};
2009
2011 : TestCase(description)
2012{
2013}
2014
2015void
2017{
2019 NS_TEST_ASSERT_MSG_NE(p, nullptr, "Unable to CreateObject");
2020
2021 //
2022 // The member variable m_cbValue is declared as a Callback<void, int8_t>. The
2023 // Attribute named "Callback" also points to m_cbValue and allows us to set the
2024 // callback using that Attribute.
2025 //
2026 // NotifyCallbackValue is going to be the target of the callback and will just set
2027 // m_gotCbValue to its single parameter. This will be the parameter from the
2028 // callback invocation. The method InvokeCbValue() just invokes the m_cbValue
2029 // callback if it is non-null.
2030 //
2031 m_gotCbValue = 1;
2032
2033 //
2034 // If we invoke the callback (which has not been set) nothing should happen.
2035 // Further, nothing should happen when we initialize the callback (it shouldn't
2036 // accidentally fire).
2037 //
2038 p->InvokeCbValue(2);
2040
2041 NS_TEST_ASSERT_MSG_EQ(m_gotCbValue, 1, "Callback unexpectedly fired");
2042
2043 bool ok = p->SetAttributeFailSafe("Callback", cbValue);
2044 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() a CallbackValue");
2045
2046 //
2047 // Now that the callback has been set, invoking it should set m_gotCbValue.
2048 //
2049 p->InvokeCbValue(2);
2050 NS_TEST_ASSERT_MSG_EQ(m_gotCbValue, 2, "Callback Attribute set by CallbackValue did not fire");
2051
2052 ok = p->SetAttributeFailSafe("Callback", CallbackValue(MakeNullCallback<void, int8_t>()));
2053 NS_TEST_ASSERT_MSG_EQ(ok, true, "Could not SetAttributeFailSafe() a null CallbackValue");
2054
2055 //
2056 // If the callback has been set to a null callback, it should no longer fire.
2057 //
2058 p->InvokeCbValue(3);
2060 2,
2061 "Callback Attribute set to null callback unexpectedly fired");
2062}
2063
2064/**
2065 * \ingroup attribute-tests
2066 *
2067 * \brief The attributes Test Suite.
2068 */
2070{
2071 public:
2073};
2074
2076 : TestSuite("attributes", Type::UNIT)
2077{
2078 AddTestCase(new AttributeTestCase<BooleanValue>("Check Attributes of type BooleanValue"),
2079 TestCase::Duration::QUICK);
2080 AddTestCase(new AttributeTestCase<IntegerValue>("Check Attributes of type IntegerValue"),
2081 TestCase::Duration::QUICK);
2082 AddTestCase(new AttributeTestCase<UintegerValue>("Check Attributes of type UintegerValue"),
2083 TestCase::Duration::QUICK);
2084 AddTestCase(new AttributeTestCase<DoubleValue>("Check Attributes of type DoubleValue"),
2085 TestCase::Duration::QUICK);
2087 "Check Attributes of type EnumValue"),
2088 TestCase::Duration::QUICK);
2090 "Check Attributes of type EnumValue (wrapping an enum class)"),
2091 TestCase::Duration::QUICK);
2092 AddTestCase(new AttributeTestCase<TimeValue>("Check Attributes of type TimeValue"),
2093 TestCase::Duration::QUICK);
2095 new RandomVariableStreamAttributeTestCase("Check Attributes of type RandomVariableStream"),
2096 TestCase::Duration::QUICK);
2097 AddTestCase(new ObjectVectorAttributeTestCase("Check Attributes of type ObjectVectorValue"),
2098 TestCase::Duration::QUICK);
2099 AddTestCase(new ObjectMapAttributeTestCase("Check Attributes of type ObjectMapValue"),
2100 TestCase::Duration::QUICK);
2101 AddTestCase(new PointerAttributeTestCase("Check Attributes of type PointerValue"),
2102 TestCase::Duration::QUICK);
2103 AddTestCase(new CallbackValueTestCase("Check Attributes of type CallbackValue"),
2104 TestCase::Duration::QUICK);
2106 "Ensure TracedValue<uint8_t> can be set like IntegerValue"),
2107 TestCase::Duration::QUICK);
2109 new IntegerTraceSourceTestCase("Ensure TracedValue<uint8_t> also works as trace source"),
2110 TestCase::Duration::QUICK);
2112 "Ensure TracedCallback<double, int, float> works as trace source"),
2113 TestCase::Duration::QUICK);
2114}
2115
2116static AttributesTestSuite g_attributesTestSuite; //!< Static variable for test initialization
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.
Ptr< Derived > DoGetVector(std::size_t i) const
Get the i-th item 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.
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(* NumericTracedCallback)(double, int, float)
Traced callbacks for (double, int, float) values.
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.
IntegerTraceSourceTestCase(std::string description)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
void NotifySource1(int8_t old, int8_t n)
Notify the call of source 1.
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.
double m_got2
Value used to verify that source 2 was called.
PointerAttributeTestCase(std::string description)
Constructor.
void NotifySource2(double a, int b, float c)
Notify the call of source 2.
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...
TracedCallbackTestCase(std::string description)
Constructor.
void NotifySource2(double a, int b, float c)
Notify the call of source 2.
double m_got2
Value used to verify that source 2 was called.
void DoRun() override
Implementation to actually run this TestCase.
Callback template class.
Definition callback.h:422
bool IsNull() const
Check for null implementation.
Definition callback.h:555
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
Hold variables of type enum.
Definition enum.h:52
Hold a signed integer type.
Definition integer.h:34
int64_t Get() const
Definition integer.cc:26
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:78
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
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.
AttributeValue implementation for Pointer.
Ptr< T > Get() const
Definition pointer.h:223
Smart pointer class similar to boost::intrusive_ptr.
Hold variables of type string.
Definition string.h:45
std::string Get() const
Definition string.cc:20
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
@ NS
nanosecond
Definition nstime.h:108
static void SetResolution(Unit resolution)
Definition time.cc:202
Forward calls to a chain of Callback.
Trace classes with value semantics.
a unique identifier for an interface.
Definition type-id.h:48
TypeId AddConstructor()
Record in this TypeId the fact that the default constructor is accessible.
Definition type-id.h:670
@ DEPRECATED
Attribute or trace source is deprecated; user is warned.
Definition type-id.h:64
Hold an unsigned integer type.
Definition uinteger.h:34
Test class for TracedValue callbacks attributes.
void(* TracedValueCallback)(const ValueClassTest oldValue, const ValueClassTest newValue)
TracedValue callback signature for ValueClassTest.
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:248
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:269
#define ATTRIBUTE_HELPER_CPP(type)
Define the attribute value, accessor and checkers for class type
#define ATTRIBUTE_HELPER_HEADER(type)
Declare the attribute value, accessor and checkers for class type
Callback< R, Args... > MakeNullCallback()
Definition callback.h:727
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
bool SetDefaultFailSafe(std::string fullName, const AttributeValue &value)
Definition config.cc:893
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#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:134
#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:554
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
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:113
Ptr< const AttributeChecker > MakeIntegerChecker()
Definition integer.h:99
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Definition integer.h:35
Ptr< const AttributeAccessor > MakeCallbackAccessor(T1 a1)
Definition callback.h:818
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
bool operator!=(Callback< R, Args... > a, Callback< R, Args... > b)
Inequality test.
Definition callback.h:658
Ptr< const AttributeAccessor > MakeValueClassTestAccessor(T1 a1)
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition nstime.h:1396
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:684
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
Ptr< const AttributeChecker > MakeValueClassTestChecker()
Ptr< const AttributeChecker > MakeObjectVectorChecker()
ObjectPtrContainerValue ObjectMapValue
ObjectMapValue is an alias for ObjectPtrContainerValue.
Definition object-map.h:29
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
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:179
std::istream & operator>>(std::istream &is, Angles &a)
Definition angles.cc:172
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Ptr< const AttributeChecker > MakeCallbackChecker()
Definition callback.cc:77
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition boolean.h:70
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition double.h:32
Ptr< const AttributeAccessor > MakeObjectMapAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition object-map.h:65
Ptr< const AttributeChecker > MakeObjectMapChecker()
Definition object-map.h:110
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition enum.h:221
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1416