A Discrete-Event Network Simulator
API
attribute-test-suite.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2009 University of Washington
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#include "ns3/test.h"
20#include "ns3/object.h"
21#include "ns3/boolean.h"
22#include "ns3/integer.h"
23#include "ns3/uinteger.h"
24#include "ns3/config.h"
25#include "ns3/enum.h"
26#include "ns3/string.h"
27#include "ns3/random-variable-stream.h"
28#include "ns3/double.h"
29#include "ns3/object-vector.h"
30#include "ns3/object-map.h"
31#include "ns3/traced-value.h"
32#include "ns3/callback.h"
33#include "ns3/trace-source-accessor.h"
34#include "ns3/pointer.h"
35#include "ns3/object-factory.h"
36#include "ns3/nstime.h"
37
38using namespace ns3;
39
40namespace ns3 {
41
60{
61public:
63 {}
64
71 typedef void (* TracedValueCallback)(const ValueClassTest oldValue,
72 const ValueClassTest newValue);
73};
74
81bool operator != ([[maybe_unused]] const ValueClassTest &a, [[maybe_unused]] const ValueClassTest &b)
82{
83 return true;
84}
92std::ostream & operator << (std::ostream &os, [[maybe_unused]] ValueClassTest v)
93{
94 return os;
95}
103std::istream & operator >> (std::istream &is, [[maybe_unused]] ValueClassTest &v)
104{
105 return is;
106}
107
110
111} // end of ns3 namespace
112
118class Derived : public Object
119{
120public:
125 static TypeId GetTypeId (void)
126 {
127 static TypeId tid = TypeId ("ns3::Derived")
129 .SetParent<Object> ()
130 ;
131 return tid;
132 }
134 {}
135};
136
138
145{
146public:
149 {
152 TEST_C
153 };
158 static TypeId GetTypeId (void)
159 {
160 static TypeId tid = TypeId ("ns3::AttributeObjectTest")
162 .SetParent<Object> ()
163 .HideFromDocumentation ()
164 .AddAttribute ("TestBoolName", "help text",
165 BooleanValue (false),
168 .AddAttribute ("TestBoolA", "help text",
169 BooleanValue (false),
173 .AddAttribute ("TestInt16", "help text",
174 IntegerValue (-2),
176 MakeIntegerChecker<int16_t> ())
177 .AddAttribute ("TestInt16WithBounds", "help text",
178 IntegerValue (-2),
180 MakeIntegerChecker<int16_t> (-5, 10))
181 .AddAttribute ("TestInt16SetGet", "help text",
182 IntegerValue (6),
185 MakeIntegerChecker<int16_t> ())
186 .AddAttribute ("TestUint8", "help text",
187 UintegerValue (1),
189 MakeUintegerChecker<uint8_t> ())
190 .AddAttribute ("TestEnum", "help text",
193 MakeEnumChecker (TEST_A, "TestA",
194 TEST_B, "TestB",
195 TEST_C, "TestC"))
196 .AddAttribute ("TestEnumSetGet", "help text",
200 MakeEnumChecker (TEST_A, "TestA",
201 TEST_B, "TestB",
202 TEST_C, "TestC"))
203 .AddAttribute ("TestRandom", "help text",
204 StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"),
206 MakePointerChecker <RandomVariableStream>())
207 .AddAttribute ("TestFloat", "help text",
208 DoubleValue (-1.1),
210 MakeDoubleChecker<float> ())
211 .AddAttribute ("TestVector1", "help text",
214 MakeObjectVectorChecker<Derived> ())
215 .AddAttribute ("TestVector2", "help text",
219 MakeObjectVectorChecker<Derived> ())
220 .AddAttribute ("TestMap1", "help text",
223 MakeObjectMapChecker<Derived> ())
224 .AddAttribute ("IntegerTraceSource1", "help text",
225 IntegerValue (-2),
227 MakeIntegerChecker<int8_t> ())
228 .AddAttribute ("IntegerTraceSource2", "help text",
229 IntegerValue (-2),
232 MakeIntegerChecker<int8_t> ())
233 .AddAttribute ("UIntegerTraceSource", "help text",
234 UintegerValue (2),
236 MakeIntegerChecker<uint8_t> ())
237 .AddAttribute ("DoubleTraceSource", "help text",
238 DoubleValue (2),
240 MakeDoubleChecker<double> ())
241 .AddAttribute ("BoolTraceSource", "help text",
242 BooleanValue (false),
245 .AddAttribute ("EnumTraceSource", "help text",
246 EnumValue (false),
248 MakeEnumChecker (TEST_A, "TestA"))
249 .AddAttribute ("ValueClassSource", "help text",
251 MakeValueClassTestAccessor (&AttributeObjectTest::m_valueSrc),
252 MakeValueClassTestChecker ())
253 .AddTraceSource ("Source1", "help test",
255 "ns3::TracedValueCallback::Int8")
256 .AddTraceSource ("Source2", "help text",
258 "ns3::AttributeObjectTest::NumericTracedCallback")
259 .AddTraceSource ("ValueSource", "help text",
261 "ns3::ValueClassTest::TracedValueCallback")
262 .AddAttribute ("Pointer", "help text",
263 PointerValue (),
265 MakePointerChecker<Derived> ())
266 .AddAttribute ("PointerInitialized", "help text",
267 StringValue ("ns3::Derived"),
269 MakePointerChecker<Derived> ())
270 .AddAttribute ("PointerInitialized2", "help text",
271 StringValue ("ns3::Derived[]"),
273 MakePointerChecker<Derived> ())
274 .AddAttribute ("Callback", "help text",
275 CallbackValue (),
278 .AddAttribute ("TestTimeWithBounds", "help text",
279 TimeValue (Seconds (-2)),
281 MakeTimeChecker (Seconds (-5), Seconds (10)))
282 .AddAttribute ("TestDeprecated", "help text",
283 BooleanValue (false),
286 TypeId::DEPRECATED,
287 "DEPRECATED test working.")
288 ;
289
290 return tid;
291 }
292
294 {
295 }
296
297 virtual ~AttributeObjectTest (void)
298 {}
299
301 void AddToVector1 (void)
302 {
303 m_vector1.push_back (CreateObject<Derived> ());
304 }
306 void AddToVector2 (void)
307 {
308 m_vector2.push_back (CreateObject<Derived> ());
309 }
310
316 {
317 m_map1.insert (std::pair <uint32_t, Ptr<Derived> > (i, CreateObject<Derived> ()));
318 }
319
326 void InvokeCb (double a, int b, float c)
327 {
328 m_cb (a,b,c);
329 }
330
336 {
337 if (!m_cbValue.IsNull ())
338 {
339 m_cbValue (a);
340 }
341 }
342
343private:
348 void DoSetTestA (bool v)
349 {
350 m_boolTestA = v;
351 }
356 bool DoGetTestA (void) const
357 {
358 return m_boolTestA;
359 }
364 int16_t DoGetInt16 (void) const
365 {
366 return m_int16SetGet;
367 }
372 void DoSetInt16 (int16_t v)
373 {
374 m_int16SetGet = v;
375 }
380 std::size_t DoGetVectorN (void) const
381 {
382 return m_vector2.size ();
383 }
389 Ptr<Derived> DoGetVector (std::size_t i) const
390 {
391 return m_vector2[i];
392 }
399 {
400 m_intSrc2 = v;
401 return true;
402 }
407 int8_t DoGetIntSrc (void) const
408 {
409 return m_intSrc2;
410 }
417 {
418 m_enumSetGet = v;
419 return true;
420 }
425 Test_e DoGetEnum (void) const
426 {
427 return m_enumSetGet;
428 }
429
433 int16_t m_int16;
436 uint8_t m_uint8;
437 float m_float;
441 std::vector<Ptr<Derived> > m_vector1;
442 std::vector<Ptr<Derived> > m_vector2;
443 std::map <uint32_t, Ptr<Derived> > m_map1;
447
449 typedef void (* NumericTracedCallback) (double, int, float);
460};
461
463
470template <typename T>
472{
473public:
478 AttributeTestCase (std::string description);
479 virtual ~AttributeTestCase ();
480
481private:
482 virtual void DoRun (void);
491 bool CheckGetCodePaths (Ptr<Object> p, std::string attributeName, std::string expectedString, T expectedValue);
492};
493
494template <typename T>
496 : TestCase (description)
497{}
498
499template <typename T>
501{}
502
503template <typename T> bool
505 Ptr<Object> p,
506 std::string attributeName,
507 std::string expectedString,
508 T expectedValue)
509{
510 StringValue stringValue;
511 T actualValue;
512
513 //
514 // Get an Attribute value through its StringValue representation.
515 //
516 bool ok1 = p->GetAttributeFailSafe (attributeName.c_str (), stringValue);
517 bool ok2 = stringValue.Get () == expectedString;
518
519 //
520 // Get the existing boolean value through its particular type representation.
521 //
522 bool ok3 = p->GetAttributeFailSafe (attributeName.c_str (), actualValue);
523 bool ok4 = expectedValue.Get () == actualValue.Get ();
524
525 return ok1 && ok2 && ok3 && ok4;
526}
527
528// ===========================================================================
529// The actual Attribute type test cases are specialized for each Attribute type
530// ===========================================================================
531template <> void
533{
535 bool ok;
536
537 p = CreateObject<AttributeObjectTest> ();
538 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
539
540 //
541 // Set the default value of the BooleanValue and create an object. The new
542 // default value should stick.
543 //
544 Config::SetDefault ("ns3::AttributeObjectTest::TestBoolName", StringValue ("true"));
545 p = CreateObject<AttributeObjectTest> ();
546 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
547
548 ok = CheckGetCodePaths (p, "TestBoolName", "true", BooleanValue (true));
549 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by default value");
550
551 std::string expected ("Attribute 'TestDeprecated' is deprecated: DEPRECATED test working.\n");
552 // Temporarily redirect std::cerr to a stringstream
553 std::stringstream buffer;
554 std::streambuf *oldBuffer = std::cerr.rdbuf (buffer.rdbuf());
555 // Cause the deprecation warning to be sent to the stringstream
556 Config::SetDefault ("ns3::AttributeObjectTest::TestDeprecated", BooleanValue (true));
557
558 // Compare the obtained actual string with the expected string.
559 NS_TEST_ASSERT_MSG_EQ (buffer.str (), expected, "Deprecated attribute not working");
560 // Restore cerr to its original stream buffer
561 std::cerr.rdbuf (oldBuffer);
562
563
564
565 //
566 // Set the default value of the BooleanValue the other way and create an object.
567 // The new default value should stick.
568 //
569 Config::SetDefaultFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("false"));
570
571 p = CreateObject<AttributeObjectTest> ();
572 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
573
574 ok = CheckGetCodePaths (p, "TestBoolName", "false", BooleanValue (false));
575 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not et properly by default value");
576
577 //
578 // Set the BooleanValue Attribute to true via SetAttributeFailSafe path.
579 //
580 ok = p->SetAttributeFailSafe ("TestBoolName", StringValue ("true"));
581 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() \"TestBoolName\" to true");
582
583 ok = CheckGetCodePaths (p, "TestBoolName", "true", BooleanValue (true));
584 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
585
586 //
587 // Set the BooleanValue to false via SetAttributeFailSafe path.
588 //
589 ok = p->SetAttributeFailSafe ("TestBoolName", StringValue ("false"));
590 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() \"TestBoolName\" to false");
591
592 ok = CheckGetCodePaths (p, "TestBoolName", "false", BooleanValue (false));
593 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
594
595 //
596 // Create an object using
597 //
598 p = CreateObject<AttributeObjectTest> ();
599 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
600
601 //
602 // The previous object-based tests checked access directly. Now check through
603 // setter and getter. The code here looks the same, but the underlying
604 // attribute is declared differently in the object. First make sure we can set
605 // to true.
606 //
607 ok = p->SetAttributeFailSafe ("TestBoolA", StringValue ("true"));
608 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a boolean value to true");
609
610 ok = CheckGetCodePaths (p, "TestBoolA", "true", BooleanValue (true));
611 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() (getter/setter) via StringValue");
612
613 //
614 // Now Set the BooleanValue to false via the setter.
615 //
616 ok = p->SetAttributeFailSafe ("TestBoolA", StringValue ("false"));
617 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a boolean value to false");
618
619 ok = CheckGetCodePaths (p, "TestBoolA", "false", BooleanValue (false));
620 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() (getter/setter) via StringValue");
621}
622
623template <> void
625{
627 bool ok;
628
629 p = CreateObject<AttributeObjectTest> ();
630 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
631
632 //
633 // When the object is first created, the Attribute should have the default
634 // value.
635 //
636 ok = CheckGetCodePaths (p, "TestInt16", "-2", IntegerValue (-2));
637 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by default value");
638
639 //
640 // Set the Attribute to a negative value through a StringValue.
641 //
642 ok = p->SetAttributeFailSafe ("TestInt16", StringValue ("-5"));
643 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to -5");
644
645 ok = CheckGetCodePaths (p, "TestInt16", "-5", IntegerValue (-5));
646 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
647
648 //
649 // Set the Attribute to a positive value through a StringValue.
650 //
651 ok = p->SetAttributeFailSafe ("TestInt16", StringValue ("+2"));
652 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to +2");
653
654 ok = CheckGetCodePaths (p, "TestInt16", "2", IntegerValue (2));
655 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
656
657 //
658 // Set the Attribute to the most negative value of the signed 16-bit range.
659 //
660 ok = p->SetAttributeFailSafe ("TestInt16", StringValue ("-32768"));
661 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to -32768");
662
663 ok = CheckGetCodePaths (p, "TestInt16", "-32768", IntegerValue (-32768));
664 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() (most negative) via StringValue");
665
666 //
667 // Try to set the Attribute past the most negative value of the signed 16-bit
668 // range and make sure the underlying attribute is unchanged.
669 //
670 ok = p->SetAttributeFailSafe ("TestInt16", StringValue ("-32769"));
671 NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via StringValue to -32769");
672
673 ok = CheckGetCodePaths (p, "TestInt16", "-32768", IntegerValue (-32768));
674 NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
675
676 //
677 // Set the Attribute to the most positive value of the signed 16-bit range.
678 //
679 ok = p->SetAttributeFailSafe ("TestInt16", StringValue ("32767"));
680 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to 32767");
681
682 ok = CheckGetCodePaths (p, "TestInt16", "32767", IntegerValue (32767));
683 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() (most positive) via StringValue");
684
685 //
686 // Try to set the Attribute past the most positive value of the signed 16-bit
687 // range and make sure the underlying attribute is unchanged.
688 //
689 ok = p->SetAttributeFailSafe ("TestInt16", StringValue ("32768"));
690 NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via StringValue to 32768");
691
692 ok = CheckGetCodePaths (p, "TestInt16", "32767", IntegerValue (32767));
693 NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
694
695 //
696 // Attributes can have limits other than the intrinsic limits of the
697 // underlying data types. These limits are specified in the Object.
698 //
699 ok = p->SetAttributeFailSafe ("TestInt16WithBounds", IntegerValue (10));
700 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 10");
701
702 ok = CheckGetCodePaths (p, "TestInt16WithBounds", "10", IntegerValue (10));
703 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() (positive limit) via StringValue");
704
705 //
706 // Set the Attribute past the positive limit.
707 //
708 ok = p->SetAttributeFailSafe ("TestInt16WithBounds", IntegerValue (11));
709 NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 11");
710
711 ok = CheckGetCodePaths (p, "TestInt16WithBounds", "10", IntegerValue (10));
712 NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
713
714 //
715 // Set the Attribute at the negative limit.
716 //
717 ok = p->SetAttributeFailSafe ("TestInt16WithBounds", IntegerValue (-5));
718 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -5");
719
720 ok = CheckGetCodePaths (p, "TestInt16WithBounds", "-5", IntegerValue (-5));
721 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() (negative limit) via StringValue");
722
723 //
724 // Set the Attribute past the negative limit.
725 //
726 ok = p->SetAttributeFailSafe ("TestInt16WithBounds", IntegerValue (-6));
727 NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -6");
728
729 ok = CheckGetCodePaths (p, "TestInt16WithBounds", "-5", IntegerValue (-5));
730 NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
731}
732
733template <> void
735{
737 bool ok;
738
739 p = CreateObject<AttributeObjectTest> ();
740 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
741
742 //
743 // When the object is first created, the Attribute should have the default
744 // value.
745 //
746 ok = CheckGetCodePaths (p, "TestUint8", "1", UintegerValue (1));
747 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by default value");
748
749 //
750 // Set the Attribute to zero.
751 //
752 ok = p->SetAttributeFailSafe ("TestUint8", UintegerValue (0));
753 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to 0");
754
755 ok = CheckGetCodePaths (p, "TestUint8", "0", UintegerValue (0));
756 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
757
758 //
759 // Set the Attribute to the most positive value of the unsigned 8-bit range.
760 //
761 ok = p->SetAttributeFailSafe ("TestUint8", UintegerValue (255));
762 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to 255");
763
764 ok = CheckGetCodePaths (p, "TestUint8", "255", UintegerValue (255));
765 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() (positive limit) via UintegerValue");
766
767 //
768 // Try and set the Attribute past the most positive value of the unsigned
769 // 8-bit range.
770 //
771 ok = p->SetAttributeFailSafe ("TestUint8", UintegerValue (256));
772 NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() to 256");
773
774 ok = CheckGetCodePaths (p, "TestUint8", "255", UintegerValue (255));
775 NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
776
777 //
778 // Set the Attribute to the most positive value of the unsigned 8-bit range
779 // through a StringValue.
780 //
781 ok = p->SetAttributeFailSafe ("TestUint8", StringValue ("255"));
782 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to 255");
783
784 ok = CheckGetCodePaths (p, "TestUint8", "255", UintegerValue (255));
785 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
786
787 //
788 // Try and set the Attribute past the most positive value of the unsigned
789 // 8-bit range through a StringValue.
790 //
791 ok = p->SetAttributeFailSafe ("TestUint8", StringValue ("256"));
792 NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via StringValue to 256");
793
794 ok = CheckGetCodePaths (p, "TestUint8", "255", UintegerValue (255));
795 NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
796
797 //
798 // Try to set the Attribute to a negative StringValue.
799 //
800 ok = p->SetAttributeFailSafe ("TestUint8", StringValue ("-1"));
801 NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via StringValue to -1");
802}
803
804template <> void
806{
808 bool ok;
809
810 p = CreateObject<AttributeObjectTest> ();
811 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
812
813 //
814 // When the object is first created, the Attribute should have the default
815 // value.
816 //
817 ok = CheckGetCodePaths (p, "TestFloat", "-1.1", DoubleValue ((float)-1.1));
818 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by default value");
819
820 //
821 // Set the Attribute.
822 //
823 ok = p->SetAttributeFailSafe ("TestFloat", DoubleValue ((float)2.3));
824 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to 2.3");
825
826 ok = CheckGetCodePaths (p, "TestFloat", "2.3", DoubleValue ((float)2.3));
827 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via DoubleValue");
828}
829
830template <> void
832{
834 bool ok;
835
836 p = CreateObject<AttributeObjectTest> ();
837 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
838
839 //
840 // When the object is first created, the Attribute should have the default
841 // value.
842 //
843 ok = CheckGetCodePaths (p, "TestEnum", "TestA", EnumValue (AttributeObjectTest::TEST_A));
844 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by default value");
845
846 //
847 // Set the Attribute using the EnumValue type.
848 //
849 ok = p->SetAttributeFailSafe ("TestEnum", EnumValue (AttributeObjectTest::TEST_C));
850 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to TEST_C");
851
852 ok = CheckGetCodePaths (p, "TestEnum", "TestC", EnumValue (AttributeObjectTest::TEST_C));
853 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via EnumValue");
854
855 //
856 // When the object is first created, the Attribute should have the default
857 // value.
858 //
859 ok = CheckGetCodePaths (p, "TestEnumSetGet", "TestB", EnumValue (AttributeObjectTest::TEST_B));
860 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by default value");
861
862 //
863 // Set the Attribute using the EnumValue type.
864 //
865 ok = p->SetAttributeFailSafe ("TestEnumSetGet", EnumValue (AttributeObjectTest::TEST_C));
866 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to TEST_C");
867
868 ok = CheckGetCodePaths (p, "TestEnumSetGet", "TestC", EnumValue (AttributeObjectTest::TEST_C));
869 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via EnumValue");
870
871 //
872 // Set the Attribute using the StringValue type.
873 //
874 ok = p->SetAttributeFailSafe ("TestEnum", StringValue ("TestB"));
875 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to TEST_B");
876
877 ok = CheckGetCodePaths (p, "TestEnum", "TestB", EnumValue (AttributeObjectTest::TEST_B));
878 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
879
880 //
881 // Try to set the Attribute to a bogus enum using the StringValue type
882 // throws a fatal error.
883 //
884 // ok = p->SetAttributeFailSafe ("TestEnum", StringValue ("TestD"));
885 // NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() to TEST_D"); //
886
887 ok = CheckGetCodePaths (p, "TestEnum", "TestB", EnumValue (AttributeObjectTest::TEST_B));
888 NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
889
890 //
891 // Try to set the Attribute to a bogus enum using an integer implicit conversion
892 // and make sure the underlying value doesn't change.
893 //
894 ok = p->SetAttributeFailSafe ("TestEnum", EnumValue (5));
895 NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() to 5");
896
897 ok = CheckGetCodePaths (p, "TestEnum", "TestB", EnumValue (AttributeObjectTest::TEST_B));
898 NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
899}
900
901template <> void
903{
905 bool ok;
906
907 p = CreateObject<AttributeObjectTest> ();
908 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
909
910 // The test vectors assume ns resolution
911 Time::SetResolution (Time::NS);
912
913 //
914 // Set value
915 //
916 ok = p->SetAttributeFailSafe ("TestTimeWithBounds", TimeValue (Seconds (5)));
917 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via TimeValue to 5s");
918
919 ok = CheckGetCodePaths (p, "TestTimeWithBounds", "+5e+09ns", TimeValue (Seconds (5)));
920 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe(5s) via TimeValue");
921
922 ok = p->SetAttributeFailSafe ("TestTimeWithBounds", StringValue ("3s"));
923 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via TimeValue to 3s");
924
925 ok = CheckGetCodePaths (p, "TestTimeWithBounds", "+3e+09ns", TimeValue (Seconds (3)));
926 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe(3s) via StringValue");
927
928
929 //
930 // Attributes can have limits other than the intrinsic limits of the
931 // underlying data types. These limits are specified in the Object.
932 //
933
934 //
935 // Set the Attribute at the positive limit
936 //
937 ok = p->SetAttributeFailSafe ("TestTimeWithBounds", TimeValue (Seconds (10)));
938 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via TimeValue to 10s");
939
940 ok = CheckGetCodePaths (p, "TestTimeWithBounds", "+1e+10ns", TimeValue (Seconds (10)));
941 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe(10s [positive limit]) via StringValue");
942
943 //
944 // Set the Attribute past the positive limit.
945 //
946 ok = p->SetAttributeFailSafe ("TestTimeWithBounds", TimeValue (Seconds (11)));
947 NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via TimeValue to 11s [greater than positive limit]");
948
949 ok = CheckGetCodePaths (p, "TestTimeWithBounds", "+1e+10ns", TimeValue (Seconds (10)));
950 NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
951
952 //
953 // Set the Attribute at the negative limit.
954 //
955 ok = p->SetAttributeFailSafe ("TestTimeWithBounds", TimeValue (Seconds (-5)));
956 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via TimeValue to -5s");
957
958 ok = CheckGetCodePaths (p, "TestTimeWithBounds", "-5e+09ns", TimeValue (Seconds (-5)));
959 NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe(-5s [negative limit]) via StringValue");
960
961 //
962 // Set the Attribute past the negative limit.
963 //
964 ok = p->SetAttributeFailSafe ("TestTimeWithBounds", TimeValue (Seconds (-6)));
965 NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via TimeValue to -6s");
966
967 ok = CheckGetCodePaths (p, "TestTimeWithBounds", "-5e+09ns", TimeValue (Seconds (-5)));
968 NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
969}
970
977{
978public:
983 RandomVariableStreamAttributeTestCase (std::string description);
985 {}
986
992 {
993 if (!m_cbValue.IsNull ())
994 {
995 m_cbValue (a);
996 }
997 }
998
999private:
1000 virtual void DoRun (void);
1001
1004
1010 {
1011 m_gotCbValue = a;
1012 }
1013
1015};
1016
1018 : TestCase (description)
1019{}
1020
1021void
1023{
1025 bool ok;
1026
1027 p = CreateObject<AttributeObjectTest> ();
1028 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
1029
1030 //
1031 // Try to set a UniformRandomVariable
1032 //
1033 ok = p->SetAttributeFailSafe ("TestRandom", StringValue ("ns3::UniformRandomVariable[Min=0.|Max=1.]"));
1034 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a UniformRandomVariable");
1035
1036 //
1037 // Try to set a <snicker> ConstantRandomVariable
1038 //
1039 ok = p->SetAttributeFailSafe ("TestRandom", StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"));
1040 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a ConstantRandomVariable");
1041}
1042
1051{
1052public:
1057 ObjectVectorAttributeTestCase (std::string description);
1059 {}
1060
1061private:
1062 virtual void DoRun (void);
1063};
1064
1066 : TestCase (description)
1067{}
1068
1069void
1071{
1073 ObjectVectorValue vector;
1074
1075 p = CreateObject<AttributeObjectTest> ();
1076 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
1077
1078 //
1079 // When the object is first created, the Attribute should have no items in
1080 // the vector.
1081 //
1082 p->GetAttribute ("TestVector1", vector);
1083 NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 0, "Initial count of ObjectVectorValue \"TestVector1\" should be zero");
1084
1085 //
1086 // Adding to the attribute shouldn't affect the value we already have.
1087 //
1088 p->AddToVector1 ();
1089 NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 0, "Initial count of ObjectVectorValue \"TestVector1\" should still be zero");
1090
1091 //
1092 // Getting the attribute again should update the value.
1093 //
1094 p->GetAttribute ("TestVector1", vector);
1095 NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 1, "ObjectVectorValue \"TestVector1\" should be incremented");
1096
1097 //
1098 // Get the Object pointer from the value.
1099 //
1100 Ptr<Object> a = vector.Get (0);
1101 NS_TEST_ASSERT_MSG_NE (a, 0, "Ptr<Object> from VectorValue \"TestVector1\" is zero");
1102
1103 //
1104 // Adding to the attribute shouldn't affect the value we already have.
1105 //
1106 p->AddToVector1 ();
1107 NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 1, "Count of ObjectVectorValue \"TestVector1\" should still be one");
1108
1109 //
1110 // Getting the attribute again should update the value.
1111 //
1112 p->GetAttribute ("TestVector1", vector);
1113 NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 2, "ObjectVectorValue \"TestVector1\" should be incremented");
1114}
1115
1122{
1123public:
1128 ObjectMapAttributeTestCase (std::string description);
1130 {}
1131
1132private:
1133 virtual void DoRun (void);
1134};
1135
1137 : TestCase (description)
1138{}
1139
1140void
1142{
1144 ObjectMapValue map;
1145
1146 p = CreateObject<AttributeObjectTest> ();
1147 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
1148
1149 //
1150 // When the object is first created, the Attribute should have no items in
1151 // the vector.
1152 //
1153 p->GetAttribute ("TestMap1", map);
1154 NS_TEST_ASSERT_MSG_EQ (map.GetN (), 0, "Initial count of ObjectVectorValue \"TestMap1\" should be zero");
1155
1156 //
1157 // Adding to the attribute shouldn't affect the value we already have.
1158 //
1159 p->AddToMap1 (1);
1160 NS_TEST_ASSERT_MSG_EQ (map.GetN (), 0, "Initial count of ObjectVectorValue \"TestMap1\" should still be zero");
1161
1162 //
1163 // Getting the attribute again should update the value.
1164 //
1165 p->GetAttribute ("TestMap1", map);
1166 NS_TEST_ASSERT_MSG_EQ (map.GetN (), 1, "ObjectVectorValue \"TestMap1\" should be incremented");
1167
1168 //
1169 // Get the Object pointer from the value.
1170 //
1171 Ptr<Object> a = map.Get (1);
1172 NS_TEST_ASSERT_MSG_NE (a, 0, "Ptr<Object> from VectorValue \"TestMap1\" is zero");
1173
1174 //
1175 // Adding to the attribute shouldn't affect the value we already have.
1176 //
1177 p->AddToMap1 (2);
1178 NS_TEST_ASSERT_MSG_EQ (map.GetN (), 1, "Count of ObjectVectorValue \"TestMap1\" should still be one");
1179
1180 //
1181 // Getting the attribute again should update the value.
1182 //
1183 p->GetAttribute ("TestMap1", map);
1184 NS_TEST_ASSERT_MSG_EQ (map.GetN (), 2, "ObjectVectorValue \"TestMap1\" should be incremented");
1185}
1186
1194{
1195public:
1200 IntegerTraceSourceAttributeTestCase (std::string description);
1202 {}
1203
1204private:
1205 virtual void DoRun (void);
1206};
1207
1209 : TestCase (description)
1210{}
1211
1212void
1214{
1216 IntegerValue iv;
1217 bool ok;
1218
1219 p = CreateObject<AttributeObjectTest> ();
1220 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
1221
1222 //
1223 // When the object is first created, the Attribute should have the default
1224 // value.
1225 //
1226 p->GetAttribute ("IntegerTraceSource1", iv);
1227 NS_TEST_ASSERT_MSG_EQ (iv.Get (), -2, "Attribute not set properly by default value");
1228
1229 //
1230 // Set the Attribute to a positive value through an IntegerValue.
1231 //
1232 ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (5));
1233 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 5");
1234
1235 p->GetAttribute ("IntegerTraceSource1", iv);
1236 NS_TEST_ASSERT_MSG_EQ (iv.Get (), 5, "Attribute not set properly by SetAttributeFailSafe() via IntegerValue");
1237
1238 //
1239 // Limits should work.
1240 //
1241 ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (127));
1242 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 127");
1243
1244 ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (128));
1245 NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 128");
1246
1247 ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (-128));
1248 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -128");
1249
1250 ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (-129));
1251 NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -129");
1252
1253 //
1254 // When the object is first created, the Attribute should have the default
1255 // value.
1256 //
1257 p->GetAttribute ("IntegerTraceSource2", iv);
1258 NS_TEST_ASSERT_MSG_EQ (iv.Get (), -2, "Attribute not set properly by default value");
1259
1260 //
1261 // Set the Attribute to a positive value through an IntegerValue.
1262 //
1263 ok = p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (5));
1264 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 5");
1265
1266 p->GetAttribute ("IntegerTraceSource2", iv);
1267 NS_TEST_ASSERT_MSG_EQ (iv.Get (), 5, "Attribute not set properly by SetAttributeFailSafe() via IntegerValue");
1268
1269 //
1270 // Limits should work.
1271 //
1272 ok = p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (127));
1273 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 127");
1274
1275 ok = p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (128));
1276 NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 128");
1277
1278 ok = p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (-128));
1279 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -128");
1280
1281 ok = p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (-129));
1282 NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -129");
1283}
1284
1292{
1293public:
1298 IntegerTraceSourceTestCase (std::string description);
1300 {}
1301
1302private:
1303 virtual void DoRun (void);
1304
1310 void NotifySource1 ([[maybe_unused]] int8_t old, int8_t n)
1311 {
1312 m_got1 = n;
1313 }
1314 int64_t m_got1;
1315};
1316
1318 : TestCase (description)
1319{}
1320
1321void
1323{
1325 bool ok;
1326
1327 p = CreateObject<AttributeObjectTest> ();
1328 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
1329
1330 //
1331 // Check to make sure changing an Attribute value triggers a trace callback
1332 // that sets a member variable.
1333 //
1334 m_got1 = 1234;
1335
1336 ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (-1));
1337 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -1");
1338
1339 //
1340 // Source1 is declared as a TraceSourceAccessor to m_intSrc1. This m_intSrc1
1341 // is also declared as an Integer Attribute. We just checked to make sure we
1342 // could set it using an IntegerValue through its IntegerTraceSource1 "persona."
1343 // We should also be able to hook a trace source to the underlying variable.
1344 //
1345 ok = p->TraceConnectWithoutContext ("Source1", MakeCallback (&IntegerTraceSourceTestCase::NotifySource1, this));
1346 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not TraceConnectWithoutContext() \"Source1\" to NodifySource1()");
1347
1348 //
1349 // When we set the IntegerValue that now underlies both the Integer Attribute
1350 // and the trace source, the trace should fire and call NotifySource1 which
1351 // will set m_got1 to the new value.
1352 //
1353 ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (0));
1354 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 0");
1355
1356 NS_TEST_ASSERT_MSG_EQ (m_got1, 0, "Hitting a TracedValue does not cause trace callback to be called");
1357
1358 //
1359 // Now disconnect from the trace source and ensure that the trace callback
1360 // is not called if the trace source is hit.
1361 //
1362 ok = p->TraceDisconnectWithoutContext ("Source1", MakeCallback (&IntegerTraceSourceTestCase::NotifySource1, this));
1363 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not TraceConnectWithoutContext() \"Source1\" to NodifySource1()");
1364
1365 ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (1));
1366 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 1");
1367
1368 NS_TEST_ASSERT_MSG_EQ (m_got1, 0, "Hitting a TracedValue after disconnect still causes callback");
1369}
1370
1378{
1379public:
1384 TracedCallbackTestCase (std::string description);
1386 {}
1387
1388private:
1389 virtual void DoRun (void);
1390
1397 void NotifySource2 (double a, [[maybe_unused]] int b, [[maybe_unused]] float c)
1398 {
1399 m_got2 = a;
1400 }
1401
1402 double m_got2;
1403};
1404
1406 : TestCase (description)
1407{}
1408
1409void
1411{
1413 bool ok;
1414
1415 p = CreateObject<AttributeObjectTest> ();
1416 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
1417
1418 //
1419 // Initialize the
1420 //
1421 m_got2 = 4.3;
1422
1423 //
1424 // Invoke the callback that lies at the heart of this test. We have a
1425 // method InvokeCb() that just executes m_cb(). The variable m_cb is
1426 // declared as a TracedCallback<double, int, float>. This kind of beast
1427 // is like a callback but can call a list of targets. This list should
1428 // be empty so nothing should happen now. Specifically, m_got2 shouldn't
1429 // have changed.
1430 //
1431 p->InvokeCb (1.0, -5, 0.0);
1432 NS_TEST_ASSERT_MSG_EQ (m_got2, 4.3, "Invoking a newly created TracedCallback results in an unexpected callback");
1433
1434 //
1435 // Now, wire the TracedCallback up to a trace sink. This sink will just set
1436 // m_got2 to the first argument.
1437 //
1438 ok = p->TraceConnectWithoutContext ("Source2", MakeCallback (&TracedCallbackTestCase::NotifySource2, this));
1439 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not TraceConnectWithoutContext() to NotifySource2");
1440
1441 //
1442 // Now if we invoke the callback, the trace source should fire and m_got2
1443 // should be set in the trace sink.
1444 //
1445 p->InvokeCb (1.0, -5, 0.0);
1446 NS_TEST_ASSERT_MSG_EQ (m_got2, 1.0, "Invoking TracedCallback does not result in trace callback");
1447
1448 //
1449 // Now, disconnect the trace sink and see what happens when we invoke the
1450 // callback again. Of course, the trace should not happen and m_got2
1451 // should remain unchanged.
1452 //
1453 ok = p->TraceDisconnectWithoutContext ("Source2", MakeCallback (&TracedCallbackTestCase::NotifySource2, this));
1454 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not TraceDisconnectWithoutContext() from NotifySource2");
1455
1456 p->InvokeCb (-1.0, -5, 0.0);
1457 NS_TEST_ASSERT_MSG_EQ (m_got2, 1.0, "Invoking disconnected TracedCallback unexpectedly results in trace callback");
1458}
1459
1467{
1468public:
1473 PointerAttributeTestCase (std::string description);
1475 {}
1476
1477private:
1478 virtual void DoRun (void);
1479
1486 void NotifySource2 (double a, [[maybe_unused]] int b, [[maybe_unused]] float c)
1487 {
1488 m_got2 = a;
1489 }
1490
1491 double m_got2;
1492};
1493
1495 : TestCase (description)
1496{}
1497
1498void
1500{
1502 bool ok;
1503
1504 p = CreateObject<AttributeObjectTest> ();
1505 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
1506
1507 //
1508 // We have declared a PointerValue Attribute named "Pointer" with a pointer
1509 // checker of type Derived. This means that we should be able to pull out
1510 // a Ptr<Derived> with the initial value (which is 0).
1511 //
1512 PointerValue ptr;
1513 p->GetAttribute ("Pointer", ptr);
1514 Ptr<Derived> derived = ptr.Get<Derived> ();
1515 NS_TEST_ASSERT_MSG_EQ (derived, 0, "Unexpectedly found non-null pointer in newly initialized PointerValue Attribute");
1516
1517 //
1518 // Now, lets create an Object of type Derived and set the local Ptr to point
1519 // to that object. We can then set the PointerValue Attribute to that Ptr.
1520 //
1521 derived = Create<Derived> ();
1522 ok = p->SetAttributeFailSafe ("Pointer", PointerValue (derived));
1523 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a PointerValue of the correct type");
1524
1525 //
1526 // Pull the value back out of the Attribute and make sure it points to the
1527 // correct object.
1528 //
1529 p->GetAttribute ("Pointer", ptr);
1530 Ptr<Derived> stored = ptr.Get<Derived> ();
1531 NS_TEST_ASSERT_MSG_EQ (stored, derived, "Retrieved Attribute does not match stored PointerValue");
1532
1533 //
1534 // We should be able to use the Attribute Get() just like GetObject<type>,
1535 // So see if we can get a Ptr<Object> out of the Ptr<Derived> we stored.
1536 // This should be a pointer to the same physical memory since its the
1537 // same object.
1538 //
1539 p->GetAttribute ("Pointer", ptr);
1540 Ptr<Object> storedBase = ptr.Get<Object> ();
1541 NS_TEST_ASSERT_MSG_EQ (storedBase, stored, "Retrieved Ptr<Object> does not match stored Ptr<Derived>");
1542
1543 //
1544 // If we try to Get() something that is unrelated to what we stored, we should
1545 // retrieve a 0.
1546 //
1547 p->GetAttribute ("Pointer", ptr);
1549 NS_TEST_ASSERT_MSG_EQ (x, 0, "Unexpectedly retrieved unrelated Ptr<type> from stored Ptr<Derived>");
1550
1551 //
1552 // Test whether the initialized pointers from two different objects
1553 // point to different Derived objects
1554 //
1555 p->GetAttribute ("PointerInitialized", ptr);
1556 Ptr<Derived> storedPtr = ptr.Get<Derived> ();
1557 Ptr<AttributeObjectTest> p2 = CreateObject<AttributeObjectTest> ();
1558 PointerValue ptr2;
1559 p2->GetAttribute ("PointerInitialized", ptr2);
1560 Ptr<Derived> storedPtr2 = ptr2.Get<Derived> ();
1561 NS_TEST_ASSERT_MSG_NE (storedPtr, storedPtr2, "ptr and ptr2 both have PointerInitialized pointing to the same object");
1562 PointerValue ptr3;
1563 p2->GetAttribute ("PointerInitialized", ptr3);
1564 Ptr<Derived> storedPtr3 = ptr3.Get<Derived> ();
1565 NS_TEST_ASSERT_MSG_NE (storedPtr, storedPtr3, "ptr and ptr3 both have PointerInitialized pointing to the same object");
1566
1567 //
1568 // Test whether object factory creates the objects properly
1569 //
1570 ObjectFactory factory;
1571 factory.SetTypeId ("ns3::AttributeObjectTest");
1572 factory.Set ("PointerInitialized", StringValue ("ns3::Derived"));
1574 NS_TEST_ASSERT_MSG_NE (aotPtr, 0, "Unable to factory.Create() a AttributeObjectTest");
1576 NS_TEST_ASSERT_MSG_NE (aotPtr2, 0, "Unable to factory.Create() a AttributeObjectTest");
1577 NS_TEST_ASSERT_MSG_NE (aotPtr, aotPtr2, "factory object not creating unique objects");
1578 PointerValue ptr4;
1579 aotPtr->GetAttribute ("PointerInitialized", ptr4);
1580 Ptr<Derived> storedPtr4 = ptr4.Get<Derived> ();
1581 PointerValue ptr5;
1582 aotPtr2->GetAttribute ("PointerInitialized", ptr5);
1583 Ptr<Derived> storedPtr5 = ptr5.Get<Derived> ();
1584 NS_TEST_ASSERT_MSG_NE (storedPtr4, storedPtr5, "aotPtr and aotPtr2 are unique, but their Derived member is not");
1585}
1586
1593{
1594public:
1599 CallbackValueTestCase (std::string description);
1601 {}
1602
1608 {
1609 if (!m_cbValue.IsNull ())
1610 {
1611 m_cbValue (a);
1612 }
1613 }
1614
1615private:
1616 virtual void DoRun (void);
1617
1619
1625 {
1626 m_gotCbValue = a;
1627 }
1628
1630};
1631
1633 : TestCase (description)
1634{}
1635
1636void
1638{
1640 bool ok;
1641
1642 p = CreateObject<AttributeObjectTest> ();
1643 NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
1644
1645 //
1646 // The member variable m_cbValue is declared as a Callback<void, int8_t>. The
1647 // Attribute named "Callback" also points to m_cbValue and allows us to set the
1648 // callback using that Attribute.
1649 //
1650 // NotifyCallbackValue is going to be the target of the callback and will just set
1651 // m_gotCbValue to its single parameter. This will be the parameter from the
1652 // callback invocation. The method InvokeCbValue() just invokes the m_cbValue
1653 // callback if it is non-null.
1654 //
1655 m_gotCbValue = 1;
1656
1657 //
1658 // If we invoke the callback (which has not been set) nothing should happen.
1659 // Further, nothing should happen when we initialize the callback (it shouldn't
1660 // accidentally fire).
1661 //
1662 p->InvokeCbValue (2);
1664
1665 NS_TEST_ASSERT_MSG_EQ (m_gotCbValue, 1, "Callback unexpectedly fired");
1666
1667 ok = p->SetAttributeFailSafe ("Callback", cbValue);
1668 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a CallbackValue");
1669
1670 //
1671 // Now that the callback has been set, invoking it should set m_gotCbValue.
1672 //
1673 p->InvokeCbValue (2);
1674 NS_TEST_ASSERT_MSG_EQ (m_gotCbValue, 2, "Callback Attribute set by CallbackValue did not fire");
1675
1676 ok = p->SetAttributeFailSafe ("Callback", CallbackValue (MakeNullCallback<void,int8_t> ()));
1677 NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a null CallbackValue");
1678
1679 //
1680 // If the callback has been set to a null callback, it should no longer fire.
1681 //
1682 p->InvokeCbValue (3);
1683 NS_TEST_ASSERT_MSG_EQ (m_gotCbValue, 2, "Callback Attribute set to null callback unexpectedly fired");
1684}
1685
1692{
1693public:
1695};
1696
1698 : TestSuite ("attributes", UNIT)
1699{
1700 AddTestCase (new AttributeTestCase<BooleanValue> ("Check Attributes of type BooleanValue"), TestCase::QUICK);
1701 AddTestCase (new AttributeTestCase<IntegerValue> ("Check Attributes of type IntegerValue"), TestCase::QUICK);
1702 AddTestCase (new AttributeTestCase<UintegerValue> ("Check Attributes of type UintegerValue"), TestCase::QUICK);
1703 AddTestCase (new AttributeTestCase<DoubleValue> ("Check Attributes of type DoubleValue"), TestCase::QUICK);
1704 AddTestCase (new AttributeTestCase<EnumValue> ("Check Attributes of type EnumValue"), TestCase::QUICK);
1705 AddTestCase (new AttributeTestCase<TimeValue> ("Check Attributes of type TimeValue"), TestCase::QUICK);
1706 AddTestCase (new RandomVariableStreamAttributeTestCase ("Check Attributes of type RandomVariableStream"), TestCase::QUICK);
1707 AddTestCase (new ObjectVectorAttributeTestCase ("Check Attributes of type ObjectVectorValue"), TestCase::QUICK);
1708 AddTestCase (new ObjectMapAttributeTestCase ("Check Attributes of type ObjectMapValue"), TestCase::QUICK);
1709 AddTestCase (new PointerAttributeTestCase ("Check Attributes of type PointerValue"), TestCase::QUICK);
1710 AddTestCase (new CallbackValueTestCase ("Check Attributes of type CallbackValue"), TestCase::QUICK);
1711 AddTestCase (new IntegerTraceSourceAttributeTestCase ("Ensure TracedValue<uint8_t> can be set like IntegerValue"), TestCase::QUICK);
1712 AddTestCase (new IntegerTraceSourceTestCase ("Ensure TracedValue<uint8_t> also works as trace source"), TestCase::QUICK);
1713 AddTestCase (new TracedCallbackTestCase ("Ensure TracedCallback<double, int, float> works as trace source"), TestCase::QUICK);
1714}
1715
static AttributesTestSuite g_attributesTestSuite
Static variable for test initialization.
Class used to check attributes.
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.
enum Test_e m_enumSetGet
Enum set-get.
static TypeId GetTypeId(void)
Get the type ID.
std::map< uint32_t, Ptr< Derived > > m_map1
Map of uint32_t, derived objects.
int16_t m_int16SetGet
16-bit integer set-get.
void InvokeCb(double a, int b, float c)
Invoke the m_cb callback.
Ptr< RandomVariableStream > m_random
Random number generator.
bool m_boolTestA
Boolean test A.
int16_t m_int16
16-bit integer.
std::vector< Ptr< Derived > > m_vector1
First vector of derived objects.
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.
TracedCallback< double, int, float > m_cb
TracedCallback (double, int, float).
Test_e DoGetEnum(void) const
Get the m_enumSetGet value.
Ptr< Derived > m_ptr
Pointer to Derived class.
virtual ~AttributeObjectTest(void)
int8_t DoGetIntSrc(void) const
Get the m_intSrc2 value.
void AddToVector1(void)
Add an object to the first vector.
int16_t m_int16WithBounds
16-bit integer with bounds.
TracedValue< int8_t > m_intSrc1
First int8_t Traced value.
Callback< void, int8_t > m_cbValue
Callback accepting an integer.
Ptr< Derived > m_ptrInitialized
Pointer to Derived class.
Ptr< Derived > m_ptrInitialized2
Pointer to Derived class.
std::size_t DoGetVectorN(void) const
Get the length of m_vector2.
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.
int16_t DoGetInt16(void) const
Get the m_int16SetGet value.
TracedValue< bool > m_boolSrc
bool Traced value.
TracedValue< int8_t > m_intSrc2
Second int8_t Traced value.
TracedValue< enum Test_e > m_enumSrc
enum Traced value.
bool DoGetTestA(void) const
Get the m_boolTestA value.
Time m_timeWithBounds
Time with bounds.
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 AddToVector2(void)
Add an object to the second vector.
void(* NumericTracedCallback)(double, int, float)
Traced callbacks for (double, int, float) values.
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...
virtual void DoRun(void)
Implementation to actually run this TestCase.
bool CheckGetCodePaths(Ptr< Object > p, std::string attributeName, std::string expectedString, T expectedValue)
Check the attribute path and value.
AttributeTestCase(std::string description)
Constructor.
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.
Callback< void, int8_t > m_cbValue
The callback.
void InvokeCbValue(int8_t a)
Function to invoke the callback.
virtual void DoRun(void)
Implementation to actually run this TestCase.
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(void)
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.
virtual void DoRun(void)
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.
virtual void DoRun(void)
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.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Test case for Object Vector Attributes.
virtual void DoRun(void)
Implementation to actually run this TestCase.
ObjectVectorAttributeTestCase(std::string description)
Constructor.
Smart pointers (Ptr) are central to our architecture, so they must work as attributes.
double m_got2
Value used to verify that source 2 was called.
virtual void DoRun(void)
Implementation to actually run this TestCase.
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.
virtual void DoRun(void)
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.
virtual void DoRun(void)
Implementation to actually run this TestCase.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
AttributeValue implementation for Callback.
Definition: callback.h:1944
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
Hold variables of type enum.
Definition: enum.h:55
Hold a signed integer type.
Definition: integer.h:44
int64_t Get(void) const
Definition: integer.cc:35
bool GetAttributeFailSafe(std::string name, AttributeValue &value) const
Get the value of an attribute without raising erros.
Definition: object-base.cc:329
Instantiate subclasses of ns3::Object.
void Set(const std::string &name, const AttributeValue &value, Args &&... args)
Set an attribute to be set during construction.
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
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:88
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
Container for a set of ns3::Object pointers.
std::size_t GetN(void) const
Get the number of Objects.
Ptr< Object > Get(std::size_t i) const
Get a specific Object.
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Ptr< T > Get(void) const
Definition: pointer.h:201
Hold variables of type string.
Definition: string.h:41
std::string Get(void) const
Definition: string.cc:31
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
AttributeValue implementation for Time.
Definition: nstime.h:1308
a unique identifier for an interface.
Definition: type-id.h:59
TypeId AddConstructor(void)
Record in this TypeId the fact that the default constructor is accessible.
Definition: type-id.h:638
Hold an unsigned integer type.
Definition: uinteger.h:44
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 AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:85
Ptr< const AttributeAccessor > MakeCallbackAccessor(T1 a1)
Definition: callback.h:1982
Ptr< const AttributeChecker > MakeCallbackChecker(void)
Definition: callback.cc:74
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:42
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition: enum.h:205
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Definition: integer.h:45
Ptr< const AttributeAccessor > MakeObjectMapAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-map.h:80
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:81
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1309
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:45
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
bool SetDefaultFailSafe(std::string fullName, const AttributeValue &value)
Definition: config.cc:857
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
#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:141
#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:542
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
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.
ATTRIBUTE_HELPER_HEADER(ValueClassTest)
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139
ATTRIBUTE_HELPER_CPP(Length)
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:162
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:522
bool operator!=(Callback< R, T1, T2, T3, T4, T5, T6, T7, T8, T9 > a, Callback< R, T1, T2, T3, T4, T5, T6, T7, T8, T9 > b)
Inequality test.
Definition: callback.h:1612
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
Ptr< const AttributeChecker > MakeEnumChecker(int v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:162
list x
Random number samples.