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 
38 using namespace ns3;
39 
45 {
46 public:
48 
55  typedef void (* TracedValueCallback)(const ValueClassTest oldValue,
56  const ValueClassTest newValue);
57 
58 private:
59  int m_v;
60 };
61 
62 
63 bool operator != (const ValueClassTest &a, const ValueClassTest &b)
64 {
65  return true;
66 }
67 std::ostream & operator << (std::ostream &os, ValueClassTest v)
68 {
69  return os;
70 }
71 std::istream & operator >> (std::istream &is, ValueClassTest &v)
72 {
73  return is;
74 }
75 
78 
79 class Derived : public Object
80 {
81 public:
82  static TypeId GetTypeId (void) {
83  static TypeId tid = TypeId ("ns3::Derived")
85  .SetParent<Object> ()
86  ;
87  return tid;
88  }
89  Derived () {}
90 };
91 
93 
95 {
96 public:
97  enum Test_e {
100  TEST_C
101  };
102  static TypeId GetTypeId (void) {
103  static TypeId tid = TypeId ("ns3::AttributeObjectTest")
105  .SetParent<Object> ()
106  .HideFromDocumentation ()
107  .AddAttribute ("TestBoolName", "help text",
108  BooleanValue (false),
111  .AddAttribute ("TestBoolA", "help text",
112  BooleanValue (false),
116  .AddAttribute ("TestInt16", "help text",
117  IntegerValue (-2),
119  MakeIntegerChecker<int16_t> ())
120  .AddAttribute ("TestInt16WithBounds", "help text",
121  IntegerValue (-2),
123  MakeIntegerChecker<int16_t> (-5, 10))
124  .AddAttribute ("TestInt16SetGet", "help text",
125  IntegerValue (6),
128  MakeIntegerChecker<int16_t> ())
129  .AddAttribute ("TestUint8", "help text",
130  UintegerValue (1),
132  MakeUintegerChecker<uint8_t> ())
133  .AddAttribute ("TestEnum", "help text",
134  EnumValue (TEST_A),
136  MakeEnumChecker (TEST_A, "TestA",
137  TEST_B, "TestB",
138  TEST_C, "TestC"))
139  .AddAttribute ("TestEnumSetGet", "help text",
140  EnumValue (TEST_B),
143  MakeEnumChecker (TEST_A, "TestA",
144  TEST_B, "TestB",
145  TEST_C, "TestC"))
146  .AddAttribute ("TestRandom", "help text",
147  StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"),
149  MakePointerChecker <RandomVariableStream>())
150  .AddAttribute ("TestFloat", "help text",
151  DoubleValue (-1.1),
153  MakeDoubleChecker<float> ())
154  .AddAttribute ("TestVector1", "help text",
157  MakeObjectVectorChecker<Derived> ())
158  .AddAttribute ("TestVector2", "help text",
162  MakeObjectVectorChecker<Derived> ())
163  .AddAttribute ("TestMap1", "help text",
164  ObjectMapValue (),
166  MakeObjectMapChecker<Derived> ())
167  .AddAttribute ("IntegerTraceSource1", "help text",
168  IntegerValue (-2),
170  MakeIntegerChecker<int8_t> ())
171  .AddAttribute ("IntegerTraceSource2", "help text",
172  IntegerValue (-2),
175  MakeIntegerChecker<int8_t> ())
176  .AddAttribute ("UIntegerTraceSource", "help text",
177  UintegerValue (2),
179  MakeIntegerChecker<uint8_t> ())
180  .AddAttribute ("DoubleTraceSource", "help text",
181  DoubleValue (2),
183  MakeDoubleChecker<double> ())
184  .AddAttribute ("BoolTraceSource", "help text",
185  BooleanValue (false),
188  .AddAttribute ("EnumTraceSource", "help text",
189  EnumValue (false),
191  MakeEnumChecker (TEST_A, "TestA"))
192  .AddAttribute ("ValueClassSource", "help text",
196  .AddTraceSource ("Source1", "help test",
198  "ns3::TracedValueCallback::Int8")
199  .AddTraceSource ("Source2", "help text",
201  "ns3::AttributeObjectTest::NumericTracedCallback")
202  .AddTraceSource ("ValueSource", "help text",
204  "ns3::ValueClassTest::TracedValueCallback")
205  .AddAttribute ("Pointer", "help text",
206  PointerValue (),
208  MakePointerChecker<Derived> ())
209  .AddAttribute ("PointerInitialized", "help text",
210  StringValue("ns3::Derived"),
212  MakePointerChecker<Derived> ())
213  .AddAttribute ("PointerInitialized2", "help text",
214  StringValue("ns3::Derived[]"),
216  MakePointerChecker<Derived> ())
217  .AddAttribute ("Callback", "help text",
218  CallbackValue (),
221  .AddAttribute ("TestTimeWithBounds", "help text",
222  TimeValue (Seconds (-2)),
224  MakeTimeChecker (Seconds (-5), Seconds (10)))
225  ;
226 
227  return tid;
228  }
229 
231  {
232  NS_UNUSED (m_boolTest);
233  NS_UNUSED (m_int16);
234  NS_UNUSED (m_int16WithBounds);
235  NS_UNUSED (m_uint8);
236  NS_UNUSED (m_float);
237  NS_UNUSED (m_enum);
238  NS_UNUSED (m_enumSetGet);
239  }
240 
241  virtual ~AttributeObjectTest (void) {};
242 
243  void AddToVector1 (void) { m_vector1.push_back (CreateObject<Derived> ()); }
244  void AddToVector2 (void) { m_vector2.push_back (CreateObject<Derived> ()); }
245 
246  void AddToMap1 (uint32_t i) { m_map1.insert (std::pair <uint32_t, Ptr<Derived> > (i, CreateObject<Derived> ())); }
247 
248  void InvokeCb (double a, int b, float c) { m_cb (a,b,c); }
249 
250  void InvokeCbValue (int8_t a)
251  {
252  if (!m_cbValue.IsNull ()) {
253  m_cbValue (a);
254  }
255  }
256 
257 private:
258  void DoSetTestB (bool v) { m_boolTestA = v; }
259  bool DoGetTestB (void) const { return m_boolTestA; }
260  int16_t DoGetInt16 (void) const { return m_int16SetGet; }
261  void DoSetInt16 (int16_t v) { m_int16SetGet = v; }
262  uint32_t DoGetVectorN (void) const { return m_vector2.size (); }
263  Ptr<Derived> DoGetVector (uint32_t i) const { return m_vector2[i]; }
264  bool DoSetIntSrc (int8_t v) { m_intSrc2 = v; return true; }
265  int8_t DoGetIntSrc (void) const { return m_intSrc2; }
266  bool DoSetEnum (Test_e v) { m_enumSetGet = v; return true; }
267  Test_e DoGetEnum (void) const { return m_enumSetGet; }
268 
271  int16_t m_int16;
273  int16_t m_int16SetGet;
274  uint8_t m_uint8;
275  float m_float;
276  enum Test_e m_enum;
277  enum Test_e m_enumSetGet;
279  std::vector<Ptr<Derived> > m_vector1;
280  std::vector<Ptr<Derived> > m_vector2;
281  std::map <uint32_t, Ptr<Derived> > m_map1;
285 
286  typedef void (* NumericTracedCallback) (double, int, float);
297 };
298 
300 
301 // ===========================================================================
302 // Test case template used for generic Attribute Value types -- used to make
303 // sure that Attributes work as expected.
304 // ===========================================================================
305 template <typename T>
307 {
308 public:
309  AttributeTestCase (std::string description);
310  virtual ~AttributeTestCase ();
311 
312 private:
313  virtual void DoRun (void);
314 
315  bool CheckGetCodePaths (Ptr<Object> p, std::string attributeName, std::string expectedString, T expectedValue);
316 };
317 
318 template <typename T>
320  : TestCase (description)
321 {
322 }
323 
324 template <typename T>
326 {
327 }
328 
329 template <typename T> bool
331  Ptr<Object> p,
332  std::string attributeName,
333  std::string expectedString,
334  T expectedValue)
335 {
336  StringValue stringValue;
337  T actualValue;
338 
339  //
340  // Get an Attribute value through its StringValue representation.
341  //
342  bool ok1 = p->GetAttributeFailSafe (attributeName.c_str (), stringValue);
343  bool ok2 = stringValue.Get () == expectedString;
344 
345  //
346  // Get the existing boolean value through its particular type representation.
347  //
348  bool ok3 = p->GetAttributeFailSafe (attributeName.c_str (), actualValue);
349  bool ok4 = expectedValue.Get () == actualValue.Get ();
350 
351  return ok1 && ok2 && ok3 && ok4;
352 }
353 
354 // ===========================================================================
355 // The actual Attribute type test cases are specialized for each Attribute type
356 // ===========================================================================
357 template <> void
359 {
361  bool ok;
362 
363  p = CreateObject<AttributeObjectTest> ();
364  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
365 
366  //
367  // Set the default value of the BooleanValue and create an object. The new
368  // default value should stick.
369  //
370  Config::SetDefault ("ns3::AttributeObjectTest::TestBoolName", StringValue ("true"));
371  p = CreateObject<AttributeObjectTest> ();
372  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
373 
374  ok = CheckGetCodePaths (p, "TestBoolName", "true", BooleanValue (true));
375  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by default value");
376 
377  //
378  // Set the default value of the BooleanValue the other way and create an object.
379  // The new default value should stick.
380  //
381  Config::SetDefaultFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("false"));
382 
383  p = CreateObject<AttributeObjectTest> ();
384  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
385 
386  ok = CheckGetCodePaths (p, "TestBoolName", "false", BooleanValue (false));
387  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not et properly by default value");
388 
389  //
390  // Set the BooleanValue Attribute to true via SetAttributeFailSafe path.
391  //
392  ok = p->SetAttributeFailSafe ("TestBoolName", StringValue ("true"));
393  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() \"TestBoolName\" to true");
394 
395  ok = CheckGetCodePaths (p, "TestBoolName", "true", BooleanValue (true));
396  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
397 
398  //
399  // Set the BooleanValue to false via SetAttributeFailSafe path.
400  //
401  ok = p->SetAttributeFailSafe ("TestBoolName", StringValue ("false"));
402  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() \"TestBoolName\" to false");
403 
404  ok = CheckGetCodePaths (p, "TestBoolName", "false", BooleanValue (false));
405  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
406 
407  //
408  // Create an object using
409  //
410  p = CreateObject<AttributeObjectTest> ();
411  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
412 
413  //
414  // The previous object-based tests checked access directly. Now check through
415  // setter and getter. The code here looks the same, but the underlying
416  // attribute is declared differently in the object. First make sure we can set
417  // to true.
418  //
419  ok = p->SetAttributeFailSafe ("TestBoolA", StringValue ("true"));
420  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a boolean value to true");
421 
422  ok = CheckGetCodePaths (p, "TestBoolA", "true", BooleanValue (true));
423  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() (getter/setter) via StringValue");
424 
425  //
426  // Now Set the BooleanValue to false via the setter.
427  //
428  ok = p->SetAttributeFailSafe ("TestBoolA", StringValue ("false"));
429  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a boolean value to false");
430 
431  ok = CheckGetCodePaths (p, "TestBoolA", "false", BooleanValue (false));
432  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() (getter/setter) via StringValue");
433 }
434 
435 template <> void
437 {
439  bool ok;
440 
441  p = CreateObject<AttributeObjectTest> ();
442  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
443 
444  //
445  // When the object is first created, the Attribute should have the default
446  // value.
447  //
448  ok = CheckGetCodePaths (p, "TestInt16", "-2", IntegerValue (-2));
449  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by default value");
450 
451  //
452  // Set the Attribute to a negative value through a StringValue.
453  //
454  ok = p->SetAttributeFailSafe ("TestInt16", StringValue ("-5"));
455  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to -5");
456 
457  ok = CheckGetCodePaths (p, "TestInt16", "-5", IntegerValue (-5));
458  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
459 
460  //
461  // Set the Attribute to a positive value through a StringValue.
462  //
463  ok = p->SetAttributeFailSafe ("TestInt16", StringValue ("+2"));
464  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to +2");
465 
466  ok = CheckGetCodePaths (p, "TestInt16", "2", IntegerValue (2));
467  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
468 
469  //
470  // Set the Attribute to the most negative value of the signed 16-bit range.
471  //
472  ok = p->SetAttributeFailSafe ("TestInt16", StringValue ("-32768"));
473  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to -32768");
474 
475  ok = CheckGetCodePaths (p, "TestInt16", "-32768", IntegerValue (-32768));
476  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() (most negative) via StringValue");
477 
478  //
479  // Try to set the Attribute past the most negative value of the signed 16-bit
480  // range and make sure the underlying attribute is unchanged.
481  //
482  ok = p->SetAttributeFailSafe ("TestInt16", StringValue ("-32769"));
483  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via StringValue to -32769");
484 
485  ok = CheckGetCodePaths (p, "TestInt16", "-32768", IntegerValue (-32768));
486  NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
487 
488  //
489  // Set the Attribute to the most positive value of the signed 16-bit range.
490  //
491  ok = p->SetAttributeFailSafe ("TestInt16", StringValue ("32767"));
492  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to 32767");
493 
494  ok = CheckGetCodePaths (p, "TestInt16", "32767", IntegerValue (32767));
495  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() (most positive) via StringValue");
496 
497  //
498  // Try to set the Attribute past the most positive value of the signed 16-bit
499  // range and make sure the underlying attribute is unchanged.
500  //
501  ok = p->SetAttributeFailSafe ("TestInt16", StringValue ("32768"));
502  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via StringValue to 32768");
503 
504  ok = CheckGetCodePaths (p, "TestInt16", "32767", IntegerValue (32767));
505  NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
506 
507  //
508  // Attributes can have limits other than the intrinsic limits of the
509  // underlying data types. These limits are specified in the Object.
510  //
511  ok = p->SetAttributeFailSafe ("TestInt16WithBounds", IntegerValue (10));
512  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 10");
513 
514  ok = CheckGetCodePaths (p, "TestInt16WithBounds", "10", IntegerValue (10));
515  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() (positive limit) via StringValue");
516 
517  //
518  // Set the Attribute past the positive limit.
519  //
520  ok = p->SetAttributeFailSafe ("TestInt16WithBounds", IntegerValue (11));
521  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 11");
522 
523  ok = CheckGetCodePaths (p, "TestInt16WithBounds", "10", IntegerValue (10));
524  NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
525 
526  //
527  // Set the Attribute at the negative limit.
528  //
529  ok = p->SetAttributeFailSafe ("TestInt16WithBounds", IntegerValue (-5));
530  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -5");
531 
532  ok = CheckGetCodePaths (p, "TestInt16WithBounds", "-5", IntegerValue (-5));
533  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() (negative limit) via StringValue");
534 
535  //
536  // Set the Attribute past the negative limit.
537  //
538  ok = p->SetAttributeFailSafe ("TestInt16WithBounds", IntegerValue (-6));
539  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -6");
540 
541  ok = CheckGetCodePaths (p, "TestInt16WithBounds", "-5", IntegerValue (-5));
542  NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
543 }
544 
545 template <> void
547 {
549  bool ok;
550 
551  p = CreateObject<AttributeObjectTest> ();
552  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
553 
554  //
555  // When the object is first created, the Attribute should have the default
556  // value.
557  //
558  ok = CheckGetCodePaths (p, "TestUint8", "1", UintegerValue (1));
559  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by default value");;
560 
561  //
562  // Set the Attribute to zero.
563  //
564  ok = p->SetAttributeFailSafe ("TestUint8", UintegerValue (0));
565  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to 0");
566 
567  ok = CheckGetCodePaths (p, "TestUint8", "0", UintegerValue (0));
568  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
569 
570  //
571  // Set the Attribute to the most positive value of the unsigned 8-bit range.
572  //
573  ok = p->SetAttributeFailSafe ("TestUint8", UintegerValue (255));
574  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to 255");
575 
576  ok = CheckGetCodePaths (p, "TestUint8", "255", UintegerValue (255));
577  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() (positive limit) via UintegerValue");
578 
579  //
580  // Try and set the Attribute past the most positive value of the unsigned
581  // 8-bit range.
582  //
583  ok = p->SetAttributeFailSafe ("TestUint8", UintegerValue (256));
584  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() to 256");
585 
586  ok = CheckGetCodePaths (p, "TestUint8", "255", UintegerValue (255));
587  NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
588 
589  //
590  // Set the Attribute to the most positive value of the unsigned 8-bit range
591  // through a StringValue.
592  //
593  ok = p->SetAttributeFailSafe ("TestUint8", StringValue ("255"));
594  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to 255");
595 
596  ok = CheckGetCodePaths (p, "TestUint8", "255", UintegerValue (255));
597  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
598 
599  //
600  // Try and set the Attribute past the most positive value of the unsigned
601  // 8-bit range through a StringValue.
602  //
603  ok = p->SetAttributeFailSafe ("TestUint8", StringValue ("256"));
604  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via StringValue to 256");
605 
606  ok = CheckGetCodePaths (p, "TestUint8", "255", UintegerValue (255));
607  NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
608 
609  //
610  // Try to set the Attribute to a negative StringValue.
611  //
612  ok = p->SetAttributeFailSafe ("TestUint8", StringValue ("-1"));
613  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via StringValue to -1");
614 }
615 
616 template <> void
618 {
620  bool ok;
621 
622  p = CreateObject<AttributeObjectTest> ();
623  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
624 
625  //
626  // When the object is first created, the Attribute should have the default
627  // value.
628  //
629  ok = CheckGetCodePaths (p, "TestFloat", "-1.1", DoubleValue ((float)-1.1));
630  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by default value");
631 
632  //
633  // Set the Attribute.
634  //
635  ok = p->SetAttributeFailSafe ("TestFloat", DoubleValue ((float)2.3));
636  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to 2.3");
637 
638  ok = CheckGetCodePaths (p, "TestFloat", "2.3", DoubleValue ((float)2.3));
639  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via DoubleValue");
640 }
641 
642 template <> void
644 {
646  bool ok;
647 
648  p = CreateObject<AttributeObjectTest> ();
649  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
650 
651  //
652  // When the object is first created, the Attribute should have the default
653  // value.
654  //
655  ok = CheckGetCodePaths (p, "TestEnum", "TestA", EnumValue (AttributeObjectTest::TEST_A));
656  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by default value");
657 
658  //
659  // Set the Attribute using the EnumValue type.
660  //
662  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to TEST_C");
663 
664  ok = CheckGetCodePaths (p, "TestEnum", "TestC", EnumValue (AttributeObjectTest::TEST_C));
665  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via EnumValue");
666 
667  //
668  // When the object is first created, the Attribute should have the default
669  // value.
670  //
671  ok = CheckGetCodePaths (p, "TestEnumSetGet", "TestB", EnumValue (AttributeObjectTest::TEST_B));
672  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by default value");
673 
674  //
675  // Set the Attribute using the EnumValue type.
676  //
677  ok = p->SetAttributeFailSafe ("TestEnumSetGet", EnumValue (AttributeObjectTest::TEST_C));
678  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to TEST_C");
679 
680  ok = CheckGetCodePaths (p, "TestEnumSetGet", "TestC", EnumValue (AttributeObjectTest::TEST_C));
681  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via EnumValue");
682 
683  //
684  // Set the Attribute using the StringValue type.
685  //
686  ok = p->SetAttributeFailSafe ("TestEnum", StringValue ("TestB"));
687  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to TEST_B");
688 
689  ok = CheckGetCodePaths (p, "TestEnum", "TestB", EnumValue (AttributeObjectTest::TEST_B));
690  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
691 
692  //
693  // Try to set the Attribute to a bogus enum using the StringValue type and
694  // make sure the underlying value doesn't change.
695  //
696  ok = p->SetAttributeFailSafe ("TestEnum", StringValue ("TestD"));
697  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() to TEST_D"); //
698 
699  ok = CheckGetCodePaths (p, "TestEnum", "TestB", EnumValue (AttributeObjectTest::TEST_B));
700  NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
701 
702  //
703  // Try to set the Attribute to a bogus enum using an integer implicit conversion
704  // and make sure the underlying value doesn't change.
705  //
706  ok = p->SetAttributeFailSafe ("TestEnum", EnumValue (5));
707  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() to 5");
708 
709  ok = CheckGetCodePaths (p, "TestEnum", "TestB", EnumValue (AttributeObjectTest::TEST_B));
710  NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
711 }
712 
713 template <> void
715 {
717  bool ok;
718 
719  p = CreateObject<AttributeObjectTest> ();
720  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
721 
722  // The test vectors assume ns resolution
723  Time::SetResolution (Time::NS);
724 
725  //
726  // Set value
727  //
728  ok = p->SetAttributeFailSafe ("TestTimeWithBounds", TimeValue (Seconds (5)));
729  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via TimeValue to 5s");
730 
731  ok = CheckGetCodePaths (p, "TestTimeWithBounds", "+5000000000.0ns", TimeValue (Seconds (5)));
732  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe(5s) via TimeValue");
733 
734  ok = p->SetAttributeFailSafe ("TestTimeWithBounds", StringValue ("3s"));
735  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via TimeValue to 3s");
736 
737  ok = CheckGetCodePaths (p, "TestTimeWithBounds", "+3000000000.0ns", TimeValue (Seconds (3)));
738  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe(3s) via StringValue");
739 
740 
741  //
742  // Attributes can have limits other than the intrinsic limits of the
743  // underlying data types. These limits are specified in the Object.
744  //
745 
746  //
747  // Set the Attribute at the positive limit
748  //
749  ok = p->SetAttributeFailSafe ("TestTimeWithBounds", TimeValue (Seconds (10)));
750  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via TimeValue to 10s");
751 
752  ok = CheckGetCodePaths (p, "TestTimeWithBounds", "+10000000000.0ns", TimeValue (Seconds (10)));
753  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe(10s [positive limit]) via StringValue");
754 
755  //
756  // Set the Attribute past the positive limit.
757  //
758  ok = p->SetAttributeFailSafe ("TestTimeWithBounds", TimeValue (Seconds (11)));
759  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via TimeValue to 11s [greater than positive limit]");
760 
761  ok = CheckGetCodePaths (p, "TestTimeWithBounds", "+10000000000.0ns", TimeValue (Seconds (10)));
762  NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
763 
764  //
765  // Set the Attribute at the negative limit.
766  //
767  ok = p->SetAttributeFailSafe ("TestTimeWithBounds", TimeValue (Seconds (-5)));
768  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via TimeValue to -5s");
769 
770  ok = CheckGetCodePaths (p, "TestTimeWithBounds", "-5000000000.0ns", TimeValue (Seconds (-5)));
771  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe(-5s [negative limit]) via StringValue");
772 
773  //
774  // Set the Attribute past the negative limit.
775  //
776  ok = p->SetAttributeFailSafe ("TestTimeWithBounds", TimeValue (Seconds (-6)));
777  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via TimeValue to -6s");
778 
779  ok = CheckGetCodePaths (p, "TestTimeWithBounds", "-5000000000.0ns", TimeValue (Seconds (-5)));
780  NS_TEST_ASSERT_MSG_EQ (ok, true, "Error in SetAttributeFailSafe() but value changes");
781 }
782 
783 // ===========================================================================
784 // Test the Attributes of type RandomVariableStream.
785 // ===========================================================================
787 {
788 public:
789  RandomVariableStreamAttributeTestCase (std::string description);
791 
792  void InvokeCbValue (int8_t a)
793  {
794  if (!m_cbValue.IsNull ()) {
795  m_cbValue (a);
796  }
797  }
798 
799 private:
800  virtual void DoRun (void);
801 
803 
804  void NotifyCallbackValue (int8_t a) { m_gotCbValue = a; }
805 
806  int16_t m_gotCbValue;
807 };
808 
810  : TestCase (description)
811 {
812 }
813 
814 void
816 {
818  bool ok;
819 
820  p = CreateObject<AttributeObjectTest> ();
821  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
822 
823  //
824  // Try to set a UniformRandomVariable
825  //
826  ok = p->SetAttributeFailSafe ("TestRandom", StringValue ("ns3::UniformRandomVariable[Min=0.,Max=1.]"));
827  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a UniformRandomVariable");
828 
829  //
830  // Try to set a <snicker> ConstantRandomVariable
831  //
832  // ok = p->SetAttributeFailSafe ("TestRandom", StringValue ("ns3::ConstantRandomVariable[Constant=10.0]"));
833  //ok = p->SetAttributeFailSafe ("TestRandom", StringValue ("ns3::UniformRandomVariable[Min=0.,Max=1.]"));
834 
835  ok = p->SetAttributeFailSafe ("TestRandom", StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"));
836 
837  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a ConstantRandomVariable");
838 }
839 
840 // ===========================================================================
841 // Test case for Object Vector Attributes. Generic nature is pretty much lost
842 // here, so we just break the class out.
843 // ===========================================================================
845 {
846 public:
847  ObjectVectorAttributeTestCase (std::string description);
849 
850 private:
851  virtual void DoRun (void);
852 };
853 
855  : TestCase (description)
856 {
857 }
858 
859 void
861 {
863  ObjectVectorValue vector;
864 
865  p = CreateObject<AttributeObjectTest> ();
866  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
867 
868  //
869  // When the object is first created, the Attribute should have no items in
870  // the vector.
871  //
872  p->GetAttribute ("TestVector1", vector);
873  NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 0, "Initial count of ObjectVectorValue \"TestVector1\" should be zero");
874 
875  //
876  // Adding to the attribute shouldn't affect the value we already have.
877  //
878  p->AddToVector1 ();
879  NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 0, "Initial count of ObjectVectorValue \"TestVector1\" should still be zero");
880 
881  //
882  // Getting the attribute again should update the value.
883  //
884  p->GetAttribute ("TestVector1", vector);
885  NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 1, "ObjectVectorValue \"TestVector1\" should be incremented");
886 
887  //
888  // Get the Object pointer from the value.
889  //
890  Ptr<Object> a = vector.Get (0);
891  NS_TEST_ASSERT_MSG_NE (a, 0, "Ptr<Object> from VectorValue \"TestVector1\" is zero");
892 
893  //
894  // Adding to the attribute shouldn't affect the value we already have.
895  //
896  p->AddToVector1 ();
897  NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 1, "Count of ObjectVectorValue \"TestVector1\" should still be one");
898 
899  //
900  // Getting the attribute again should update the value.
901  //
902  p->GetAttribute ("TestVector1", vector);
903  NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 2, "ObjectVectorValue \"TestVector1\" should be incremented");
904 }
905 
906 // ===========================================================================
907 // Test case for Object Map Attributes.
908 // ===========================================================================
910 {
911 public:
912  ObjectMapAttributeTestCase (std::string description);
914 
915 private:
916  virtual void DoRun (void);
917 };
918 
920  : TestCase (description)
921 {
922 }
923 
924 void
926 {
928  ObjectMapValue map;
929 
930  p = CreateObject<AttributeObjectTest> ();
931  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
932 
933  //
934  // When the object is first created, the Attribute should have no items in
935  // the vector.
936  //
937  p->GetAttribute ("TestMap1", map);
938  NS_TEST_ASSERT_MSG_EQ (map.GetN (), 0, "Initial count of ObjectVectorValue \"TestMap1\" should be zero");
939 
940  //
941  // Adding to the attribute shouldn't affect the value we already have.
942  //
943  p->AddToMap1 (1);
944  NS_TEST_ASSERT_MSG_EQ (map.GetN (), 0, "Initial count of ObjectVectorValue \"TestMap1\" should still be zero");
945 
946  //
947  // Getting the attribute again should update the value.
948  //
949  p->GetAttribute ("TestMap1", map);
950  NS_TEST_ASSERT_MSG_EQ (map.GetN (), 1, "ObjectVectorValue \"TestMap1\" should be incremented");
951 
952  //
953  // Get the Object pointer from the value.
954  //
955  Ptr<Object> a = map.Get (1);
956  NS_TEST_ASSERT_MSG_NE (a, 0, "Ptr<Object> from VectorValue \"TestMap1\" is zero");
957 
958  //
959  // Adding to the attribute shouldn't affect the value we already have.
960  //
961  p->AddToMap1 (2);
962  NS_TEST_ASSERT_MSG_EQ (map.GetN (), 1, "Count of ObjectVectorValue \"TestMap1\" should still be one");
963 
964  //
965  // Getting the attribute again should update the value.
966  //
967  p->GetAttribute ("TestMap1", map);
968  NS_TEST_ASSERT_MSG_EQ (map.GetN (), 2, "ObjectVectorValue \"TestMap1\" should be incremented");
969 }
970 
971 // ===========================================================================
972 // Trace sources with value semantics can be used like Attributes. Make sure
973 // we can use them that way.
974 // ===========================================================================
976 {
977 public:
978  IntegerTraceSourceAttributeTestCase (std::string description);
980 
981 private:
982  virtual void DoRun (void);
983 };
984 
986  : TestCase (description)
987 {
988 }
989 
990 void
992 {
994  IntegerValue iv;
995  bool ok;
996 
997  p = CreateObject<AttributeObjectTest> ();
998  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
999 
1000  //
1001  // When the object is first created, the Attribute should have the default
1002  // value.
1003  //
1004  p->GetAttribute ("IntegerTraceSource1", iv);
1005  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -2, "Attribute not set properly by default value");
1006 
1007  //
1008  // Set the Attribute to a positive value through an IntegerValue.
1009  //
1010  ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (5));
1011  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 5");
1012 
1013  p->GetAttribute ("IntegerTraceSource1", iv);
1014  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 5, "Attribute not set properly by SetAttributeFailSafe() via IntegerValue");
1015 
1016  //
1017  // Limits should work.
1018  //
1019  ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (127));
1020  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 127");
1021 
1022  ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (128));
1023  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 128");
1024 
1025  ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (-128));
1026  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -128");
1027 
1028  ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (-129));
1029  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -129");
1030 
1031  //
1032  // When the object is first created, the Attribute should have the default
1033  // value.
1034  //
1035  p->GetAttribute ("IntegerTraceSource2", iv);
1036  NS_TEST_ASSERT_MSG_EQ (iv.Get (), -2, "Attribute not set properly by default value");
1037 
1038  //
1039  // Set the Attribute to a positive value through an IntegerValue.
1040  //
1041  ok = p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (5));
1042  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 5");
1043 
1044  p->GetAttribute ("IntegerTraceSource2", iv);
1045  NS_TEST_ASSERT_MSG_EQ (iv.Get (), 5, "Attribute not set properly by SetAttributeFailSafe() via IntegerValue");
1046 
1047  //
1048  // Limits should work.
1049  //
1050  ok = p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (127));
1051  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 127");
1052 
1053  ok = p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (128));
1054  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 128");
1055 
1056  ok = p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (-128));
1057  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -128");
1058 
1059  ok = p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (-129));
1060  NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -129");
1061 }
1062 
1063 // ===========================================================================
1064 // Trace sources used like Attributes must also work as trace sources. Make
1065 // sure we can use them that way.
1066 // ===========================================================================
1068 {
1069 public:
1070  IntegerTraceSourceTestCase (std::string description);
1072 
1073 private:
1074  virtual void DoRun (void);
1075 
1076  void NotifySource1 (int8_t old, int8_t n) { m_got1 = n; }
1077  int64_t m_got1;
1078 };
1079 
1081  : TestCase (description)
1082 {
1083 }
1084 
1085 void
1087 {
1089  bool ok;
1090 
1091  p = CreateObject<AttributeObjectTest> ();
1092  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
1093 
1094  //
1095  // Check to make sure changing an Attibute value triggers a trace callback
1096  // that sets a member variable.
1097  //
1098  m_got1 = 1234;
1099 
1100  ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (-1));
1101  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -1");
1102 
1103  //
1104  // Source1 is declared as a TraceSourceAccessor to m_intSrc1. This m_intSrc1
1105  // is also declared as an Integer Attribute. We just checked to make sure we
1106  // could set it using an IntegerValue through its IntegerTraceSource1 "persona."
1107  // We should also be able to hook a trace source to the underlying variable.
1108  //
1110  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not TraceConnectWithoutContext() \"Source1\" to NodifySource1()");
1111 
1112  //
1113  // When we set the IntegerValue that now underlies both the Integer Attribute
1114  // and the trace source, the trace should fire and call NotifySource1 which
1115  // will set m_got1 to the new value.
1116  //
1117  ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (0));
1118  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 0");
1119 
1120  NS_TEST_ASSERT_MSG_EQ (m_got1, 0, "Hitting a TracedValue does not cause trace callback to be called");
1121 
1122  //
1123  // Now disconnect from the trace source and ensure that the trace callback
1124  // is not called if the trace source is hit.
1125  //
1127  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not TraceConnectWithoutContext() \"Source1\" to NodifySource1()");
1128 
1129  ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (1));
1130  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 1");
1131 
1132  NS_TEST_ASSERT_MSG_EQ (m_got1, 0, "Hitting a TracedValue after disconnect still causes callback");
1133 }
1134 
1135 // ===========================================================================
1136 // Trace sources used like Attributes must also work as trace sources. Make
1137 // sure we can use them that way.
1138 // ===========================================================================
1140 {
1141 public:
1142  TracedCallbackTestCase (std::string description);
1144 
1145 private:
1146  virtual void DoRun (void);
1147 
1148  void NotifySource2 (double a, int b, float c) { m_got2 = a; }
1149 
1150  double m_got2;
1151 };
1152 
1154  : TestCase (description)
1155 {
1156 }
1157 
1158 void
1160 {
1162  bool ok;
1163 
1164  p = CreateObject<AttributeObjectTest> ();
1165  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
1166 
1167  //
1168  // Initialize the
1169  //
1170  m_got2 = 4.3;
1171 
1172  //
1173  // Invoke the callback that lies at the heart of this test. We have a
1174  // method InvokeCb() that just executes m_cb(). The variable m_cb is
1175  // declared as a TracedCallback<double, int, float>. This kind of beast
1176  // is like a callback but can call a list of targets. This list should
1177  // be empty so nothing should happen now. Specifically, m_got2 shouldn't
1178  // have changed.
1179  //
1180  p->InvokeCb (1.0, -5, 0.0);
1181  NS_TEST_ASSERT_MSG_EQ (m_got2, 4.3, "Invoking a newly created TracedCallback results in an unexpected callback");
1182 
1183  //
1184  // Now, wire the TracedCallback up to a trace sink. This sink will just set
1185  // m_got2 to the first argument.
1186  //
1188  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not TraceConnectWithoutContext() to NotifySource2");
1189 
1190  //
1191  // Now if we invoke the callback, the trace source should fire and m_got2
1192  // should be set in the trace sink.
1193  //
1194  p->InvokeCb (1.0, -5, 0.0);
1195  NS_TEST_ASSERT_MSG_EQ (m_got2, 1.0, "Invoking TracedCallback does not result in trace callback");
1196 
1197  //
1198  // Now, disconnect the trace sink and see what happens when we invoke the
1199  // callback again. Of course, the trace should not happen and m_got2
1200  // should remain unchanged.
1201  //
1203  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not TraceDisconnectWithoutContext() from NotifySource2");
1204 
1205  p->InvokeCb (-1.0, -5, 0.0);
1206  NS_TEST_ASSERT_MSG_EQ (m_got2, 1.0, "Invoking disconnected TracedCallback unexpectedly results in trace callback");
1207 }
1208 
1209 // ===========================================================================
1210 // Smart pointers (Ptr) are central to our architecture, so they must work as
1211 // attributes.
1212 // ===========================================================================
1214 {
1215 public:
1216  PointerAttributeTestCase (std::string description);
1218 
1219 private:
1220  virtual void DoRun (void);
1221 
1222  void NotifySource2 (double a, int b, float c) { m_got2 = a; }
1223 
1224  double m_got2;
1225 };
1226 
1228  : TestCase (description)
1229 {
1230 }
1231 
1232 void
1234 {
1236  bool ok;
1237 
1238  p = CreateObject<AttributeObjectTest> ();
1239  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
1240 
1241  //
1242  // We have declared a PointerValue Attribute named "Pointer" with a pointer
1243  // checker of type Derived. This means that we should be able to pull out
1244  // a Ptr<Derived> with the initial value (which is 0).
1245  //
1246  PointerValue ptr;
1247  p->GetAttribute ("Pointer", ptr);
1248  Ptr<Derived> derived = ptr.Get<Derived> ();
1249  NS_TEST_ASSERT_MSG_EQ (derived, 0, "Unexpectedly found non-null pointer in newly initialized PointerValue Attribute");
1250 
1251  //
1252  // Now, lets create an Object of type Derived and set the local Ptr to point
1253  // to that object. We can then set the PointerValue Attribute to that Ptr.
1254  //
1255  derived = Create<Derived> ();
1256  ok = p->SetAttributeFailSafe ("Pointer", PointerValue (derived));
1257  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a PointerValue of the correct type");
1258 
1259  //
1260  // Pull the value back out of the Attribute and make sure it points to the
1261  // correct object.
1262  //
1263  p->GetAttribute ("Pointer", ptr);
1264  Ptr<Derived> stored = ptr.Get<Derived> ();
1265  NS_TEST_ASSERT_MSG_EQ (stored, derived, "Retreived Attribute does not match stored PointerValue");
1266 
1267  //
1268  // We should be able to use the Attribute Get() just like GetObject<type>,
1269  // So see if we can get a Ptr<Object> out of the Ptr<Derived> we stored.
1270  // This should be a pointer to the same physical memory since its the
1271  // same object.
1272  //
1273  p->GetAttribute ("Pointer", ptr);
1274  Ptr<Object> storedBase = ptr.Get<Object> ();
1275  NS_TEST_ASSERT_MSG_EQ (storedBase, stored, "Retreived Ptr<Object> does not match stored Ptr<Derived>");
1276 
1277  //
1278  // If we try to Get() something that is unrelated to what we stored, we should
1279  // retrieve a 0.
1280  //
1281  p->GetAttribute ("Pointer", ptr);
1283  NS_TEST_ASSERT_MSG_EQ (x, 0, "Unexpectedly retreived unrelated Ptr<type> from stored Ptr<Derived>");
1284 
1285  //
1286  // Test whether the initialized pointers from two different objects
1287  // point to different Derived objects
1288  //
1289  p->GetAttribute ("PointerInitialized", ptr);
1290  Ptr<Derived> storedPtr = ptr.Get<Derived> ();
1291  Ptr<AttributeObjectTest> p2 = CreateObject<AttributeObjectTest> ();
1292  PointerValue ptr2;
1293  p2->GetAttribute ("PointerInitialized", ptr2);
1294  Ptr<Derived> storedPtr2 = ptr2.Get<Derived> ();
1295  NS_TEST_ASSERT_MSG_NE (storedPtr, storedPtr2, "ptr and ptr2 both have PointerInitialized pointing to the same object");
1296  PointerValue ptr3;
1297  p2->GetAttribute ("PointerInitialized", ptr3);
1298  Ptr<Derived> storedPtr3 = ptr3.Get<Derived> ();
1299  NS_TEST_ASSERT_MSG_NE (storedPtr, storedPtr3, "ptr and ptr3 both have PointerInitialized pointing to the same object");
1300 
1301  //
1302  // Test whether object factory creates the objects properly
1303  //
1304  ObjectFactory factory;
1305  factory.SetTypeId ("ns3::AttributeObjectTest");
1306  factory.Set ("PointerInitialized", StringValue ("ns3::Derived"));
1308  NS_TEST_ASSERT_MSG_NE (aotPtr, 0, "Unable to factory.Create() a AttributeObjectTest");
1310  NS_TEST_ASSERT_MSG_NE (aotPtr2, 0, "Unable to factory.Create() a AttributeObjectTest");
1311  NS_TEST_ASSERT_MSG_NE (aotPtr, aotPtr2, "factory object not creating unique objects");
1312  PointerValue ptr4;
1313  aotPtr->GetAttribute ("PointerInitialized", ptr4);
1314  Ptr<Derived> storedPtr4 = ptr4.Get<Derived> ();
1315  PointerValue ptr5;
1316  aotPtr2->GetAttribute ("PointerInitialized", ptr5);
1317  Ptr<Derived> storedPtr5 = ptr5.Get<Derived> ();
1318  NS_TEST_ASSERT_MSG_NE (storedPtr4, storedPtr5, "aotPtr and aotPtr2 are unique, but their Derived member is not");
1319 }
1320 
1321 // ===========================================================================
1322 // Test the Attributes of type CallbackValue.
1323 // ===========================================================================
1325 {
1326 public:
1327  CallbackValueTestCase (std::string description);
1329 
1330  void InvokeCbValue (int8_t a)
1331  {
1332  if (!m_cbValue.IsNull ()) {
1333  m_cbValue (a);
1334  }
1335  }
1336 
1337 private:
1338  virtual void DoRun (void);
1339 
1341 
1342  void NotifyCallbackValue (int8_t a) { m_gotCbValue = a; }
1343 
1344  int16_t m_gotCbValue;
1345 };
1346 
1348  : TestCase (description)
1349 {
1350 }
1351 
1352 void
1354 {
1356  bool ok;
1357 
1358  p = CreateObject<AttributeObjectTest> ();
1359  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
1360 
1361  //
1362  // The member variable m_cbValue is declared as a Callback<void, int8_t>. The
1363  // Attibute named "Callback" also points to m_cbValue and allows us to set the
1364  // callback using that Attribute.
1365  //
1366  // NotifyCallbackValue is going to be the target of the callback and will just set
1367  // m_gotCbValue to its single parameter. This will be the parameter from the
1368  // callback invocation. The method InvokeCbValue() just invokes the m_cbValue
1369  // callback if it is non-null.
1370  //
1371  m_gotCbValue = 1;
1372 
1373  //
1374  // If we invoke the callback (which has not been set) nothing should happen.
1375  // Further, nothing should happen when we initialize the callback (it shouldn't
1376  // accidentally fire).
1377  //
1378  p->InvokeCbValue (2);
1380 
1381  NS_TEST_ASSERT_MSG_EQ (m_gotCbValue, 1, "Callback unexpectedly fired");
1382 
1383  ok = p->SetAttributeFailSafe ("Callback", cbValue);
1384  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a CallbackValue");
1385 
1386  //
1387  // Now that the callback has been set, invoking it should set m_gotCbValue.
1388  //
1389  p->InvokeCbValue (2);
1390  NS_TEST_ASSERT_MSG_EQ (m_gotCbValue, 2, "Callback Attribute set by CallbackValue did not fire");
1391 
1392  ok = p->SetAttributeFailSafe ("Callback", CallbackValue (MakeNullCallback<void,int8_t> ()));
1393  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a null CallbackValue");
1394 
1395  //
1396  // If the callback has been set to a null callback, it should no longer fire.
1397  //
1398  p->InvokeCbValue (3);
1399  NS_TEST_ASSERT_MSG_EQ (m_gotCbValue, 2, "Callback Attribute set to null callback unexpectedly fired");
1400 }
1401 
1402 // ===========================================================================
1403 // The Test Suite that glues all of the Test Cases together.
1404 // ===========================================================================
1406 {
1407 public:
1409 };
1410 
1412  : TestSuite ("attributes", UNIT)
1413 {
1414  AddTestCase (new AttributeTestCase<BooleanValue> ("Check Attributes of type BooleanValue"), TestCase::QUICK);
1415  AddTestCase (new AttributeTestCase<IntegerValue> ("Check Attributes of type IntegerValue"), TestCase::QUICK);
1416  AddTestCase (new AttributeTestCase<UintegerValue> ("Check Attributes of type UintegerValue"), TestCase::QUICK);
1417  AddTestCase (new AttributeTestCase<DoubleValue> ("Check Attributes of type DoubleValue"), TestCase::QUICK);
1418  AddTestCase (new AttributeTestCase<EnumValue> ("Check Attributes of type EnumValue"), TestCase::QUICK);
1419  AddTestCase (new AttributeTestCase<TimeValue> ("Check Attributes of type TimeValue"), TestCase::QUICK);
1420  AddTestCase (new RandomVariableStreamAttributeTestCase ("Check Attributes of type RandomVariableStream"), TestCase::QUICK);
1421  AddTestCase (new ObjectVectorAttributeTestCase ("Check Attributes of type ObjectVectorValue"), TestCase::QUICK);
1422  AddTestCase (new ObjectMapAttributeTestCase ("Check Attributes of type ObjectMapValue"), TestCase::QUICK);
1423  AddTestCase (new PointerAttributeTestCase ("Check Attributes of type PointerValue"), TestCase::QUICK);
1424  AddTestCase (new CallbackValueTestCase ("Check Attributes of type CallbackValue"), TestCase::QUICK);
1425  AddTestCase (new IntegerTraceSourceAttributeTestCase ("Ensure TracedValue<uint8_t> can be set like IntegerValue"), TestCase::QUICK);
1426  AddTestCase (new IntegerTraceSourceTestCase ("Ensure TracedValue<uint8_t> also works as trace source"), TestCase::QUICK);
1427  AddTestCase (new TracedCallbackTestCase ("Ensure TracedCallback<double, int, float> works as trace source"), TestCase::QUICK);
1428 }
1429 
TracedValue< enum Test_e > m_enumSrc
std::istream & operator>>(std::istream &is, Angles &a)
initialize a struct Angles from input
Definition: angles.cc:48
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Ptr< T > Get(void) const
Definition: pointer.h:194
bool SetDefaultFailSafe(std::string fullName, const AttributeValue &value)
Definition: config.cc:782
std::string Get(void) const
Definition: string.cc:31
Ptr< Derived > m_ptrInitialized2
Ptr< const AttributeAccessor > MakeValueClassTestAccessor(T1 a1)
TypeId AddConstructor(void)
Record in this TypeId the fact that the default constructor is accessible.
Definition: type-id.h:592
AttributeValue implementation for Boolean.
Definition: boolean.h:34
TracedValue< uint8_t > m_uintSrc
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
bool CheckGetCodePaths(Ptr< Object > p, std::string attributeName, std::string expectedString, T expectedValue)
virtual ~AttributeObjectTest(void)
Ptr< Derived > m_ptrInitialized
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:455
Hold variables of type string.
Definition: string.h:41
Ptr< Derived > DoGetVector(uint32_t i) const
virtual void DoRun(void)
Implementation to actually run this TestCase.
void NotifySource2(double a, int b, float c)
#define ATTRIBUTE_HELPER_CPP(type)
Define the attribute value, accessor and checkers for class type.
virtual void DoRun(void)
Implementation to actually run this TestCase.
A suite of tests to run.
Definition: test.h:1333
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: enum.h:209
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:81
std::vector< Ptr< Derived > > m_vector2
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1258
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:81
Hold a signed integer type.
Definition: integer.h:44
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
#define NS_UNUSED(x)
Mark a local variable as unused.
Definition: unused.h:36
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors.
Definition: object-base.cc:211
bool DoGetTestB(void) const
Callback< void, int8_t > m_cbValue
ObjectMapAttributeTestCase(std::string description)
RandomVariableStreamAttributeTestCase(std::string description)
std::map< uint32_t, Ptr< Derived > > m_map1
encapsulates test code
Definition: test.h:1147
bool GetAttributeFailSafe(std::string name, AttributeValue &value) const
Get the value of an attribute without raising erros.
Definition: object-base.cc:264
IntegerTraceSourceAttributeTestCase(std::string description)
AttributeValue implementation for Callback.
Definition: callback.h:1871
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: integer.h:45
int64_t Get(void) const
Definition: integer.cc:35
virtual void DoRun(void)
Implementation to actually run this TestCase.
std::vector< Ptr< Derived > > m_vector1
AttributeValue implementation for ValueClassTest.
Ptr< Object > Get(uint32_t i) const
Get a specific Object.
TracedCallbackTestCase(std::string description)
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: pointer.h:220
Hold variables of type enum.
Definition: enum.h:54
TracedValue< int8_t > m_intSrc2
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:297
AttributeValue implementation for Time.
Definition: nstime.h:957
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
int16_t DoGetInt16(void) const
Hold an unsigned integer type.
Definition: uinteger.h:44
void NotifySource2(double a, int b, float c)
virtual void DoRun(void)
Implementation to actually run this TestCase.
#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:161
IntegerTraceSourceTestCase(std::string description)
Ptr< const AttributeAccessor > MakeCallbackAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: callback.h:1913
virtual void DoRun(void)
Implementation to actually run this TestCase.
void NotifySource1(int8_t old, int8_t n)
bool TraceDisconnectWithoutContext(std::string name, const CallbackBase &cb)
Disconnect from a TraceSource a Callback previously connected without a context.
Definition: object-base.cc:325
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1480
TracedValue< int8_t > m_intSrc1
void AddToMap1(uint32_t i)
TracedCallback< double, int, float > m_cb
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:299
TracedValue< ValueClassTest > m_valueSrc
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:1462
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Hold objects of type Ptr.
Definition: pointer.h:36
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
ObjectVectorAttributeTestCase(std::string description)
virtual void DoRun(void)
Implementation to actually run this TestCase.
void Set(std::string name, const AttributeValue &value)
Set an attribute to be set during construction.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:958
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:229
static AttributesTestSuite attributesTestSuite
Ptr< const AttributeChecker > MakeCallbackChecker(void)
Definition: callback.cc:75
void InvokeCb(double a, int b, float c)
int8_t DoGetIntSrc(void) const
TracedValue< double > m_doubleSrc
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: double.h:42
Ptr< const AttributeChecker > MakeEnumChecker(int v1, std::string n1, int v2, std::string n2, int v3, std::string n3, int v4, std::string n4, int v5, std::string n5, int v6, std::string n6, int v7, std::string n7, int v8, std::string n8, int v9, std::string n9, int v10, std::string n10, int v11, std::string n11, int v12, std::string n12, int v13, std::string n13, int v14, std::string n14, int v15, std::string n15, int v16, std::string n16, int v17, std::string n17, int v18, std::string n18, int v19, std::string n19, int v20, std::string n20, int v21, std::string n21, int v22, std::string n22)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.cc:184
Instantiate subclasses of ns3::Object.
AttributeTestCase(std::string description)
virtual void DoRun(void)
Implementation to actually run this TestCase.
static TypeId GetTypeId(void)
uint32_t DoGetVectorN(void) const
#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:617
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:774
static TypeId GetTypeId(void)
Ptr< const AttributeAccessor > MakeObjectMapAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-map.h:80
Test_e DoGetEnum(void) const
Ptr< RandomVariableStream > m_random
Test class for TracedValue callbacks.
uint32_t GetN(void) const
Get the number of Objects.
A base class which provides memory management and object aggregation.
Definition: object.h:87
Container for a set of ns3::Object pointers.
TracedValue< bool > m_boolSrc
PointerAttributeTestCase(std::string description)
This class can be used to hold variables of floating point type such as 'double' or 'float'...
Definition: double.h:41
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
a unique identifier for an interface.
Definition: type-id.h:58
Ptr< const AttributeChecker > MakeValueClassTestChecker(void)
CallbackValueTestCase(std::string description)
#define ATTRIBUTE_HELPER_HEADER(type)
Declare the attribute value, accessor and checkers for class type.
Callback< void, int8_t > m_cbValue
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.