--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/attribute-test-suite.cc Wed Sep 23 15:20:23 2009 -0700
@@ -0,0 +1,1175 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "test.h"
+#include "object.h"
+#include "boolean.h"
+#include "integer.h"
+#include "uinteger.h"
+#include "enum.h"
+#include "string.h"
+#include "random-variable.h"
+#include "double.h"
+#include "object-vector.h"
+#include "traced-value.h"
+#include "callback.h"
+#include "trace-source-accessor.h"
+#include "pointer.h"
+
+namespace ns3 {
+
+class ValueClassTest
+{
+public:
+ ValueClassTest () {}
+private:
+ int m_v;
+};
+bool operator != (const ValueClassTest &a, const ValueClassTest &b)
+{
+ return true;
+}
+std::ostream & operator << (std::ostream &os, ValueClassTest v)
+{
+ return os;
+}
+std::istream & operator >> (std::istream &is, ValueClassTest &v)
+{
+ return is;
+}
+ATTRIBUTE_HELPER_HEADER (ValueClassTest);
+ATTRIBUTE_HELPER_CPP (ValueClassTest);
+
+class Derived : public Object
+{
+public:
+ static TypeId GetTypeId (void) {
+ static TypeId tid = TypeId ("Derived")
+ .SetParent<Object> ()
+ ;
+ return tid;
+ }
+};
+
+class AttributeObjectTest : public Object
+{
+public:
+ enum Test_e {
+ TEST_A,
+ TEST_B,
+ TEST_C
+ };
+ static TypeId GetTypeId (void) {
+ static TypeId tid = TypeId ("ns3::AttributeObjectTest")
+ .SetParent<Object> ()
+ .HideFromDocumentation ()
+ .AddAttribute ("TestBoolName", "help text",
+ BooleanValue (false),
+ MakeBooleanAccessor (&AttributeObjectTest::m_boolTest),
+ MakeBooleanChecker ())
+ .AddAttribute ("TestBoolA", "help text",
+ BooleanValue (false),
+ MakeBooleanAccessor (&AttributeObjectTest::DoSetTestB,
+ &AttributeObjectTest::DoGetTestB),
+ MakeBooleanChecker ())
+ .AddAttribute ("TestInt16", "help text",
+ IntegerValue (-2),
+ MakeIntegerAccessor (&AttributeObjectTest::m_int16),
+ MakeIntegerChecker<int16_t> ())
+ .AddAttribute ("TestInt16WithBounds", "help text",
+ IntegerValue (-2),
+ MakeIntegerAccessor (&AttributeObjectTest::m_int16WithBounds),
+ MakeIntegerChecker<int16_t> (-5, 10))
+ .AddAttribute ("TestInt16SetGet", "help text",
+ IntegerValue (6),
+ MakeIntegerAccessor (&AttributeObjectTest::DoSetInt16,
+ &AttributeObjectTest::DoGetInt16),
+ MakeIntegerChecker<int16_t> ())
+ .AddAttribute ("TestUint8", "help text",
+ UintegerValue (1),
+ MakeUintegerAccessor (&AttributeObjectTest::m_uint8),
+ MakeUintegerChecker<uint8_t> ())
+ .AddAttribute ("TestEnum", "help text",
+ EnumValue (TEST_A),
+ MakeEnumAccessor (&AttributeObjectTest::m_enum),
+ MakeEnumChecker (TEST_A, "TestA",
+ TEST_B, "TestB",
+ TEST_C, "TestC"))
+ .AddAttribute ("TestRandom", "help text",
+ RandomVariableValue (ConstantVariable (1.0)),
+ MakeRandomVariableAccessor (&AttributeObjectTest::m_random),
+ MakeRandomVariableChecker ())
+ .AddAttribute ("TestFloat", "help text",
+ DoubleValue (-1.1),
+ MakeDoubleAccessor (&AttributeObjectTest::m_float),
+ MakeDoubleChecker<float> ())
+ .AddAttribute ("TestVector1", "help text",
+ ObjectVectorValue (),
+ MakeObjectVectorAccessor (&AttributeObjectTest::m_vector1),
+ MakeObjectVectorChecker<Derived> ())
+ .AddAttribute ("TestVector2", "help text",
+ ObjectVectorValue (),
+ MakeObjectVectorAccessor (&AttributeObjectTest::DoGetVectorN,
+ &AttributeObjectTest::DoGetVector),
+ MakeObjectVectorChecker<Derived> ())
+ .AddAttribute ("IntegerTraceSource1", "help text",
+ IntegerValue (-2),
+ MakeIntegerAccessor (&AttributeObjectTest::m_intSrc1),
+ MakeIntegerChecker<int8_t> ())
+ .AddAttribute ("IntegerTraceSource2", "help text",
+ IntegerValue (-2),
+ MakeIntegerAccessor (&AttributeObjectTest::DoSetIntSrc,
+ &AttributeObjectTest::DoGetIntSrc),
+ MakeIntegerChecker<int8_t> ())
+ .AddAttribute ("ValueClassSource", "help text",
+ ValueClassTestValue (ValueClassTest ()),
+ MakeValueClassTestAccessor (&AttributeObjectTest::m_valueSrc),
+ MakeValueClassTestChecker ())
+ .AddTraceSource ("Source1", "help test",
+ MakeTraceSourceAccessor (&AttributeObjectTest::m_intSrc1))
+ .AddTraceSource ("Source2", "help text",
+ MakeTraceSourceAccessor (&AttributeObjectTest::m_cb))
+ .AddTraceSource ("ValueSource", "help text",
+ MakeTraceSourceAccessor (&AttributeObjectTest::m_valueSrc))
+ .AddAttribute ("Pointer", "help text",
+ PointerValue (),
+ MakePointerAccessor (&AttributeObjectTest::m_ptr),
+ MakePointerChecker<Derived> ())
+ .AddAttribute ("Callback", "help text",
+ CallbackValue (),
+ MakeCallbackAccessor (&AttributeObjectTest::m_cbValue),
+ MakeCallbackChecker ())
+ ;
+
+ return tid;
+ }
+
+ void AddToVector1 (void) {m_vector1.push_back (CreateObject<Derived> ());}
+ void AddToVector2 (void) {m_vector2.push_back (CreateObject<Derived> ());}
+ void InvokeCb (double a, int b, float c) {m_cb (a,b,c);}
+
+ void InvokeCbValue (int8_t a)
+ {
+ if (!m_cbValue.IsNull ()) {
+ m_cbValue (a);
+ }
+ }
+
+private:
+ void DoSetTestB (bool v) {m_boolTestA = v;}
+ bool DoGetTestB (void) const {return m_boolTestA;}
+ int16_t DoGetInt16 (void) const {return m_int16SetGet;}
+ void DoSetInt16 (int16_t v) {m_int16SetGet = v;}
+ uint32_t DoGetVectorN (void) const {return m_vector2.size ();}
+ Ptr<Derived> DoGetVector (uint32_t i) const {return m_vector2[i];}
+ bool DoSetIntSrc (int8_t v) {m_intSrc2 = v; return true;}
+ int8_t DoGetIntSrc (void) const {return m_intSrc2;}
+
+ bool m_boolTestA;
+ bool m_boolTest;
+ int16_t m_int16;
+ int16_t m_int16WithBounds;
+ int16_t m_int16SetGet;
+ uint8_t m_uint8;
+ float m_float;
+ enum Test_e m_enum;
+ RandomVariable m_random;
+ std::vector<Ptr<Derived> > m_vector1;
+ std::vector<Ptr<Derived> > m_vector2;
+ Callback<void,int8_t> m_cbValue;
+ TracedValue<int8_t> m_intSrc1;
+ TracedValue<int8_t> m_intSrc2;
+ TracedCallback<double, int, float> m_cb;
+ TracedValue<ValueClassTest> m_valueSrc;
+ Ptr<Derived> m_ptr;
+};
+
+NS_OBJECT_ENSURE_REGISTERED (AttributeObjectTest);
+
+// ===========================================================================
+// Test case template used for generic Attribute Value types -- used to make
+// sure that Attributes work as expected.
+// ===========================================================================
+template <typename T>
+class AttributeTestCase : public TestCase
+{
+public:
+ AttributeTestCase (std::string description);
+ virtual ~AttributeTestCase ();
+
+private:
+ virtual bool DoRun (void);
+
+ bool CheckGetCodePaths (Ptr<Object> p, std::string attributeName, std::string expectedString, T expectedValue);
+};
+
+template <typename T>
+AttributeTestCase<T>::AttributeTestCase (std::string description)
+ : TestCase (description)
+{
+}
+
+template <typename T>
+AttributeTestCase<T>::~AttributeTestCase ()
+{
+}
+
+template <typename T> bool
+AttributeTestCase<T>::CheckGetCodePaths (
+ Ptr<Object> p,
+ std::string attributeName,
+ std::string expectedString,
+ T expectedValue)
+{
+ StringValue stringValue;
+ T actualValue;
+
+ //
+ // Get an Attribute value through its StringValue representation.
+ //
+ bool ok = p->GetAttributeFailSafe (attributeName.c_str (), stringValue);
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not GetAttributeFailSafe() " << attributeName << " from Object");
+ NS_TEST_ASSERT_MSG_EQ (stringValue.Get (), expectedString, "Got unexpected StringValue representation");
+
+ //
+ // Get the existing boolean value through its particular type representation.
+ //
+ ok = p->GetAttributeFailSafe (attributeName.c_str (), actualValue);
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not GetAttributeFailSafe() " << attributeName << " from Object");
+ NS_TEST_ASSERT_MSG_EQ (actualValue.Get (), expectedValue.Get (), "Got unexpected Value from Object");
+
+ return GetErrorStatus ();
+}
+
+// ===========================================================================
+// The actual Attribute type test cases are specialized for each Attribute type
+// ===========================================================================
+template <> bool
+AttributeTestCase<BooleanValue>::DoRun (void)
+{
+ AttributeList attrs;
+ Ptr<AttributeObjectTest> p;
+ bool ok;
+
+ //
+ // Test setting a boolean via string representation using AttributeList.
+ //
+ ok = attrs.SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("false"));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetFailSafe() \"ns3::AttributeObjectTest::TestBoolName\" into AttributeList");
+
+ //
+ // Create an object using that attribute list (which should therefore have the
+ // boolean from above set to false.
+ //
+ p = CreateObjectWithAttributes<AttributeObjectTest> (attrs);
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObjectWithAttributes");
+
+ ok = CheckGetCodePaths (p, "TestBoolName", "false", BooleanValue (false));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly from CreateObjectWithAttributes");
+
+ //
+ // Set the default value of the BooleanValue and create an object. The new
+ // default value should stick.
+ //
+ AttributeList::GetGlobal ()->SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("true"));
+ p = CreateObject<AttributeObjectTest> ();
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
+
+ ok = CheckGetCodePaths (p, "TestBoolName", "true", BooleanValue (true));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by default value");
+
+ //
+ // Set the default value of the BooleanValue the other way and create an object.
+ // The new default value should stick.
+ //
+ AttributeList::GetGlobal ()->SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("false"));
+
+ p = CreateObject<AttributeObjectTest> ();
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
+
+ ok = CheckGetCodePaths (p, "TestBoolName", "false", BooleanValue (false));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not et properly by default value");
+
+ //
+ // Set the BooleanValue Attribute to true via SetAttributeFailSafe path.
+ //
+ ok = p->SetAttributeFailSafe("TestBoolName", StringValue ("true"));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() \"TestBoolName\" to true");
+
+ ok = CheckGetCodePaths (p, "TestBoolName", "true", BooleanValue (true));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
+
+ //
+ // Set the BooleanValue to false via SetAttributeFailSafe path.
+ //
+ ok = p->SetAttributeFailSafe("TestBoolName", StringValue ("false"));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() \"TestBoolName\" to false");
+
+ ok = CheckGetCodePaths (p, "TestBoolName", "false", BooleanValue (false));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
+
+ //
+ // Create an object using individually provided StringValue Attribute.
+ //
+ p = CreateObjectWithAttributes<AttributeObjectTest> ("TestBoolName", StringValue ("true"));
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObjectWithAttributes");
+
+ ok = CheckGetCodePaths (p, "TestBoolName", "true", BooleanValue (true));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by CreateObjectWithAttributes() with StringValue");
+
+ //
+ // Create an object using individually provided BooleanValue Attribute.
+ //
+ p = CreateObjectWithAttributes<AttributeObjectTest> ("TestBoolName", BooleanValue (false));
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObjectWithAttributes");
+
+ ok = CheckGetCodePaths (p, "TestBoolName", "false", BooleanValue (false));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by CreateObjectWithAttributes() with BooleanValue");
+
+ //
+ // The previous object-based tests checked access directly. Now check through
+ // setter and getter. The code here looks the same, but the underlying
+ // attribute is declared differently in the object. First make sure we can set
+ // to true.
+ //
+ ok = p->SetAttributeFailSafe("TestBoolA", StringValue ("true"));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a boolean value to true");
+
+ ok = CheckGetCodePaths (p, "TestBoolA", "true", BooleanValue (true));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() (getter/setter) via StringValue");
+
+ //
+ // Now Set the BooleanValue to false via the setter.
+ //
+ ok = p->SetAttributeFailSafe("TestBoolA", StringValue ("false"));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a boolean value to false");
+
+ ok = CheckGetCodePaths (p, "TestBoolA", "false", BooleanValue (false));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() (getter/setter) via StringValue");
+
+ return GetErrorStatus ();
+}
+
+template <> bool
+AttributeTestCase<IntegerValue>::DoRun (void)
+{
+ Ptr<AttributeObjectTest> p;
+ bool ok;
+
+ p = CreateObject<AttributeObjectTest> ();
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
+
+ //
+ // When the object is first created, the Attribute should have the default
+ // value.
+ //
+ ok = CheckGetCodePaths (p, "TestInt16", "-2", IntegerValue (-2));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by default value");
+
+ //
+ // Set the Attribute to a negative value through a StringValue.
+ //
+ ok = p->SetAttributeFailSafe("TestInt16", StringValue ("-5"));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to -5");
+
+ ok = CheckGetCodePaths (p, "TestInt16", "-5", IntegerValue (-5));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
+
+ //
+ // Set the Attribute to a positive value through a StringValue.
+ //
+ ok = p->SetAttributeFailSafe("TestInt16", StringValue ("+2"));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to +2");
+
+ ok = CheckGetCodePaths (p, "TestInt16", "2", IntegerValue (2));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
+
+ //
+ // Set the Attribute to the most negative value of the signed 16-bit range.
+ //
+ ok = p->SetAttributeFailSafe("TestInt16", StringValue ("-32768"));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to -32768");
+
+ ok = CheckGetCodePaths (p, "TestInt16", "-32768", IntegerValue (-32768));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() (most negative) via StringValue");
+
+ //
+ // Try to set the Attribute past the most negative value of the signed 16-bit
+ // range and make sure the underlying attribute is unchanged.
+ //
+ ok = p->SetAttributeFailSafe("TestInt16", StringValue ("-32769"));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via StringValue to -32769");
+
+ ok = CheckGetCodePaths (p, "TestInt16", "-32768", IntegerValue (-32768));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Error in SetAttributeFailSafe() but value changes");
+
+ //
+ // Set the Attribute to the most positive value of the signed 16-bit range.
+ //
+ ok = p->SetAttributeFailSafe("TestInt16", StringValue ("32767"));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to 32767");
+
+ ok = CheckGetCodePaths (p, "TestInt16", "32767", IntegerValue (32767));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() (most positive) via StringValue");
+
+ //
+ // Try to set the Attribute past the most positive value of the signed 16-bit
+ // range and make sure the underlying attribute is unchanged.
+ //
+ ok = p->SetAttributeFailSafe("TestInt16", StringValue ("32768"));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via StringValue to 32768");
+
+ ok = CheckGetCodePaths (p, "TestInt16", "32767", IntegerValue (32767));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Error in SetAttributeFailSafe() but value changes");
+
+ //
+ // Attributes can have limits other than the intrinsic limits of the
+ // underlying data types. These limits are specified in the Object.
+ //
+ ok = p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue (10));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 10");
+
+ ok = CheckGetCodePaths (p, "TestInt16WithBounds", "10", IntegerValue (10));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() (positive limit) via StringValue");
+
+ //
+ // Set the Attribute past the positive limit.
+ //
+ ok = p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue (11));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 11");
+
+ ok = CheckGetCodePaths (p, "TestInt16WithBounds", "10", IntegerValue (10));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Error in SetAttributeFailSafe() but value changes");
+
+ //
+ // Set the Attribute at the negative limit.
+ //
+ ok = p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue (-5));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -5");
+
+ ok = CheckGetCodePaths (p, "TestInt16WithBounds", "-5", IntegerValue (-5));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() (negative limit) via StringValue");
+
+ //
+ // Set the Attribute past the negative limit.
+ //
+ ok = p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue (-6));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -6");
+
+ ok = CheckGetCodePaths (p, "TestInt16WithBounds", "-5", IntegerValue (-5));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Error in SetAttributeFailSafe() but value changes");
+
+ return GetErrorStatus ();
+}
+
+template <> bool
+AttributeTestCase<UintegerValue>::DoRun (void)
+{
+ Ptr<AttributeObjectTest> p;
+ bool ok;
+
+ p = CreateObject<AttributeObjectTest> ();
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
+
+ //
+ // When the object is first created, the Attribute should have the default
+ // value.
+ //
+ ok = CheckGetCodePaths (p, "TestUint8", "1", UintegerValue (1));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by default value");;
+
+ //
+ // Set the Attribute to zero.
+ //
+ ok = p->SetAttributeFailSafe("TestUint8", UintegerValue (0));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to 0");
+
+ ok = CheckGetCodePaths (p, "TestUint8", "0", UintegerValue (0));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
+
+ //
+ // Set the Attribute to the most positive value of the unsigned 8-bit range.
+ //
+ ok = p->SetAttributeFailSafe("TestUint8", UintegerValue (255));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to 255");
+
+ ok = CheckGetCodePaths (p, "TestUint8", "255", UintegerValue (255));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() (positive limit) via UintegerValue");
+
+ //
+ // Try and set the Attribute past the most positive value of the unsigned
+ // 8-bit range.
+ //
+ ok = p->SetAttributeFailSafe("TestUint8", UintegerValue (256));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() to 256");
+
+ ok = CheckGetCodePaths (p, "TestUint8", "255", UintegerValue (255));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Error in SetAttributeFailSafe() but value changes");
+
+ //
+ // Set the Attribute to the most positive value of the unsigned 8-bit range
+ // through a StringValue.
+ //
+ ok = p->SetAttributeFailSafe("TestUint8", StringValue ("255"));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via StringValue to 255");
+
+ ok = CheckGetCodePaths (p, "TestUint8", "255", UintegerValue (255));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
+
+ //
+ // Try and set the Attribute past the most positive value of the unsigned
+ // 8-bit range through a StringValue.
+ //
+ ok = p->SetAttributeFailSafe("TestUint8", StringValue ("256"));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via StringValue to 256");
+
+ ok = CheckGetCodePaths (p, "TestUint8", "255", UintegerValue (255));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Error in SetAttributeFailSafe() but value changes");
+
+ //
+ // Try to set the Attribute to a negative StringValue.
+ //
+ ok = p->SetAttributeFailSafe("TestUint8", StringValue ("-1"));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via StringValue to -1");
+
+ return GetErrorStatus ();
+}
+
+template <> bool
+AttributeTestCase<DoubleValue>::DoRun (void)
+{
+ Ptr<AttributeObjectTest> p;
+ bool ok;
+
+ p = CreateObject<AttributeObjectTest> ();
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
+
+ //
+ // When the object is first created, the Attribute should have the default
+ // value.
+ //
+ ok = CheckGetCodePaths (p, "TestFloat", "-1.1", DoubleValue ((float)-1.1));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by default value");
+
+ //
+ // Set the Attribute.
+ //
+ ok = p->SetAttributeFailSafe("TestFloat", DoubleValue ((float)2.3));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to 2.3");
+
+ ok = CheckGetCodePaths (p, "TestFloat", "2.3", DoubleValue ((float)2.3));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() via DoubleValue");
+
+ return GetErrorStatus ();
+}
+
+template <> bool
+AttributeTestCase<EnumValue>::DoRun (void)
+{
+ Ptr<AttributeObjectTest> p;
+ bool ok;
+
+ p = CreateObject<AttributeObjectTest> ();
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
+
+ //
+ // When the object is first created, the Attribute should have the default
+ // value.
+ //
+ ok = CheckGetCodePaths (p, "TestEnum", "TestA", EnumValue (AttributeObjectTest::TEST_A));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by default value");
+
+ //
+ // Set the Attribute using the EnumValue type.
+ //
+ ok = p->SetAttributeFailSafe("TestEnum", EnumValue (AttributeObjectTest::TEST_C));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to TEST_C");
+
+ ok = CheckGetCodePaths (p, "TestEnum", "TestC", EnumValue (AttributeObjectTest::TEST_C));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() via EnumValue");
+
+ //
+ // Set the Attribute using the StringValue type.
+ //
+ ok = p->SetAttributeFailSafe("TestEnum", StringValue ("TestB"));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() to TEST_B");
+
+ ok = CheckGetCodePaths (p, "TestEnum", "TestB", EnumValue (AttributeObjectTest::TEST_B));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
+
+ //
+ // Try to set the Attribute to a bogus enum using the StringValue type and
+ // make sure the underlying value doesn't change.
+ //
+ ok = p->SetAttributeFailSafe("TestEnum", StringValue ("TestD"));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() to TEST_D"); //
+
+ ok = CheckGetCodePaths (p, "TestEnum", "TestB", EnumValue (AttributeObjectTest::TEST_B));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Error in SetAttributeFailSafe() but value changes");
+
+ //
+ // Try to set the Attribute to a bogus enum using an integer implicit conversion
+ // and make sure the underlying value doesn't change.
+ //
+ ok = p->SetAttributeFailSafe("TestEnum", EnumValue (5));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() to 5");
+
+ ok = CheckGetCodePaths (p, "TestEnum", "TestB", EnumValue (AttributeObjectTest::TEST_B));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Error in SetAttributeFailSafe() but value changes");
+
+ return GetErrorStatus ();
+}
+
+template <> bool
+AttributeTestCase<RandomVariableValue>::DoRun (void)
+{
+ Ptr<AttributeObjectTest> p;
+ bool ok;
+
+ p = CreateObject<AttributeObjectTest> ();
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
+
+ //
+ // Try to set a UniformVariable
+ //
+ ok = p->SetAttributeFailSafe("TestRandom", RandomVariableValue (UniformVariable (0., 1.)));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a UniformVariable");
+
+ //
+ // Try to set a <snicker> ConstantVariable
+ //
+ ok = p->SetAttributeFailSafe("TestRandom", RandomVariableValue (ConstantVariable (10.)));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a UniformVariable");
+
+ return GetErrorStatus ();
+}
+
+// ===========================================================================
+// Test case for Object Vector Attributes. Generic nature is pretty much lost
+// here, so we just break the class out.
+// ===========================================================================
+class ObjectVectorAttributeTestCase : public TestCase
+{
+public:
+ ObjectVectorAttributeTestCase (std::string description);
+ virtual ~ObjectVectorAttributeTestCase () {}
+
+private:
+ virtual bool DoRun (void);
+};
+
+ObjectVectorAttributeTestCase::ObjectVectorAttributeTestCase (std::string description)
+ : TestCase (description)
+{
+}
+
+bool
+ObjectVectorAttributeTestCase::DoRun (void)
+{
+ Ptr<AttributeObjectTest> p;
+ ObjectVectorValue vector;
+
+ p = CreateObject<AttributeObjectTest> ();
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
+
+ //
+ // When the object is first created, the Attribute should have no items in
+ // the vector.
+ //
+ p->GetAttribute ("TestVector1", vector);
+ NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 0, "Initial count of ObjectVectorValue \"TestVector1\" should be zero");
+
+ //
+ // Adding to the attribute shouldn't affect the value we already have.
+ //
+ p->AddToVector1 ();
+ NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 0, "Initial count of ObjectVectorValue \"TestVector1\" should still be zero");
+
+ //
+ // Getting the attribute again should update the value.
+ //
+ p->GetAttribute ("TestVector1", vector);
+ NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 1, "ObjectVectorValue \"TestVector1\" should be incremented");
+
+ //
+ // Get the Object pointer from the value.
+ //
+ Ptr<Object> a = vector.Get (0);
+ NS_TEST_ASSERT_MSG_NE (a, 0, "Ptr<Object> from VectorValue \"TestVector1\" is zero");
+
+ //
+ // Adding to the attribute shouldn't affect the value we already have.
+ //
+ p->AddToVector1 ();
+ NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 1, "Count of ObjectVectorValue \"TestVector1\" should still be one");
+
+ //
+ // Getting the attribute again should update the value.
+ //
+ p->GetAttribute ("TestVector1", vector);
+ NS_TEST_ASSERT_MSG_EQ (vector.GetN (), 2, "ObjectVectorValue \"TestVector1\" should be incremented");
+
+ return GetErrorStatus ();
+}
+
+// ===========================================================================
+// Trace sources with value semantics can be used like Attributes. Make sure
+// we can use them that way.
+// ===========================================================================
+class IntegerTraceSourceAttributeTestCase : public TestCase
+{
+public:
+ IntegerTraceSourceAttributeTestCase (std::string description);
+ virtual ~IntegerTraceSourceAttributeTestCase () {}
+
+private:
+ virtual bool DoRun (void);
+};
+
+IntegerTraceSourceAttributeTestCase::IntegerTraceSourceAttributeTestCase (std::string description)
+ : TestCase (description)
+{
+}
+
+bool
+IntegerTraceSourceAttributeTestCase::DoRun (void)
+{
+ Ptr<AttributeObjectTest> p;
+ IntegerValue iv;
+ bool ok;
+
+ p = CreateObject<AttributeObjectTest> ();
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
+
+ //
+ // When the object is first created, the Attribute should have the default
+ // value.
+ //
+ p->GetAttribute ("IntegerTraceSource1", iv);
+ NS_TEST_ASSERT_MSG_EQ (iv.Get (), -2, "Attribute not set properly by default value");
+
+ //
+ // Set the Attribute to a positive value through an IntegerValue.
+ //
+ ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue (5));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 5");
+
+ p->GetAttribute ("IntegerTraceSource1", iv);
+ NS_TEST_ASSERT_MSG_EQ (iv.Get (), 5, "Attribute not set properly by SetAttributeFailSafe() via IntegerValue");
+
+ //
+ // Limits should work.
+ //
+ ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue (127));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 127");
+
+ ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue (128));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 128");
+
+ ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue (-128));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -128");
+
+ ok = p->SetAttributeFailSafe("IntegerTraceSource1", IntegerValue (-129));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -129");
+
+ //
+ // When the object is first created, the Attribute should have the default
+ // value.
+ //
+ p->GetAttribute ("IntegerTraceSource2", iv);
+ NS_TEST_ASSERT_MSG_EQ (iv.Get (), -2, "Attribute not set properly by default value");
+
+ //
+ // Set the Attribute to a positive value through an IntegerValue.
+ //
+ ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue (5));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 5");
+
+ p->GetAttribute ("IntegerTraceSource2", iv);
+ NS_TEST_ASSERT_MSG_EQ (iv.Get (), 5, "Attribute not set properly by SetAttributeFailSafe() via IntegerValue");
+
+ //
+ // Limits should work.
+ //
+ ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue (127));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 127");
+
+ ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue (128));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to 128");
+
+ ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue (-128));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -128");
+
+ ok = p->SetAttributeFailSafe("IntegerTraceSource2", IntegerValue (-129));
+ NS_TEST_ASSERT_MSG_EQ (ok, false, "Unexpectedly could SetAttributeFailSafe() via IntegerValue to -129");
+
+ return GetErrorStatus ();
+}
+
+// ===========================================================================
+// Trace sources used like Attributes must also work as trace sources. Make
+// sure we can use them that way.
+// ===========================================================================
+class IntegerTraceSourceTestCase : public TestCase
+{
+public:
+ IntegerTraceSourceTestCase (std::string description);
+ virtual ~IntegerTraceSourceTestCase () {}
+
+private:
+ virtual bool DoRun (void);
+
+ void NotifySource1 (int8_t old, int8_t n) {m_got1 = n;}
+ int64_t m_got1;
+};
+
+IntegerTraceSourceTestCase::IntegerTraceSourceTestCase (std::string description)
+ : TestCase (description)
+{
+}
+
+bool
+IntegerTraceSourceTestCase::DoRun (void)
+{
+ Ptr<AttributeObjectTest> p;
+ bool ok;
+
+ p = CreateObject<AttributeObjectTest> ();
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
+
+ //
+ // Check to make sure changing an Attibute value triggers a trace callback
+ // that sets a member variable.
+ //
+ m_got1 = 1234;
+
+ ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (-1));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to -1");
+
+ //
+ // Source1 is declared as a TraceSourceAccessor to m_intSrc1. This m_intSrc1
+ // is also declared as an Integer Attribute. We just checked to make sure we
+ // could set it using an IntegerValue through its IntegerTraceSource1 "persona."
+ // We should also be able to hook a trace source to the underlying variable.
+ //
+ ok = p->TraceConnectWithoutContext ("Source1", MakeCallback (&IntegerTraceSourceTestCase::NotifySource1, this));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not TraceConnectWithoutContext() \"Source1\" to NodifySource1()");
+
+ //
+ // When we set the IntegerValue that now underlies both the Integer Attribute
+ // and the trace source, the trace should fire and call NotifySource1 which
+ // will set m_got1 to the new value.
+ //
+ ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (0));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 0");
+
+ NS_TEST_ASSERT_MSG_EQ (m_got1, 0, "Hitting a TracedValue does not cause trace callback to be called");
+
+ //
+ // Now disconnect from the trace source and ensure that the trace callback
+ // is not called if the trace source is hit.
+ //
+ ok = p->TraceDisconnectWithoutContext ("Source1", MakeCallback (&IntegerTraceSourceTestCase::NotifySource1, this));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not TraceConnectWithoutContext() \"Source1\" to NodifySource1()");
+
+ ok = p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (1));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() via IntegerValue to 1");
+
+ NS_TEST_ASSERT_MSG_EQ (m_got1, 0, "Hitting a TracedValue after disconnect still causes callback");
+
+ return GetErrorStatus ();
+}
+
+// ===========================================================================
+// Trace sources used like Attributes must also work as trace sources. Make
+// sure we can use them that way.
+// ===========================================================================
+class TracedCallbackTestCase : public TestCase
+{
+public:
+ TracedCallbackTestCase (std::string description);
+ virtual ~TracedCallbackTestCase () {}
+
+private:
+ virtual bool DoRun (void);
+
+ void NotifySource2 (double a, int b, float c) {m_got2 = a;}
+
+ double m_got2;
+};
+
+TracedCallbackTestCase::TracedCallbackTestCase (std::string description)
+ : TestCase (description)
+{
+}
+
+bool
+TracedCallbackTestCase::DoRun (void)
+{
+ Ptr<AttributeObjectTest> p;
+ bool ok;
+
+ p = CreateObject<AttributeObjectTest> ();
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
+
+ //
+ // Initialize the
+ //
+ m_got2 = 4.3;
+
+ //
+ // Invoke the callback that lies at the heart of this test. We have a
+ // method InvokeCb() that just executes m_cb(). The variable m_cb is
+ // declared as a TracedCallback<double, int, float>. This kind of beast
+ // is like a callback but can call a list of targets. This list should
+ // be empty so nothing should happen now. Specifically, m_got2 shouldn't
+ // have changed.
+ //
+ p->InvokeCb (1.0, -5, 0.0);
+ NS_TEST_ASSERT_MSG_EQ (m_got2, 4.3, "Invoking a newly created TracedCallback results in an unexpected callback");
+
+ //
+ // Now, wire the TracedCallback up to a trace sink. This sink will just set
+ // m_got2 to the first argument.
+ //
+ ok = p->TraceConnectWithoutContext ("Source2", MakeCallback (&TracedCallbackTestCase::NotifySource2, this));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not TraceConnectWithoutContext() to NotifySource2");
+
+ //
+ // Now if we invoke the callback, the trace source should fire and m_got2
+ // should be set in the trace sink.
+ //
+ p->InvokeCb (1.0, -5, 0.0);
+ NS_TEST_ASSERT_MSG_EQ (m_got2, 1.0, "Invoking TracedCallback does not result in trace callback");
+
+ //
+ // Now, disconnect the trace sink and see what happens when we invoke the
+ // callback again. Of course, the trace should not happen and m_got2
+ // should remain unchanged.
+ //
+ ok = p->TraceDisconnectWithoutContext ("Source2", MakeCallback (&TracedCallbackTestCase::NotifySource2, this));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not TraceDisconnectWithoutContext() from NotifySource2");
+
+ p->InvokeCb (-1.0, -5, 0.0);
+ NS_TEST_ASSERT_MSG_EQ (m_got2, 1.0, "Invoking disconnected TracedCallback unexpectedly results in trace callback");
+
+ return GetErrorStatus ();
+}
+
+// ===========================================================================
+// Smart pointers (Ptr) are central to our architecture, so they must work as
+// attributes.
+// ===========================================================================
+class PointerAttributeTestCase : public TestCase
+{
+public:
+ PointerAttributeTestCase (std::string description);
+ virtual ~PointerAttributeTestCase () {}
+
+private:
+ virtual bool DoRun (void);
+
+ void NotifySource2 (double a, int b, float c) {m_got2 = a;}
+
+ double m_got2;
+};
+
+PointerAttributeTestCase::PointerAttributeTestCase (std::string description)
+ : TestCase (description)
+{
+}
+
+bool
+PointerAttributeTestCase::DoRun (void)
+{
+ Ptr<AttributeObjectTest> p;
+ bool ok;
+
+ p = CreateObject<AttributeObjectTest> ();
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
+
+ //
+ // We have declared a PointerValue Attribute named "Pointer" with a pointer
+ // checker of type Derived. This means that we should be able to pull out
+ // a Ptr<Derived> with the initial value (which is 0).
+ //
+ PointerValue ptr;
+ p->GetAttribute ("Pointer", ptr);
+ Ptr<Derived> derived = ptr.Get<Derived> ();
+ NS_TEST_ASSERT_MSG_EQ (derived, 0, "Unexpectedly found non-null pointer in newly initialized PointerValue Attribute");
+
+ //
+ // Now, lets create an Object of type Derived and set the local Ptr to point
+ // to that object. We can then set the PointerValue Attribute to that Ptr.
+ //
+ derived = Create<Derived> ();
+ ok = p->SetAttributeFailSafe("Pointer", PointerValue (derived));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a PointerValue of the correct type");
+
+ //
+ // Pull the value back out of the Attribute and make sure it points to the
+ // correct object.
+ //
+ p->GetAttribute ("Pointer", ptr);
+ Ptr<Derived> stored = ptr.Get<Derived> ();
+ NS_TEST_ASSERT_MSG_EQ (stored, derived, "Retreived Attribute does not match stored PointerValue");
+
+ //
+ // We should be able to use the Attribute Get() just like GetObject<type>,
+ // So see if we can get a Ptr<Object> out of the Ptr<Derived> we stored.
+ // This should be a pointer to the same physical memory since its the
+ // same object.
+ //
+ p->GetAttribute ("Pointer", ptr);
+ Ptr<Object> storedBase = ptr.Get<Object> ();
+ NS_TEST_ASSERT_MSG_EQ (storedBase, stored, "Retreived Ptr<Object> does not match stored Ptr<Derived>");
+
+ //
+ // If we try to Get() something that is unrelated to what we stored, we should
+ // retrieve a 0.
+ //
+ p->GetAttribute ("Pointer", ptr);
+ Ptr<AttributeObjectTest> x = ptr.Get<AttributeObjectTest> ();
+ NS_TEST_ASSERT_MSG_EQ (x, 0, "Unexpectedly retreived unrelated Ptr<type> from stored Ptr<Derived>");
+
+ //
+ // We should be able to create the object From a list of attributes.
+ //
+ p = CreateObjectWithAttributes<AttributeObjectTest> ("Pointer", PointerValue (Create<Derived> ()));
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Could not create Object with PointerValue Attribute in Attribute List");
+
+ derived = 0;
+ p->GetAttribute ("Pointer", ptr);
+ derived = ptr.Get<Derived> ();
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Retrieved zero PointerValue Attribute after initializing to non-zero Ptr");
+
+ return GetErrorStatus ();
+}
+
+// ===========================================================================
+// ===========================================================================
+class CallbackValueTestCase : public TestCase
+{
+public:
+ CallbackValueTestCase (std::string description);
+ virtual ~CallbackValueTestCase () {}
+
+ void InvokeCbValue (int8_t a)
+ {
+ if (!m_cbValue.IsNull ()) {
+ m_cbValue (a);
+ }
+ }
+
+
+private:
+ virtual bool DoRun (void);
+
+ Callback<void,int8_t> m_cbValue;
+
+ void NotifyCallbackValue (int8_t a) {m_gotCbValue = a;}
+
+ int16_t m_gotCbValue;
+};
+
+CallbackValueTestCase::CallbackValueTestCase (std::string description)
+ : TestCase (description)
+{
+}
+
+bool
+CallbackValueTestCase::DoRun (void)
+{
+ Ptr<AttributeObjectTest> p;
+ bool ok;
+
+ p = CreateObject<AttributeObjectTest> ();
+ NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
+
+ //
+ // The member variable m_cbValue is declared as a Callback<void, int8_t>. The
+ // Attibute named "Callback" also points to m_cbValue and allows us to set the
+ // callback using that Attribute.
+ //
+ // NotifyCallbackValue is going to be the target of the callback and will just set
+ // m_gotCbValue to its single parameter. This will be the parameter from the
+ // callback invocation. The method InvokeCbValue() just invokes the m_cbValue
+ // callback if it is non-null.
+ //
+ m_gotCbValue = 1;
+
+ //
+ // If we invoke the callback (which has not been set) nothing should happen.
+ // Further, nothing should happen when we initialize the callback (it shouldn't
+ // accidentally fire).
+ //
+ p->InvokeCbValue (2);
+ CallbackValue cbValue = MakeCallback (&CallbackValueTestCase::NotifyCallbackValue, this);
+
+ NS_TEST_ASSERT_MSG_EQ (m_gotCbValue, 1, "Callback unexpectedly fired");
+
+ ok = p->SetAttributeFailSafe ("Callback", cbValue);
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a CallbackValue");
+
+ //
+ // Now that the callback has been set, invoking it should set m_gotCbValue.
+ //
+ p->InvokeCbValue (2);
+ NS_TEST_ASSERT_MSG_EQ (m_gotCbValue, 2, "Callback Attribute set by CallbackValue did not fire");
+
+ ok = p->SetAttributeFailSafe ("Callback", CallbackValue (MakeNullCallback<void,int8_t> ()));
+ NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetAttributeFailSafe() a null CallbackValue");
+
+ //
+ // If the callback has been set to a null callback, it should no longer fire.
+ //
+ p->InvokeCbValue (3);
+ NS_TEST_ASSERT_MSG_EQ (m_gotCbValue, 2, "Callback Attribute set to null callback unexpectedly fired");
+
+ return GetErrorStatus ();
+}
+
+// ===========================================================================
+// The Test Suite that glues all of the Test Cases together.
+// ===========================================================================
+class AttributesTestSuite : public TestSuite
+{
+public:
+ AttributesTestSuite ();
+};
+
+AttributesTestSuite::AttributesTestSuite ()
+ : TestSuite ("attributes", UNIT)
+{
+ AddTestCase (new AttributeTestCase<BooleanValue> ("Check Attributes of type BooleanValue"));
+ AddTestCase (new AttributeTestCase<IntegerValue> ("Check Attributes of type IntegerValue"));
+ AddTestCase (new AttributeTestCase<UintegerValue> ("Check Attributes of type UintegerValue"));
+ AddTestCase (new AttributeTestCase<DoubleValue> ("Check Attributes of type DoubleValue"));
+ AddTestCase (new AttributeTestCase<EnumValue> ("Check Attributes of type EnumValue"));
+ AddTestCase (new AttributeTestCase<RandomVariableValue> ("Check Attributes of type RandomVariableValue"));
+ AddTestCase (new ObjectVectorAttributeTestCase ("Check Attributes of type ObjectVectorValue"));
+ AddTestCase (new IntegerTraceSourceAttributeTestCase ("Ensure TracedValue<uint8_t> can be set like IntegerValue"));
+ AddTestCase (new IntegerTraceSourceTestCase ("Ensure TracedValue<uint8_t> also works as trace source"));
+ AddTestCase (new TracedCallbackTestCase ("Ensure TracedCallback<double, int, float> works as trace source"));
+ AddTestCase (new PointerAttributeTestCase ("Check Attributes of type PointerValue"));
+ AddTestCase (new CallbackValueTestCase ("Check Attributes of type CallbackValue"));
+}
+
+AttributesTestSuite attributesTestSuite;
+
+} // namespace ns3
--- a/src/core/attribute-test.cc Mon Sep 21 11:21:05 2009 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,537 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifdef RUN_SELF_TESTS
-#include "test.h"
-#include "object.h"
-#include "boolean.h"
-#include "integer.h"
-#include "uinteger.h"
-#include "enum.h"
-#include "string.h"
-#include "random-variable.h"
-#include "double.h"
-#include "object-vector.h"
-#include "traced-value.h"
-#include "callback.h"
-#include "trace-source-accessor.h"
-#include "pointer.h"
-
-namespace ns3 {
-
-class ValueClassTest
-{
-public:
- ValueClassTest () {}
-private:
- int m_v;
-};
-bool operator != (const ValueClassTest &a, const ValueClassTest &b)
-{
- return true;
-}
-std::ostream & operator << (std::ostream &os, ValueClassTest v)
-{
- return os;
-}
-std::istream & operator >> (std::istream &is, ValueClassTest &v)
-{
- return is;
-}
-ATTRIBUTE_HELPER_HEADER (ValueClassTest);
-ATTRIBUTE_HELPER_CPP (ValueClassTest);
-
-class AttributeTest : public Test
-{
-public:
- AttributeTest ();
- virtual bool RunTests (void);
-private:
- void NotifySource1 (int8_t old, int8_t n) {
- m_got1 = n;
- }
- void NotifySource2 (double a, int b, float c) {
- m_got2 = a;
- }
- void NotifySourceValue (ValueClassTest old, ValueClassTest n) {
- m_gotValue = n;
- }
- void NotifyCallbackValue (int8_t a) {
- m_gotCbValue = a;
- }
- int64_t m_got1;
- double m_got2;
- ValueClassTest m_gotValue;
- int16_t m_gotCbValue;
-};
-
-class Derived : public Object
-{
-public:
- static TypeId GetTypeId (void) {
- static TypeId tid = TypeId ("Derived")
- .SetParent<Object> ()
- ;
- return tid;
- }
-};
-
-class AttributeObjectTest : public Object
-{
-public:
- enum Test_e {
- TEST_A,
- TEST_B,
- TEST_C
- };
- static TypeId GetTypeId (void) {
- static TypeId tid = TypeId ("ns3::AttributeObjectTest")
- .SetParent<Object> ()
- .HideFromDocumentation ()
- .AddAttribute ("TestBoolName", "help text",
- BooleanValue (false),
- MakeBooleanAccessor (&AttributeObjectTest::m_boolTest),
- MakeBooleanChecker ())
- .AddAttribute ("TestBoolA", "help text",
- BooleanValue (false),
- MakeBooleanAccessor (&AttributeObjectTest::DoSetTestB,
- &AttributeObjectTest::DoGetTestB),
- MakeBooleanChecker ())
- .AddAttribute ("TestInt16", "help text",
- IntegerValue (-2),
- MakeIntegerAccessor (&AttributeObjectTest::m_int16),
- MakeIntegerChecker<int16_t> ())
- .AddAttribute ("TestInt16WithBounds", "help text",
- IntegerValue (-2),
- MakeIntegerAccessor (&AttributeObjectTest::m_int16WithBounds),
- MakeIntegerChecker<int16_t> (-5, 10))
- .AddAttribute ("TestInt16SetGet", "help text",
- IntegerValue (6),
- MakeIntegerAccessor (&AttributeObjectTest::DoSetInt16,
- &AttributeObjectTest::DoGetInt16),
- MakeIntegerChecker<int16_t> ())
- .AddAttribute ("TestUint8", "help text",
- UintegerValue (1),
- MakeUintegerAccessor (&AttributeObjectTest::m_uint8),
- MakeUintegerChecker<uint8_t> ())
- .AddAttribute ("TestEnum", "help text",
- EnumValue (TEST_A),
- MakeEnumAccessor (&AttributeObjectTest::m_enum),
- MakeEnumChecker (TEST_A, "TestA",
- TEST_B, "TestB",
- TEST_C, "TestC"))
- .AddAttribute ("TestRandom", "help text",
- RandomVariableValue (ConstantVariable (1.0)),
- MakeRandomVariableAccessor (&AttributeObjectTest::m_random),
- MakeRandomVariableChecker ())
- .AddAttribute ("TestFloat", "help text",
- DoubleValue (-1.1),
- MakeDoubleAccessor (&AttributeObjectTest::m_float),
- MakeDoubleChecker<float> ())
- .AddAttribute ("TestVector1", "help text",
- ObjectVectorValue (),
- MakeObjectVectorAccessor (&AttributeObjectTest::m_vector1),
- MakeObjectVectorChecker<Derived> ())
- .AddAttribute ("TestVector2", "help text",
- ObjectVectorValue (),
- MakeObjectVectorAccessor (&AttributeObjectTest::DoGetVectorN,
- &AttributeObjectTest::DoGetVector),
- MakeObjectVectorChecker<Derived> ())
- .AddAttribute ("IntegerTraceSource1", "help text",
- IntegerValue (-2),
- MakeIntegerAccessor (&AttributeObjectTest::m_intSrc1),
- MakeIntegerChecker<int8_t> ())
- .AddAttribute ("IntegerTraceSource2", "help text",
- IntegerValue (-2),
- MakeIntegerAccessor (&AttributeObjectTest::DoSetIntSrc,
- &AttributeObjectTest::DoGetIntSrc),
- MakeIntegerChecker<int8_t> ())
- .AddAttribute ("ValueClassSource", "help text",
- ValueClassTestValue (ValueClassTest ()),
- MakeValueClassTestAccessor (&AttributeObjectTest::m_valueSrc),
- MakeValueClassTestChecker ())
- .AddTraceSource ("Source1", "help test",
- MakeTraceSourceAccessor (&AttributeObjectTest::m_intSrc1))
- .AddTraceSource ("Source2", "help text",
- MakeTraceSourceAccessor (&AttributeObjectTest::m_cb))
- .AddTraceSource ("ValueSource", "help text",
- MakeTraceSourceAccessor (&AttributeObjectTest::m_valueSrc))
- .AddAttribute ("Pointer", "help text",
- PointerValue (),
- MakePointerAccessor (&AttributeObjectTest::m_ptr),
- MakePointerChecker<Derived> ())
- .AddAttribute ("Callback", "help text",
- CallbackValue (),
- MakeCallbackAccessor (&AttributeObjectTest::m_cbValue),
- MakeCallbackChecker ())
- ;
-
- return tid;
- }
-
- void AddToVector1 (void) {
- m_vector1.push_back (CreateObject<Derived> ());
- }
- void AddToVector2 (void) {
- m_vector2.push_back (CreateObject<Derived> ());
- }
-
- void InvokeCb (double a, int b, float c) {
- m_cb (a,b,c);
- }
-
- void InvokeCbValue (int8_t a) {
- if (!m_cbValue.IsNull ())
- {
- m_cbValue (a);
- }
- }
-
-private:
- void DoSetTestB (bool v) {
- m_boolTestA = v;
- }
- bool DoGetTestB (void) const {
- return m_boolTestA;
- }
- int16_t DoGetInt16 (void) const {
- return m_int16SetGet;
- }
- void DoSetInt16 (int16_t v) {
- m_int16SetGet = v;
- }
- uint32_t DoGetVectorN (void) const {
- return m_vector2.size ();
- }
- Ptr<Derived> DoGetVector (uint32_t i) const {
- return m_vector2[i];
- }
- bool DoSetIntSrc (int8_t v) {
- m_intSrc2 = v;
- return true;
- }
- int8_t DoGetIntSrc (void) const {
- return m_intSrc2;
- }
- bool m_boolTestA;
- bool m_boolTest;
- int16_t m_int16;
- int16_t m_int16WithBounds;
- int16_t m_int16SetGet;
- uint8_t m_uint8;
- float m_float;
- enum Test_e m_enum;
- RandomVariable m_random;
- std::vector<Ptr<Derived> > m_vector1;
- std::vector<Ptr<Derived> > m_vector2;
- Callback<void,int8_t> m_cbValue;
- TracedValue<int8_t> m_intSrc1;
- TracedValue<int8_t> m_intSrc2;
- TracedCallback<double, int, float> m_cb;
- TracedValue<ValueClassTest> m_valueSrc;
- Ptr<Derived> m_ptr;
-};
-
-
-#define CHECK_GET_STR(p,name,value) \
- { \
- std::string expected = value; \
- StringValue got; \
- bool ok = p->GetAttributeFailSafe (name, got); \
- NS_TEST_ASSERT (ok); \
- NS_TEST_ASSERT_EQUAL (got.Get (), expected); \
- }
-#define CHECK_GET_PARAM(p,name,type,value) \
- { \
- const type expected = value; \
- type got; \
- bool ok = p->GetAttributeFailSafe (name, got); \
- NS_TEST_ASSERT (ok); \
- NS_TEST_ASSERT_EQUAL (got.Get (), expected.Get ()); \
- }
-
-NS_OBJECT_ENSURE_REGISTERED (AttributeObjectTest);
-
-AttributeTest::AttributeTest ()
- : Test ("Attribute")
-{}
-bool
-AttributeTest::RunTests (void)
-{
- bool result = true;
-
- AttributeList params;
- Ptr<AttributeObjectTest> p;
- NS_TEST_ASSERT (params.SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("false")));
- p = CreateObjectWithAttributes<AttributeObjectTest> (params);
- CHECK_GET_STR (p, "TestBoolName", "false");
- CHECK_GET_PARAM (p, "TestBoolName", BooleanValue, false);
-
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestBoolName", StringValue ("true")));
- CHECK_GET_STR (p, "TestBoolName", "true");
- CHECK_GET_PARAM (p, "TestBoolName", BooleanValue, true);
-
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestBoolName", BooleanValue (false)));
- CHECK_GET_STR (p, "TestBoolName", "false");
- CHECK_GET_PARAM (p, "TestBoolName", BooleanValue, false);
-
- p = CreateObjectWithAttributes<AttributeObjectTest> ("TestBoolName", StringValue ("true"));
- CHECK_GET_STR (p, "TestBoolName", "true");
- CHECK_GET_PARAM (p, "TestBoolName", BooleanValue, true);
-
- p = CreateObjectWithAttributes<AttributeObjectTest> ("TestBoolName", BooleanValue (true));
- CHECK_GET_STR (p, "TestBoolName", "true");
- CHECK_GET_PARAM (p, "TestBoolName", BooleanValue, true);
-
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestBoolA", StringValue ("false")));
- CHECK_GET_STR (p, "TestBoolA", "false");
- CHECK_GET_PARAM (p, "TestBoolA", BooleanValue, false);
-
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestBoolA", StringValue ("true")));
- CHECK_GET_STR (p, "TestBoolA", "true");
- CHECK_GET_PARAM (p, "TestBoolA", BooleanValue, true);
-
-
- CHECK_GET_STR (p, "TestInt16", "-2");
- CHECK_GET_PARAM (p, "TestInt16", IntegerValue, -2);
-
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16", StringValue ("-5")));
- CHECK_GET_STR (p, "TestInt16", "-5");
- CHECK_GET_PARAM (p, "TestInt16", IntegerValue, -5);
-
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16", IntegerValue (+2)));
- CHECK_GET_STR (p, "TestInt16", "2");
- CHECK_GET_PARAM (p, "TestInt16", IntegerValue, +2);
-
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16", IntegerValue (-32768)));
- CHECK_GET_STR (p, "TestInt16", "-32768");
- CHECK_GET_PARAM (p, "TestInt16", IntegerValue, -32768);
-
- NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestInt16", IntegerValue (-32769)));
- CHECK_GET_STR (p, "TestInt16", "-32768");
- CHECK_GET_PARAM (p, "TestInt16", IntegerValue, -32768);
-
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16", IntegerValue (32767)));
- CHECK_GET_STR (p, "TestInt16", "32767");
- CHECK_GET_PARAM (p, "TestInt16", IntegerValue, 32767);
-
- NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestInt16", IntegerValue (32768)));
- CHECK_GET_STR (p, "TestInt16", "32767");
- CHECK_GET_PARAM (p, "TestInt16", IntegerValue, 32767);
-
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue (10)));
- CHECK_GET_STR (p, "TestInt16WithBounds", "10");
- CHECK_GET_PARAM (p, "TestInt16WithBounds", IntegerValue, 10);
- NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue (11)));
- CHECK_GET_STR (p, "TestInt16WithBounds", "10");
- CHECK_GET_PARAM (p, "TestInt16WithBounds", IntegerValue, 10);
-
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue (-5)));
- CHECK_GET_STR (p, "TestInt16WithBounds", "-5");
- CHECK_GET_PARAM (p, "TestInt16WithBounds", IntegerValue, -5);
- NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue (-6)));
- CHECK_GET_STR (p, "TestInt16WithBounds", "-5");
- CHECK_GET_PARAM (p, "TestInt16WithBounds", IntegerValue, -5);
-
- CHECK_GET_STR (p, "TestInt16SetGet", "6");
- CHECK_GET_PARAM (p, "TestInt16SetGet", IntegerValue, 6);
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16SetGet", IntegerValue (0)));
- CHECK_GET_STR (p, "TestInt16SetGet", "0");
- CHECK_GET_PARAM (p, "TestInt16SetGet", IntegerValue, 0);
-
- CHECK_GET_STR (p, "TestUint8", "1");
- CHECK_GET_PARAM (p, "TestUint8", UintegerValue, 1);
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestUint8", UintegerValue (0)));
- CHECK_GET_STR (p, "TestUint8", "0");
- CHECK_GET_PARAM (p, "TestUint8", UintegerValue, 0);
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestUint8", UintegerValue (255)));
- CHECK_GET_STR (p, "TestUint8", "255");
- CHECK_GET_PARAM (p, "TestUint8", UintegerValue, 255);
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestUint8", StringValue ("255")));
- CHECK_GET_STR (p, "TestUint8", "255");
- CHECK_GET_PARAM (p, "TestUint8", UintegerValue, 255);
- NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestUint8", StringValue ("256")));
- CHECK_GET_STR (p, "TestUint8", "255");
- CHECK_GET_PARAM (p, "TestUint8", UintegerValue, 255);
- NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestUint8", StringValue ("-1")));
- CHECK_GET_STR (p, "TestUint8", "255");
- CHECK_GET_PARAM (p, "TestUint8", UintegerValue, 255);
- NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestUint8", UintegerValue ((uint64_t)-1)));
- CHECK_GET_STR (p, "TestUint8", "255");
- CHECK_GET_PARAM (p, "TestUint8", UintegerValue, 255);
-
- CHECK_GET_STR (p, "TestFloat", "-1.1");
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestFloat", DoubleValue ((float)+2.3)));
- CHECK_GET_PARAM (p, "TestFloat", DoubleValue, (float)+2.3);
-
- CHECK_GET_STR (p, "TestEnum", "TestA");
- CHECK_GET_PARAM (p, "TestEnum", EnumValue, AttributeObjectTest::TEST_A);
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestEnum", EnumValue (AttributeObjectTest::TEST_C)));
- CHECK_GET_STR (p, "TestEnum", "TestC");
- CHECK_GET_PARAM (p, "TestEnum", EnumValue, AttributeObjectTest::TEST_C);
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestEnum", StringValue ("TestB")));
- CHECK_GET_STR (p, "TestEnum", "TestB");
- CHECK_GET_PARAM (p, "TestEnum", EnumValue, AttributeObjectTest::TEST_B);
- NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestEnum", StringValue ("TestD")));
- CHECK_GET_STR (p, "TestEnum", "TestB");
- CHECK_GET_PARAM (p, "TestEnum", EnumValue, AttributeObjectTest::TEST_B);
- NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestEnum", EnumValue (5)));
- CHECK_GET_STR (p, "TestEnum", "TestB");
- CHECK_GET_PARAM (p, "TestEnum", EnumValue, AttributeObjectTest::TEST_B);
-
- RandomVariableValue ran;
- p->GetAttribute ("TestRandom", ran);
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestRandom", RandomVariableValue (UniformVariable (0.0, 1.0))));
- NS_TEST_ASSERT (p->SetAttributeFailSafe("TestRandom", RandomVariableValue (ConstantVariable (10.0))));
-
- {
- ObjectVectorValue vector;
- p->GetAttribute ("TestVector1", vector);
- NS_TEST_ASSERT_EQUAL (vector.GetN (), 0);
- p->AddToVector1 ();
- NS_TEST_ASSERT_EQUAL (vector.GetN (), 0);
- p->GetAttribute ("TestVector1", vector);
- NS_TEST_ASSERT_EQUAL (vector.GetN (), 1);
- Ptr<Object> a = vector.Get (0);
- NS_TEST_ASSERT_UNEQUAL (a, 0);
- p->AddToVector1 ();
- NS_TEST_ASSERT_EQUAL (vector.GetN (), 1);
- p->GetAttribute ("TestVector1", vector);
- NS_TEST_ASSERT_EQUAL (vector.GetN (), 2);
- }
-
- {
- ObjectVectorValue vector;
- p->GetAttribute ("TestVector2", vector);
- NS_TEST_ASSERT_EQUAL (vector.GetN (), 0);
- p->AddToVector2 ();
- NS_TEST_ASSERT_EQUAL (vector.GetN (), 0);
- p->GetAttribute ("TestVector2", vector);
- NS_TEST_ASSERT_EQUAL (vector.GetN (), 1);
- Ptr<Object> a = vector.Get (0);
- NS_TEST_ASSERT_UNEQUAL (a, 0);
- p->AddToVector2 ();
- NS_TEST_ASSERT_EQUAL (vector.GetN (), 1);
- p->GetAttribute ("TestVector2", vector);
- NS_TEST_ASSERT_EQUAL (vector.GetN (), 2);
- }
-
- NS_TEST_ASSERT (AttributeList::GetGlobal ()->SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("true")));
- p = CreateObject<AttributeObjectTest> ();
- BooleanValue boolV;
- p->GetAttribute ("TestBoolName", boolV);
- NS_TEST_ASSERT_EQUAL (boolV.Get (), true);
-
- NS_TEST_ASSERT (AttributeList::GetGlobal ()->SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("false")));
- p = CreateObject<AttributeObjectTest> ();
- p->GetAttribute ("TestBoolName", boolV);
- NS_TEST_ASSERT_EQUAL (boolV.Get (), false);
-
- IntegerValue i;
- p->GetAttribute ("IntegerTraceSource1", i);
- NS_TEST_ASSERT_EQUAL (i.Get (), -2);
- NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (+5)));
- p->GetAttribute ("IntegerTraceSource1", i);
- NS_TEST_ASSERT_EQUAL (i.Get (), +5);
- NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (127)));
- NS_TEST_ASSERT (!p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (128)));
- NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (-128)));
- NS_TEST_ASSERT (!p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (-129)));
-
- p->GetAttribute ("IntegerTraceSource2", i);
- NS_TEST_ASSERT_EQUAL (i.Get (), -2);
- NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (+5)));
- p->GetAttribute ("IntegerTraceSource2", i);
- NS_TEST_ASSERT_EQUAL (i.Get (), +5);
- NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (127)));
- NS_TEST_ASSERT (!p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (128)));
- NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (-128)));
- NS_TEST_ASSERT (!p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (-129)));
-
- m_got1 = -2;
- NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (-1)));
- NS_TEST_ASSERT (p->TraceConnectWithoutContext ("Source1", MakeCallback (&AttributeTest::NotifySource1, this)));
- NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (0)));
- NS_TEST_ASSERT_EQUAL (m_got1, 0);
- NS_TEST_ASSERT (p->TraceDisconnectWithoutContext ("Source1", MakeCallback (&AttributeTest::NotifySource1, this)));
- NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (1)));
- NS_TEST_ASSERT_EQUAL (m_got1, 0);
-
- m_got2 = 4.3;
- p->InvokeCb (1.0, -5, 0.0);
- NS_TEST_ASSERT_EQUAL (m_got2, 4.3);
- NS_TEST_ASSERT (p->TraceConnectWithoutContext ("Source2", MakeCallback (&AttributeTest::NotifySource2, this)));
- NS_TEST_ASSERT_EQUAL (m_got2, 4.3);
- p->InvokeCb (1.0, -5, 0.0);
- NS_TEST_ASSERT_EQUAL (m_got2, 1.0);
- NS_TEST_ASSERT (p->TraceDisconnectWithoutContext ("Source2", MakeCallback (&AttributeTest::NotifySource2, this)));
- p->InvokeCb (-1.0, -5, 0.0);
- NS_TEST_ASSERT_EQUAL (m_got2, 1.0);
-
- NS_TEST_ASSERT (p->TraceConnectWithoutContext ("ValueSource", MakeCallback (&AttributeTest::NotifySourceValue, this)));
-
- PointerValue ptr;
- p->GetAttribute ("Pointer", ptr);
- Ptr<Derived> derived = ptr.Get<Derived> ();
- NS_TEST_ASSERT (derived == 0);
- derived = Create<Derived> ();
- NS_TEST_ASSERT (p->SetAttributeFailSafe("Pointer", PointerValue (derived)));
- p->GetAttribute ("Pointer", ptr);
- Ptr<Derived> stored = ptr.Get<Derived> ();
- NS_TEST_ASSERT (stored == derived);
- p->GetAttribute ("Pointer", ptr);
- Ptr<Object> storedBase = ptr.Get<Object> ();
- NS_TEST_ASSERT (stored == storedBase);
- p->GetAttribute ("Pointer", ptr);
- Ptr<AttributeObjectTest> x = ptr.Get<AttributeObjectTest> ();
- NS_TEST_ASSERT (x == 0);
-
- p = CreateObjectWithAttributes<AttributeObjectTest> ("Pointer", PointerValue (Create<Derived> ()));
- NS_TEST_ASSERT (p != 0);
- derived = 0;
- p->GetAttribute ("Pointer", ptr);
- derived = ptr.Get<Derived> ();
- NS_TEST_ASSERT (derived != 0);
-
- p = CreateObject<AttributeObjectTest> ();
- NS_TEST_ASSERT (p != 0);
- m_gotCbValue = 1;
- p->InvokeCbValue (2);
- CallbackValue cbValue = MakeCallback (&AttributeTest::NotifyCallbackValue, this);
- NS_TEST_ASSERT_EQUAL (m_gotCbValue, 1);
- NS_TEST_ASSERT (p->SetAttributeFailSafe ("Callback",
- cbValue));
- p->InvokeCbValue (2);
- NS_TEST_ASSERT_EQUAL (m_gotCbValue, 2);
- NS_TEST_ASSERT (p->SetAttributeFailSafe ("Callback",
- CallbackValue (MakeNullCallback<void,int8_t> ())));
- p->InvokeCbValue (3);
- NS_TEST_ASSERT_EQUAL (m_gotCbValue, 2);
-
- return result;
-}
-
-
-
-static AttributeTest g_parameterTest;
-
-} // namespace ns3
-
-
-#endif /* RUN_SELF_TESTS */
--- a/src/core/test.cc Mon Sep 21 11:21:05 2009 -0700
+++ b/src/core/test.cc Wed Sep 23 15:20:23 2009 -0700
@@ -22,6 +22,36 @@
namespace ns3 {
+
+//
+// XML files have restrictions on certain characters that may be present in
+// data. We need to replace these characters with their alternate
+// representation on the way into the XML file.
+//
+std::string
+ReplaceXmlSpecialCharacters (std::string xml)
+{
+ std::string specials = "<>&\"'";
+ std::string replacements[] = {"<", ">", "&", "'", """};
+ std::string result;
+ std::size_t index, length = xml.length ();
+
+ for (size_t i = 0; i < length; ++i)
+ {
+ char character = xml[i];
+
+ if ((index = specials.find (character)) == std::string::npos)
+ {
+ result.push_back (character);
+ }
+ else
+ {
+ result += replacements[index];
+ }
+ }
+ return result;
+}
+
bool
TestDoubleIsEqual (const double x1, const double x2, const double epsilon)
{
@@ -180,7 +210,7 @@
return;
}
*m_ofs << " <TestCase>" << std::endl;
- *m_ofs << " <CaseName>" << GetName () << "</CaseName>" << std::endl;
+ *m_ofs << " <CaseName>" << ReplaceXmlSpecialCharacters (GetName ()) << "</CaseName>" << std::endl;
}
void
@@ -202,18 +232,20 @@
std::string file,
int32_t line)
{
+ m_error |= true;
+
if (m_ofs == 0)
{
return;
}
+
*m_ofs << " <CaseResult>FAIL</CaseResult>" << std::endl;
- *m_ofs << " <CaseCondition>" << cond << "</CaseCondition>" << std::endl;
- *m_ofs << " <CaseActual>" << actual << "</CaseActual>" << std::endl;
- *m_ofs << " <CaseLimit>" << limit << "</CaseLimit>" << std::endl;
- *m_ofs << " <CaseMessage>" << message << "</CaseMessage>" << std::endl;
- *m_ofs << " <CaseFile>" << file << "</CaseFile>" << std::endl;
+ *m_ofs << " <CaseCondition>" << ReplaceXmlSpecialCharacters (cond) << "</CaseCondition>" << std::endl;
+ *m_ofs << " <CaseActual>" << ReplaceXmlSpecialCharacters (actual) << "</CaseActual>" << std::endl;
+ *m_ofs << " <CaseLimit>" << ReplaceXmlSpecialCharacters (limit) << "</CaseLimit>" << std::endl;
+ *m_ofs << " <CaseMessage>" << ReplaceXmlSpecialCharacters (message) << "</CaseMessage>" << std::endl;
+ *m_ofs << " <CaseFile>" << ReplaceXmlSpecialCharacters (file) << "</CaseFile>" << std::endl;
*m_ofs << " <CaseLine>" << line << "</CaseLine>" << std::endl;
- m_error |= true;
}
void
@@ -387,7 +419,7 @@
return;
}
*m_ofs << "<TestSuite>" << std::endl;
- *m_ofs << " <SuiteName>" << GetName () << "</SuiteName>" << std::endl;
+ *m_ofs << " <SuiteName>" << ReplaceXmlSpecialCharacters (GetName ()) << "</SuiteName>" << std::endl;
}
void
--- a/src/core/test.h Mon Sep 21 11:21:05 2009 -0700
+++ b/src/core/test.h Wed Sep 23 15:20:23 2009 -0700
@@ -47,6 +47,12 @@
#define NS_TEST_SOURCEDIR \
TestCase::GetSourceDir (__FILE__)
+#define NS_TEST_RETURN_IF_ERROR \
+ if (GetErrorStatus ()) \
+ { \
+ return true; \
+ }
+
// ===========================================================================
// Test for equality (generic version)
// ===========================================================================
@@ -64,7 +70,7 @@
actualStream << actual; \
std::ostringstream limitStream; \
limitStream << limit; \
- ReportFailure (std::string (#actual) + " (actual) EQ " + std::string (#limit) + " (limit)", \
+ ReportFailure (std::string (#actual) + " (actual) == " + std::string (#limit) + " (limit)", \
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
return true; \
} \
@@ -115,7 +121,7 @@
actualStream << actual; \
std::ostringstream limitStream; \
limitStream << limit; \
- ReportFailure (std::string (#actual) + " (actual) EQ " + std::string (#limit) + " (limit)", \
+ ReportFailure (std::string (#actual) + " (actual) == " + std::string (#limit) + " (limit)", \
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
} \
} while (false)
@@ -168,8 +174,8 @@
std::ostringstream limitStream; \
limitStream << limit << " +- " << tol; \
std::ostringstream condStream; \
- condStream << #actual << " (actual) LT " << #limit << " (limit) + " << #tol << " (tol) AND " << \
- #actual << " (actual) GT " << #limit << " (limit) - " << #tol << " (tol)"; \
+ condStream << #actual << " (actual) < " << #limit << " (limit) + " << #tol << " (tol) && " << \
+ #actual << " (actual) > " << #limit << " (limit) - " << #tol << " (tol)"; \
ReportFailure (condStream.str (), actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
return true; \
} \
@@ -243,8 +249,8 @@
std::ostringstream limitStream; \
limitStream << limit << " +- " << tol; \
std::ostringstream condStream; \
- condStream << #actual << " (actual) LT " << #limit << " (limit) + " << #tol << " (tol) AND " << \
- #actual << " (actual) GT " << #limit << " (limit) - " << #tol << " (tol)"; \
+ condStream << #actual << " (actual) < " << #limit << " (limit) + " << #tol << " (tol) && " << \
+ #actual << " (actual) > " << #limit << " (limit) - " << #tol << " (tol)"; \
ReportFailure (condStream.str (), actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
} \
} while (false)
@@ -317,7 +323,7 @@
actualStream << actual; \
std::ostringstream limitStream; \
limitStream << limit; \
- ReportFailure (std::string (#actual) + " (actual) NE " + std::string (#limit) + " (limit)", \
+ ReportFailure (std::string (#actual) + " (actual) != " + std::string (#limit) + " (limit)", \
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
return true; \
} \
@@ -367,7 +373,7 @@
actualStream << actual; \
std::ostringstream limitStream; \
limitStream << limit; \
- ReportFailure (std::string (#actual) + " (actual) NE " + std::string (#limit) + " (limit)", \
+ ReportFailure (std::string (#actual) + " (actual) != " + std::string (#limit) + " (limit)", \
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
} \
} while (false)
@@ -417,7 +423,7 @@
actualStream << actual; \
std::ostringstream limitStream; \
limitStream << limit; \
- ReportFailure (std::string (#actual) + " (actual) LT " + std::string (#limit) + " (limit)", \
+ ReportFailure (std::string (#actual) + " (actual) < " + std::string (#limit) + " (limit)", \
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
return true; \
} \
@@ -457,7 +463,7 @@
actualStream << actual; \
std::ostringstream limitStream; \
limitStream << limit; \
- ReportFailure (std::string (#actual) + " (actual) LT " + std::string (#limit) + " (limit)", \
+ ReportFailure (std::string (#actual) + " (actual) < " + std::string (#limit) + " (limit)", \
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
} \
} while (false)
@@ -496,7 +502,7 @@
actualStream << actual; \
std::ostringstream limitStream; \
limitStream << limit; \
- ReportFailure (std::string (#actual) + " (actual) GT " + std::string (#limit) + " (limit)", \
+ ReportFailure (std::string (#actual) + " (actual) > " + std::string (#limit) + " (limit)", \
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
return true; \
} \
@@ -536,7 +542,7 @@
actualStream << actual; \
std::ostringstream limitStream; \
limitStream << limit; \
- ReportFailure (std::string (#actual) + " (actual) GT " + std::string (#limit) + " (limit)", \
+ ReportFailure (std::string (#actual) + " (actual) > " + std::string (#limit) + " (limit)", \
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
} \
} while (false)
--- a/src/core/wscript Mon Sep 21 11:21:05 2009 -0700
+++ b/src/core/wscript Wed Sep 23 15:20:23 2009 -0700
@@ -70,7 +70,6 @@
'string.cc',
'pointer.cc',
'object-vector.cc',
- 'attribute-test.cc',
'object-factory.cc',
'global-value.cc',
'traced-callback.cc',
@@ -80,6 +79,7 @@
'names.cc',
'vector.cc',
'names-test-suite.cc',
+ 'attribute-test-suite.cc',
]
headers = bld.new_task_gen('ns3header')
--- a/test.py Mon Sep 21 11:21:05 2009 -0700
+++ b/test.py Wed Sep 23 15:20:23 2009 -0700
@@ -27,6 +27,7 @@
import signal
import random
import xml.dom.minidom
+import shutil
#
# XXX This should really be part of a waf command to list the configuration
@@ -805,8 +806,9 @@
else:
f = open(xml_results_file, 'a')
f.write("<TestSuite>\n")
- f.write(" <Name>%s</Name>\n" % job.display_name)
- f.write(' <Result>CRASH</Result>\n')
+ f.write(" <SuiteName>%s</SuiteName>\n" % job.display_name)
+ f.write(' <SuiteResult>CRASH</SuiteResult>\n')
+ f.write(' <SuiteTime>Execution times not available</SuiteTime>\n')
f.write("</TestSuite>\n")
f.close()
@@ -832,7 +834,7 @@
#
# The last things to do are to translate the XML results file to "human
- # readable form" if the user asked for it
+ # readable form" if the user asked for it (or make an XML file somewhere)
#
if len(options.html):
translate_to_html(xml_results_file, options.html)
@@ -840,6 +842,9 @@
if len(options.text):
translate_to_text(xml_results_file, options.text)
+ if len(options.xml):
+ shutil.copyfile(xml_results_file, options.xml)
+
def main(argv):
random.seed()
@@ -876,6 +881,10 @@
metavar="TEXT-FILE",
help="write detailed test results into TEXT-FILE.txt")
+ parser.add_option("-x", "--xml", action="store", type="string", dest="xml", default="",
+ metavar="XML-FILE",
+ help="write detailed test results into XML-FILE.xml")
+
global options
options = parser.parse_args()[0]
signal.signal(signal.SIGINT, sigint_hook)