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 * 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
37using namespace ns3;
38
39namespace ns3
40{
41
42/**
43 * \file
44 * \ingroup attribute-tests
45 * Attribute test suite
46 */
47
48/**
49 * \ingroup core-tests
50 * \defgroup attribute-tests Attribute tests
51 */
52
53/**
54 * \ingroup attribute-tests
55 *
56 * Test class for TracedValue callbacks attributes.
57 * \see attribute_ValueClassTest
58 */
60{
61 public:
63 {
64 }
65
66 /**
67 * TracedValue callback signature for ValueClassTest
68 *
69 * \param [in] oldValue original value of the traced variable
70 * \param [in] newValue new value of the traced variable
71 */
72 typedef void (*TracedValueCallback)(const ValueClassTest oldValue,
73 const ValueClassTest newValue);
74};
75
76/**
77 * Operator not equal.
78 * \param a The left operand.
79 * \param b The right operand.
80 * \return always true.
81 */
82bool
83operator!=(const ValueClassTest& a [[maybe_unused]], const ValueClassTest& b [[maybe_unused]])
84{
85 return true;
86}
87
88/**
89 * \brief Stream insertion operator.
90 *
91 * \param [in] os The reference to the output stream.
92 * \param [in] v The ValueClassTest object.
93 * \returns The reference to the output stream.
94 */
95std::ostream&
96operator<<(std::ostream& os, ValueClassTest v [[maybe_unused]])
97{
98 return os;
99}
100
101/**
102 * \brief Stream extraction operator.
103 *
104 * \param [in] is The reference to the input stream.
105 * \param [out] v The ValueClassTest object.
106 * \returns The reference to the input stream.
107 */
108std::istream&
109operator>>(std::istream& is, ValueClassTest& v [[maybe_unused]])
110{
111 return is;
112}
113
116
117} // namespace ns3
118
119/**
120 * \ingroup attribute-tests
121 *
122 * Simple class derived from ns3::Object, used to check attribute constructors.
123 */
124class Derived : public Object
125{
126 public:
127 /**
128 * \brief Get the type ID.
129 * \return The object TypeId.
130 */
132 {
133 static TypeId tid = TypeId("ns3::Derived").AddConstructor<Derived>().SetParent<Object>();
134 return tid;
135 }
136
138 {
139 }
140};
141
143
144/**
145 * \ingroup attribute-tests
146 *
147 * Class used to check attributes.
148 */
150{
151 public:
152 /// Test enumerator.
154 {
155 TEST_A, //!< Test value A.
156 TEST_B, //!< Test value B.
157 TEST_C //!< Test value C.
158 };
159
160 /// Test enumerator.
161 enum class Test_ec
162 {
163 TEST_D, //!< Test value D.
164 TEST_E, //!< Test value E.
165 TEST_F //!< Test value F.
166 };
167
168 /**
169 * \brief Get the type ID.
170 * \return The object TypeId.
171 */
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",
214 MakeEnumAccessor<Test_e>(&AttributeObjectTest::m_enum),
215 MakeEnumChecker(TEST_A, "TestA", TEST_B, "TestB", TEST_C, "TestC"))
216 .AddAttribute("TestEnumSetGet",
217 "help text",
219 MakeEnumAccessor<Test_e>(&AttributeObjectTest::DoSetEnum,
221 MakeEnumChecker(TEST_A, "TestA", TEST_B, "TestB", TEST_C, "TestC"))
222 .AddAttribute("TestEnumClass",
223 "help text",
225 MakeEnumAccessor<Test_ec>(&AttributeObjectTest::m_enumclass),
227 "TestD",
229 "TestE",
231 "TestF"))
232 .AddAttribute("TestEnumClassSetGet",
233 "help text",
235 MakeEnumAccessor<Test_ec>(&AttributeObjectTest::DoSetEnumClass,
238 "TestD",
240 "TestE",
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",
268 MakeObjectMapChecker<Derived>())
269 .AddAttribute("TestUnorderedMap",
270 "help text",
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",
304 MakeEnumAccessor<TracedValue<Test_e>>(&AttributeObjectTest::m_enumSrc),
305 MakeEnumChecker(TEST_A, "TestA"))
306 .AddAttribute("ValueClassSource",
307 "help text",
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",
343 .AddAttribute("TestTimeWithBounds",
344 "help text",
345 TimeValue(Seconds(-2)),
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
367 /// Add an object to the first vector.
369 {
370 m_vector1.push_back(CreateObject<Derived>());
371 }
372
373 /// Add an object to the second vector.
375 {
376 m_vector2.push_back(CreateObject<Derived>());
377 }
378
379 /**
380 * Adds an object to the first map.
381 * \param i The index to assign to the object.
382 */
384 {
385 m_map1.insert(std::pair<uint32_t, Ptr<Derived>>(i, CreateObject<Derived>()));
386 }
387
388 /**
389 * Adds an object to the unordered map.
390 * \param i The index to assign to the object.
391 */
392 void AddToUnorderedMap(uint64_t i)
393 {
394 m_unorderedMap.insert({i, CreateObject<Derived>()});
395 }
396
397 /**
398 * Remove an object from the first map.
399 * \param i The index to assign to the object.
400 */
401 void RemoveFromUnorderedMap(uint64_t i)
402 {
403 m_unorderedMap.erase(i);
404 }
405
406 /**
407 * Invoke the m_cb callback.
408 * \param a The first argument of the callback.
409 * \param b The second argument of the callback.
410 * \param c The third argument of the callback.
411 */
412 void InvokeCb(double a, int b, float c)
413 {
414 m_cb(a, b, c);
415 }
416
417 /**
418 * Invoke the m_cbValue callback.
419 * \param a The argument of the callback.
420 */
422 {
423 if (!m_cbValue.IsNull())
424 {
425 m_cbValue(a);
426 }
427 }
428
429 private:
430 /**
431 * Set the m_boolTestA value.
432 * \param v The value to set.
433 */
434 void DoSetTestA(bool v)
435 {
436 m_boolTestA = v;
437 }
438
439 /**
440 * Get the m_boolTestA value.
441 * \return the value of m_boolTestA.
442 */
443 bool DoGetTestA() const
444 {
445 return m_boolTestA;
446 }
447
448 /**
449 * Get the m_int16SetGet value.
450 * \return the value of m_int16SetGet.
451 */
452 int16_t DoGetInt16() const
453 {
454 return m_int16SetGet;
455 }
456
457 /**
458 * Set the m_int16SetGet value.
459 * \param v The value to set.
460 */
461 void DoSetInt16(int16_t v)
462 {
463 m_int16SetGet = v;
464 }
465
466 /**
467 * Get the length of m_vector2.
468 * \return the vector size.
469 */
470 std::size_t DoGetVectorN() const
471 {
472 return m_vector2.size();
473 }
474
475 /**
476 * Get the i-th item of m_vector2.
477 * \param i The index of the element to get.
478 * \return i-th item of m_vector2.
479 */
480 Ptr<Derived> DoGetVector(std::size_t i) const
481 {
482 return m_vector2[i];
483 }
484
485 /**
486 * Set the m_intSrc2 value.
487 * \param v The value to set.
488 * \return true.
489 */
491 {
492 m_intSrc2 = v;
493 return true;
494 }
495
496 /**
497 * Get the m_intSrc2 value.
498 * \return the value of m_intSrc2.
499 */
501 {
502 return m_intSrc2;
503 }
504
505 /**
506 * Set the m_enumSetGet value.
507 * \param v The value to set.
508 * \return true.
509 */
511 {
512 m_enumSetGet = v;
513 return true;
514 }
515
516 /**
517 * Get the m_enumSetGet value.
518 * \return the value of m_enumSetGet.
519 */
521 {
522 return m_enumSetGet;
523 }
524
525 /**
526 * Set the m_enumClassSetGet value.
527 * \param v The value to set.
528 * \return true.
529 */
531 {
533 return true;
534 }
535
536 /**
537 * Get the m_enumClassSetGet value.
538 * \return the value of m_enumSetGet.
539 */
541 {
542 return m_enumClassSetGet;
543 }
544
545 bool m_boolTestA; //!< Boolean test A.
546 bool m_boolTest; //!< Boolean test.
547 bool m_boolTestDeprecated; //!< Boolean test deprecated.
548 int16_t m_int16; //!< 16-bit integer.
549 int16_t m_int16WithBounds; //!< 16-bit integer with bounds.
550 int16_t m_int16SetGet; //!< 16-bit integer set-get.
551 uint8_t m_uint8; //!< 8-bit integer.
552 float m_float; //!< float.
553 Test_e m_enum; //!< Enum.
554 Test_e m_enumSetGet; //!< Enum set-get.
555 Test_ec m_enumclass; //!< Enum class.
556 Test_ec m_enumClassSetGet; //!< Enum class set-get.
557 Ptr<RandomVariableStream> m_random; //!< Random number generator.
558 std::vector<Ptr<Derived>> m_vector1; //!< First vector of derived objects.
559 std::vector<Ptr<Derived>> m_vector2; //!< Second vector of derived objects.
560 std::map<uint32_t, Ptr<Derived>> m_map1; //!< Map of uint32_t, derived objects.
561 std::unordered_map<uint64_t, Ptr<Derived>>
562 m_unorderedMap; //!< Unordered map of uint64_t, derived objects.
563 Callback<void, int8_t> m_cbValue; //!< Callback accepting an integer.
564 TracedValue<int8_t> m_intSrc1; //!< First int8_t Traced value.
565 TracedValue<int8_t> m_intSrc2; //!< Second int8_t Traced value.
566
567 /// Traced callbacks for (double, int, float) values.
568 typedef void (*NumericTracedCallback)(double, int, float);
569 TracedCallback<double, int, float> m_cb; //!< TracedCallback (double, int, float).
570 TracedValue<ValueClassTest> m_valueSrc; //!< ValueClassTest Traced value.
571 Ptr<Derived> m_ptr; //!< Pointer to Derived class.
572 Ptr<Derived> m_ptrInitialized; //!< Pointer to Derived class.
573 Ptr<Derived> m_ptrInitialized2; //!< Pointer to Derived class.
574 TracedValue<uint8_t> m_uintSrc; //!< uint8_t Traced value.
575 TracedValue<Test_e> m_enumSrc; //!< enum Traced value.
576 TracedValue<double> m_doubleSrc; //!< double Traced value.
577 TracedValue<bool> m_boolSrc; //!< bool Traced value.
578 Time m_timeWithBounds; //!< Time with bounds
579};
580
582
583/**
584 * \ingroup attribute-tests
585 *
586 * \brief Test case template used for generic Attribute Value types -- used to make
587 * sure that Attributes work as expected.
588 */
589template <typename T>
591{
592 public:
593 /**
594 * Constructor.
595 * \param description The TestCase description.
596 */
597 AttributeTestCase(std::string description);
598 ~AttributeTestCase() override;
599
600 private:
601 void DoRun() override;
602 /**
603 * Check the attribute path and value.
604 * \param p The object to test.
605 * \param attributeName The attribute name.
606 * \param expectedString The expected attribute name.
607 * \param expectedValue The expected attribute value.
608 * \return true if everything is as expected.
609 */
611 std::string attributeName,
612 std::string expectedString,
613 T expectedValue);
614};
615
616template <typename T>
618 : TestCase(description)
619{
620}
621
622template <typename T>
624{
625}
626
627template <typename T>
628bool
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// ===========================================================================
655template <>
656void
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
753template <>
754void
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
885template <>
886void
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
965template <>
966void
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
991template <>
992void
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
1066template <>
1067void
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
1163template <>
1164void
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
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
1245/**
1246 * \ingroup attribute-tests
1247 *
1248 * Test the Attributes of type RandomVariableStream.
1249 */
1251{
1252 public:
1253 /**
1254 * Constructor.
1255 * \param description The TestCase description.
1256 */
1257 RandomVariableStreamAttributeTestCase(std::string description);
1258
1260 {
1261 }
1262
1263 /**
1264 * Invoke the m_cbValue.
1265 * \param a The value to use on the callback.
1266 */
1268 {
1269 if (!m_cbValue.IsNull())
1270 {
1271 m_cbValue(a);
1272 }
1273 }
1274
1275 private:
1276 void DoRun() override;
1277
1278 /// Callback used in the test.
1280
1281 /**
1282 * Function called when the callback is used.
1283 * \param a The value of the callback.
1284 */
1286 {
1287 m_gotCbValue = a;
1288 }
1289
1290 int16_t m_gotCbValue; //!< Value used to verify that the callback has been invoked.
1291};
1292
1294 std::string description)
1295 : TestCase(description)
1296{
1297}
1298
1299void
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
1320/**
1321 * \ingroup attribute-tests
1322 *
1323 * \brief Test case for Object Vector Attributes.
1324 *
1325 * Generic nature is pretty much lost here, so we just break the class out.
1326 */
1328{
1329 public:
1330 /**
1331 * Constructor.
1332 * \param description The TestCase description.
1333 */
1334 ObjectVectorAttributeTestCase(std::string description);
1335
1337 {
1338 }
1339
1340 private:
1341 void DoRun() override;
1342};
1343
1345 : TestCase(description)
1346{
1347}
1348
1349void
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
1406/**
1407 * \ingroup attribute-tests
1408 *
1409 * \brief Test case for Object Map Attributes.
1410 */
1412{
1413 public:
1414 /**
1415 * Constructor.
1416 * \param description The TestCase description.
1417 */
1418 ObjectMapAttributeTestCase(std::string description);
1419
1421 {
1422 }
1423
1424 private:
1425 void DoRun() override;
1426};
1427
1429 : TestCase(description)
1430{
1431}
1432
1433void
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
1521/**
1522 * \ingroup attribute-tests
1523 *
1524 * \brief Trace sources with value semantics can be used like Attributes,
1525 * make sure we can use them that way.
1526 */
1528{
1529 public:
1530 /**
1531 * Constructor.
1532 * \param description The TestCase description.
1533 */
1534 IntegerTraceSourceAttributeTestCase(std::string description);
1535
1537 {
1538 }
1539
1540 private:
1541 void DoRun() override;
1542};
1543
1545 : TestCase(description)
1546{
1547}
1548
1549void
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
1632/**
1633 * \ingroup attribute-tests
1634 *
1635 * \brief Trace sources used like Attributes must also work as trace sources,
1636 * make sure we can use them that way.
1637 */
1639{
1640 public:
1641 /**
1642 * Constructor.
1643 * \param description The TestCase description.
1644 */
1645 IntegerTraceSourceTestCase(std::string description);
1646
1648 {
1649 }
1650
1651 private:
1652 void DoRun() override;
1653
1654 /**
1655 * Notify the call of source 1.
1656 * \param old First value.
1657 * \param n Second value.
1658 */
1659 void NotifySource1(int8_t old [[maybe_unused]], int8_t n)
1660 {
1661 m_got1 = n;
1662 }
1663
1664 int64_t m_got1; //!< Value used to verify that source 1 was called.
1665};
1666
1668 : TestCase(description)
1669{
1670}
1671
1672void
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
1731/**
1732 * \ingroup attribute-tests
1733 *
1734 * \brief Trace sources used like Attributes must also work as trace sources,
1735 * make sure we can use them that way.
1736 */
1738{
1739 public:
1740 /**
1741 * Constructor.
1742 * \param description The TestCase description.
1743 */
1744 TracedCallbackTestCase(std::string description);
1745
1747 {
1748 }
1749
1750 private:
1751 void DoRun() override;
1752
1753 /**
1754 * Notify the call of source 2.
1755 * \param a First value.
1756 * \param b Second value.
1757 * \param c Third value.
1758 */
1759 void NotifySource2(double a, int b [[maybe_unused]], float c [[maybe_unused]])
1760 {
1761 m_got2 = a;
1762 }
1763
1764 double m_got2; //!< Value used to verify that source 2 was called.
1765};
1766
1768 : TestCase(description)
1769{
1770}
1771
1772void
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
1830/**
1831 * \ingroup attribute-tests
1832 *
1833 * \brief Smart pointers (Ptr) are central to our architecture, so they
1834 * must work as attributes.
1835 */
1837{
1838 public:
1839 /**
1840 * Constructor.
1841 * \param description The TestCase description.
1842 */
1843 PointerAttributeTestCase(std::string description);
1844
1846 {
1847 }
1848
1849 private:
1850 void DoRun() override;
1851
1852 /**
1853 * Notify the call of source 2.
1854 * \param a First value.
1855 * \param b Second value.
1856 * \param c Third value.
1857 */
1858 void NotifySource2(double a, int b [[maybe_unused]], float c [[maybe_unused]])
1859 {
1860 m_got2 = a;
1861 }
1862
1863 double m_got2; //!< Value used to verify that source 2 was called.
1864};
1865
1867 : TestCase(description)
1868{
1869}
1870
1871void
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
1974/**
1975 * \ingroup attribute-tests
1976 *
1977 * \brief Test the Attributes of type CallbackValue.
1978 */
1980{
1981 public:
1982 /**
1983 * Constructor.
1984 * \param description The TestCase description.
1985 */
1986 CallbackValueTestCase(std::string description);
1987
1989 {
1990 }
1991
1992 /**
1993 * Function to invoke the callback.
1994 * \param a The value.
1995 */
1997 {
1998 if (!m_cbValue.IsNull())
1999 {
2000 m_cbValue(a);
2001 }
2002 }
2003
2004 private:
2005 void DoRun() override;
2006
2008
2009 /**
2010 * Function invoked when the callback is fired.
2011 * \param a The value.
2012 */
2014 {
2015 m_gotCbValue = a;
2016 }
2017
2018 int16_t m_gotCbValue; //!< Value used to verify that source 2 was called.
2019};
2020
2022 : TestCase(description)
2023{
2024}
2025
2026void
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
2075/**
2076 * \ingroup attribute-tests
2077 *
2078 * \brief The attributes Test Suite.
2079 */
2081{
2082 public:
2084};
2085
2087 : TestSuite("attributes", Type::UNIT)
2088{
2089 AddTestCase(new AttributeTestCase<BooleanValue>("Check Attributes of type BooleanValue"),
2090 TestCase::Duration::QUICK);
2091 AddTestCase(new AttributeTestCase<IntegerValue>("Check Attributes of type IntegerValue"),
2092 TestCase::Duration::QUICK);
2093 AddTestCase(new AttributeTestCase<UintegerValue>("Check Attributes of type UintegerValue"),
2094 TestCase::Duration::QUICK);
2095 AddTestCase(new AttributeTestCase<DoubleValue>("Check Attributes of type DoubleValue"),
2096 TestCase::Duration::QUICK);
2098 "Check Attributes of type EnumValue"),
2099 TestCase::Duration::QUICK);
2101 "Check Attributes of type EnumValue (wrapping an enum class)"),
2102 TestCase::Duration::QUICK);
2103 AddTestCase(new AttributeTestCase<TimeValue>("Check Attributes of type TimeValue"),
2104 TestCase::Duration::QUICK);
2106 new RandomVariableStreamAttributeTestCase("Check Attributes of type RandomVariableStream"),
2107 TestCase::Duration::QUICK);
2108 AddTestCase(new ObjectVectorAttributeTestCase("Check Attributes of type ObjectVectorValue"),
2109 TestCase::Duration::QUICK);
2110 AddTestCase(new ObjectMapAttributeTestCase("Check Attributes of type ObjectMapValue"),
2111 TestCase::Duration::QUICK);
2112 AddTestCase(new PointerAttributeTestCase("Check Attributes of type PointerValue"),
2113 TestCase::Duration::QUICK);
2114 AddTestCase(new CallbackValueTestCase("Check Attributes of type CallbackValue"),
2115 TestCase::Duration::QUICK);
2117 "Ensure TracedValue<uint8_t> can be set like IntegerValue"),
2118 TestCase::Duration::QUICK);
2120 new IntegerTraceSourceTestCase("Ensure TracedValue<uint8_t> also works as trace source"),
2121 TestCase::Duration::QUICK);
2123 "Ensure TracedCallback<double, int, float> works as trace source"),
2124 TestCase::Duration::QUICK);
2125}
2126
2127static 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.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Callback template class.
Definition: callback.h:438
bool IsNull() const
Check for null implementation.
Definition: callback.h:571
AttributeValue implementation for Callback.
Definition: callback.h:808
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
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:522
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.
Definition: pointer.h:48
Ptr< T > Get() const
Definition: pointer.h:234
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Hold variables of type string.
Definition: string.h:56
std::string Get() const
Definition: string.cc:31
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
@ NS
nanosecond
Definition: nstime.h:119
static void SetResolution(Unit resolution)
Definition: time.cc:213
AttributeValue implementation for Time.
Definition: nstime.h:1406
Forward calls to a chain of Callback.
Trace classes with value semantics.
Definition: traced-value.h:116
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.
AttributeValue implementation for ValueClassTest.
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:81
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeCallbackAccessor(T1 a1)
Definition: callback.h:840
Ptr< const AttributeChecker > MakeCallbackChecker()
Definition: callback.cc:88
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Definition: integer.h:46
ObjectPtrContainerValue ObjectMapValue
ObjectMapValue is an alias for ObjectPtrContainerValue.
Definition: object-map.h:40
Ptr< const AttributeAccessor > MakeObjectMapAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-map.h:76
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 AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:259
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1427
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1407
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
Ptr< const AttributeAccessor > MakeValueClassTestAccessor(T1 a1)
Ptr< const AttributeChecker > MakeValueClassTestChecker()
#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
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:894
bool SetDefaultFailSafe(std::string fullName, const AttributeValue &value)
Definition: config.cc:904
#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:145
#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:565
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
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.
bool operator!=(Callback< R, Args... > a, Callback< R, Args... > b)
Inequality test.
Definition: callback.h:680
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:706
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159
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:189
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:183