From a0ab62ad90de4608094b211d9f73fe64701d121a Mon Sep 17 00:00:00 2001 From: Mitch Watrous Date: Wed, 6 Apr 2011 15:32:12 -0700 Subject: [PATCH] Move tests from core module to its test library and update CHANGES.html --- CHANGES.html | 5 + src/core/model/command-line.cc | 199 ------- src/core/model/config.cc | 584 ------------------ src/core/model/global-value.cc | 68 --- src/core/model/object.cc | 405 ------------- src/core/model/random-variable.cc | 115 ---- src/core/test/command-line-test-suite.cc | 230 ++++++++ src/core/test/config-test-suite.cc | 617 ++++++++++++++++++++ src/core/test/global-value-test-suite.cc | 94 +++ src/core/test/object-test-suite.cc | 429 ++++++++++++++ src/core/test/random-variable-test-suite.cc | 147 +++++ src/core/wscript | 6 + 12 files changed, 1528 insertions(+), 1371 deletions(-) create mode 100644 src/core/test/command-line-test-suite.cc create mode 100644 src/core/test/config-test-suite.cc create mode 100644 src/core/test/global-value-test-suite.cc create mode 100644 src/core/test/object-test-suite.cc create mode 100644 src/core/test/random-variable-test-suite.cc diff --git a/CHANGES.html b/CHANGES.html index 1b002f460..34a35e960 100644 --- a/CHANGES.html +++ b/CHANGES.html @@ -62,6 +62,11 @@ You can now make tests be built in ns-3 in two ways.

+
  • Subsets of modules can be enabled using the ns-3 configuration file +

    A new configuration file, .ns3rc, has been added to ns-3 that +specifies the modules that should be enabled during the ns-3 build. +See the documentation for details. +

  • New API:

    diff --git a/src/core/model/command-line.cc b/src/core/model/command-line.cc index 93384eb99..e6fc00cb0 100644 --- a/src/core/model/command-line.cc +++ b/src/core/model/command-line.cc @@ -22,7 +22,6 @@ #include "config.h" #include "global-value.h" #include "type-id.h" -#include "test.h" #include "string.h" #include #include @@ -306,202 +305,4 @@ CommandLine::AddValue (const std::string &name, m_items.push_back (item); } -// =========================================================================== -// A test base class that drives Command Line parsing -// =========================================================================== -class CommandLineTestCaseBase : public TestCase -{ -public: - CommandLineTestCaseBase (std::string description); - virtual ~CommandLineTestCaseBase () {} - - void Parse (const CommandLine &cmd, int n, ...); -}; - -CommandLineTestCaseBase::CommandLineTestCaseBase (std::string description) - : TestCase (description) -{ -} - -void -CommandLineTestCaseBase::Parse (const CommandLine &cmd, int n, ...) -{ - char **args = new char* [n+1]; - args[0] = (char *) "Test"; - va_list ap; - va_start (ap, n); - int i = 0; - while (i < n) - { - char *arg = va_arg (ap, char *); - args[i+1] = arg; - i++; - } - int argc = n + 1; - cmd.Parse (argc, args); - delete [] args; -} - -// =========================================================================== -// Test boolean Command Line processing -// =========================================================================== -class CommandLineBooleanTestCase : public CommandLineTestCaseBase -{ -public: - CommandLineBooleanTestCase (); - virtual ~CommandLineBooleanTestCase () {} - -private: - virtual void DoRun (void); - -}; - -CommandLineBooleanTestCase::CommandLineBooleanTestCase () - : CommandLineTestCaseBase ("Check boolean arguments") -{ -} - -void -CommandLineBooleanTestCase::DoRun (void) -{ - CommandLine cmd; - bool myBool = true; - - cmd.AddValue ("my-bool", "help", myBool); - - Parse (cmd, 1, "--my-bool=0"); - NS_TEST_ASSERT_MSG_EQ (myBool, false, "Command parser did not correctly set a boolean value to false"); - - Parse (cmd, 1, "--my-bool=1"); - NS_TEST_ASSERT_MSG_EQ (myBool, true, "Command parser did not correctly set a boolean value to true"); -} - -// =========================================================================== -// Test int Command Line processing -// =========================================================================== -class CommandLineIntTestCase : public CommandLineTestCaseBase -{ -public: - CommandLineIntTestCase (); - virtual ~CommandLineIntTestCase () {} - -private: - virtual void DoRun (void); - -}; - -CommandLineIntTestCase::CommandLineIntTestCase () - : CommandLineTestCaseBase ("Check int arguments") -{ -} - -void -CommandLineIntTestCase::DoRun (void) -{ - CommandLine cmd; - bool myBool = true; - int32_t myInt32 = 10; - - cmd.AddValue ("my-bool", "help", myBool); - cmd.AddValue ("my-int32", "help", myInt32); - - Parse (cmd, 2, "--my-bool=0", "--my-int32=-3"); - NS_TEST_ASSERT_MSG_EQ (myBool, false, "Command parser did not correctly set a boolean value to false"); - NS_TEST_ASSERT_MSG_EQ (myInt32, -3, "Command parser did not correctly set an integer value to -3"); - - Parse (cmd, 2, "--my-bool=1", "--my-int32=+2"); - NS_TEST_ASSERT_MSG_EQ (myBool, true, "Command parser did not correctly set a boolean value to true"); - NS_TEST_ASSERT_MSG_EQ (myInt32, +2, "Command parser did not correctly set an integer value to +2"); -} - -// =========================================================================== -// Test unsigned int Command Line processing -// =========================================================================== -class CommandLineUnsignedIntTestCase : public CommandLineTestCaseBase -{ -public: - CommandLineUnsignedIntTestCase (); - virtual ~CommandLineUnsignedIntTestCase () {} - -private: - virtual void DoRun (void); - -}; - -CommandLineUnsignedIntTestCase::CommandLineUnsignedIntTestCase () - : CommandLineTestCaseBase ("Check unsigned int arguments") -{ -} - -void -CommandLineUnsignedIntTestCase::DoRun (void) -{ - CommandLine cmd; - bool myBool = true; - uint32_t myUint32 = 10; - - cmd.AddValue ("my-bool", "help", myBool); - cmd.AddValue ("my-uint32", "help", myUint32); - - Parse (cmd, 2, "--my-bool=0", "--my-uint32=9"); - - NS_TEST_ASSERT_MSG_EQ (myBool, false, "Command parser did not correctly set a boolean value to true"); - NS_TEST_ASSERT_MSG_EQ (myUint32, 9, "Command parser did not correctly set an unsigned integer value to 9"); -} - -// =========================================================================== -// Test string Command Line processing -// =========================================================================== -class CommandLineStringTestCase : public CommandLineTestCaseBase -{ -public: - CommandLineStringTestCase (); - virtual ~CommandLineStringTestCase () {} - -private: - virtual void DoRun (void); - -}; - -CommandLineStringTestCase::CommandLineStringTestCase () - : CommandLineTestCaseBase ("Check unsigned int arguments") -{ -} - -void -CommandLineStringTestCase::DoRun (void) -{ - CommandLine cmd; - uint32_t myUint32 = 10; - std::string myStr = "MyStr"; - - cmd.AddValue ("my-uint32", "help", myUint32); - cmd.AddValue ("my-str", "help", myStr); - - Parse (cmd, 2, "--my-uint32=9", "--my-str=XX"); - - NS_TEST_ASSERT_MSG_EQ (myUint32, 9, "Command parser did not correctly set an unsigned integer value to 9"); - NS_TEST_ASSERT_MSG_EQ (myStr, "XX", "Command parser did not correctly set an string value to \"XX\""); -} - -// =========================================================================== -// The Test Suite that glues all of the Test Cases together. -// =========================================================================== -class CommandLineTestSuite : public TestSuite -{ -public: - CommandLineTestSuite (); -}; - -CommandLineTestSuite::CommandLineTestSuite () - : TestSuite ("command-line", BVT) -{ - AddTestCase (new CommandLineBooleanTestCase); - AddTestCase (new CommandLineIntTestCase); - AddTestCase (new CommandLineUnsignedIntTestCase); - AddTestCase (new CommandLineStringTestCase); -} - -static CommandLineTestSuite CommandLineTestSuite; - } // namespace ns3 diff --git a/src/core/model/config.cc b/src/core/model/config.cc index f124e8bdb..85a32f05c 100644 --- a/src/core/model/config.cc +++ b/src/core/model/config.cc @@ -26,12 +26,6 @@ #include "pointer.h" #include "log.h" -#include "test.h" -#include "integer.h" -#include "traced-value.h" -#include "trace-source-accessor.h" -#include "callback.h" - #include NS_LOG_COMPONENT_DEFINE ("Config"); @@ -654,582 +648,4 @@ Ptr GetRootNamespaceObject (uint32_t i) } // namespace Config -// =========================================================================== -// An object with some attributes that we can play with using config. -// =========================================================================== -class ConfigTestObject : public Object -{ -public: - static TypeId GetTypeId (void); - - void AddNodeA (Ptr a); - void AddNodeB (Ptr b); - - void SetNodeA (Ptr a); - void SetNodeB (Ptr b); - - int8_t GetA (void) const; - int8_t GetB (void) const; - -private: - std::vector > m_nodesA; - std::vector > m_nodesB; - Ptr m_nodeA; - Ptr m_nodeB; - int8_t m_a; - int8_t m_b; - TracedValue m_trace; -}; - -TypeId -ConfigTestObject::GetTypeId (void) -{ - static TypeId tid = TypeId ("ConfigTestObject") - .SetParent () - .AddAttribute ("NodesA", "", - ObjectVectorValue (), - MakeObjectVectorAccessor (&ConfigTestObject::m_nodesA), - MakeObjectVectorChecker ()) - .AddAttribute ("NodesB", "", - ObjectVectorValue (), - MakeObjectVectorAccessor (&ConfigTestObject::m_nodesB), - MakeObjectVectorChecker ()) - .AddAttribute ("NodeA", "", - PointerValue (), - MakePointerAccessor (&ConfigTestObject::m_nodeA), - MakePointerChecker ()) - .AddAttribute ("NodeB", "", - PointerValue (), - MakePointerAccessor (&ConfigTestObject::m_nodeB), - MakePointerChecker ()) - .AddAttribute ("A", "", - IntegerValue (10), - MakeIntegerAccessor (&ConfigTestObject::m_a), - MakeIntegerChecker ()) - .AddAttribute ("B", "", - IntegerValue (9), - MakeIntegerAccessor (&ConfigTestObject::m_b), - MakeIntegerChecker ()) - .AddAttribute ("Source", "XX", - IntegerValue (-1), - MakeIntegerAccessor (&ConfigTestObject::m_trace), - MakeIntegerChecker ()) - .AddTraceSource ("Source", "XX", - MakeTraceSourceAccessor (&ConfigTestObject::m_trace)) - ; - return tid; -} - -void -ConfigTestObject::SetNodeA (Ptr a) -{ - m_nodeA = a; -} - -void -ConfigTestObject::SetNodeB (Ptr b) -{ - m_nodeB = b; -} - -void -ConfigTestObject::AddNodeA (Ptr a) -{ - m_nodesA.push_back (a); -} - -void -ConfigTestObject::AddNodeB (Ptr b) -{ - m_nodesB.push_back (b); -} - -int8_t -ConfigTestObject::GetA (void) const -{ - return m_a; -} - -int8_t -ConfigTestObject::GetB (void) const -{ - return m_b; -} - -// =========================================================================== -// Test for the ability to register and use a root namespace -// =========================================================================== -class RootNamespaceConfigTestCase : public TestCase -{ -public: - RootNamespaceConfigTestCase (); - virtual ~RootNamespaceConfigTestCase () {} - -private: - virtual void DoRun (void); -}; - -RootNamespaceConfigTestCase::RootNamespaceConfigTestCase () - : TestCase ("Check ability to register a root namespace and use it") -{ -} - -void -RootNamespaceConfigTestCase::DoRun (void) -{ - IntegerValue iv; - // - // Create an object and register its attributes directly in the root - // namespace. - // - Ptr root = CreateObject (); - Config::RegisterRootNamespaceObject (root); - - // - // We should find the default values there. - // - root->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" not initialized as expected"); - - // - // Now use the config mechanism to set the attribute; and we should find the - // new value. - // - Config::Set ("/A", IntegerValue (1)); - root->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 1, "Object Attribute \"A\" not set correctly"); - - // - // We should find the default values of "B" too. - // - root->GetAttribute ("B", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 9, "Object Attribute \"B\" not initialized as expected"); - - // - // Now use the config mechanism to set the attribute; and we should find the - // new value. - // - Config::Set ("/B", IntegerValue (-1)); - root->GetAttribute ("B", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -1, "Object Attribute \"B\" not set correctly"); -} - -// =========================================================================== -// Test for the ability to add an object under the root namespace. -// =========================================================================== -class UnderRootNamespaceConfigTestCase : public TestCase -{ -public: - UnderRootNamespaceConfigTestCase (); - virtual ~UnderRootNamespaceConfigTestCase () {} - -private: - virtual void DoRun (void); -}; - -UnderRootNamespaceConfigTestCase::UnderRootNamespaceConfigTestCase () - : TestCase ("Check ability to register an object under the root namespace and use it") -{ -} - -void -UnderRootNamespaceConfigTestCase::DoRun (void) -{ - IntegerValue iv; - // - // Create an object and register its attributes directly in the root - // namespace. - // - Ptr root = CreateObject (); - Config::RegisterRootNamespaceObject (root); - - Ptr a = CreateObject (); - root->SetNodeA (a); - - // - // We should find the default values there. - // - a->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" not initialized as expected"); - - // - // Now use the config mechanism to set the attribute; and we should find the - // new value. - // - Config::Set ("/NodeA/A", IntegerValue (1)); - a->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 1, "Object Attribute \"A\" not set correctly"); - - // - // We should find the default values of "B" too. - // - a->GetAttribute ("B", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 9, "Object Attribute \"B\" not initialized as expected"); - - // - // Now use the config mechanism to set the attribute; and we should find the - // new value. - // - Config::Set ("/NodeA/B", IntegerValue (-1)); - a->GetAttribute ("B", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -1, "Object Attribute \"B\" not set correctly"); - - // - // Try and set through a nonexistent path. Should do nothing. - // - Config::Set ("/NodeB/A", IntegerValue (1234)); - a->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 1, "Object Attribute \"A\" unexpectedly set via bad path"); - - Config::Set ("/NodeB/B", IntegerValue (1234)); - a->GetAttribute ("B", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -1, "Object Attribute \"B\" unexpectedly set via bad path"); - - // - // Step down one level of recursion and try again - // - Ptr b = CreateObject (); - - // - // We should find the default values there. - // - b->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" not initialized as expected"); - b->GetAttribute ("B", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 9, "Object Attribute \"B\" not initialized as expected"); - - // - // Now tell A that it has a B; and we should be able to set this new object's - // Attributes. - // - a->SetNodeB (b); - - Config::Set ("/NodeA/NodeB/A", IntegerValue (4)); - Config::Set ("/NodeA/NodeB/B", IntegerValue (-4)); - b->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 4, "Object Attribute \"A\" not set as expected"); - b->GetAttribute ("B", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -4, "Object Attribute \"B\" not set as expected"); -} - -// =========================================================================== -// Test for the ability to deal configure with vectors of objects. -// =========================================================================== -class ObjectVectorConfigTestCase : public TestCase -{ -public: - ObjectVectorConfigTestCase (); - virtual ~ObjectVectorConfigTestCase () {} - -private: - virtual void DoRun (void); -}; - -ObjectVectorConfigTestCase::ObjectVectorConfigTestCase () - : TestCase ("Check ability to configure vectors of Object using regular expressions") -{ -} - -void -ObjectVectorConfigTestCase::DoRun (void) -{ - IntegerValue iv; - - // - // Create a root namespace object - // - Ptr root = CreateObject (); - Config::RegisterRootNamespaceObject (root); - - // - // Create an object under the root. - // - Ptr a = CreateObject (); - root->SetNodeA (a); - - // - // Create an object one level down. - // - Ptr b = CreateObject (); - a->SetNodeB (b); - - // - // Add four objects to the ObjectVector Attribute at the bottom of the - // object hierarchy. By this point, we believe that the Attributes - // will be initialized correctly. - // - Ptr obj0 = CreateObject (); - Ptr obj1 = CreateObject (); - Ptr obj2 = CreateObject (); - Ptr obj3 = CreateObject (); - b->AddNodeB (obj0); - b->AddNodeB (obj1); - b->AddNodeB (obj2); - b->AddNodeB (obj3); - - // - // Set an Attribute of the zeroth Object in the vector by explicitly writing - // the '0' and make sure that only the one thing changed. - // - Config::Set ("/NodeA/NodeB/NodesB/0/A", IntegerValue (-11)); - obj0->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -11, "Object Attribute \"A\" not set as expected"); - - obj1->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); - - obj2->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); - - obj3->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); - - // - // Start using regular expression-like syntax to set Attributes. First try - // the OR syntax. Make sure that the two objects changed and nothing else - // - Config::Set ("/NodeA/NodeB/NodesB/0|1/A", IntegerValue (-12)); - obj0->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -12, "Object Attribute \"A\" not set as expected"); - - obj1->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -12, "Object Attribute \"A\" not set as expected"); - - obj2->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); - - obj3->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); - - // - // Make sure that extra '|' are allowed at the start and end of the regular expression - // - Config::Set ("/NodeA/NodeB/NodesB/|0|1|/A", IntegerValue (-13)); - obj0->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -13, "Object Attribute \"A\" not set as expected"); - - obj1->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -13, "Object Attribute \"A\" not set as expected"); - - obj2->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); - - obj3->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); - - // - // Try the [x-y] syntax - // - Config::Set ("/NodeA/NodeB/NodesB/[0-2]/A", IntegerValue (-14)); - obj0->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -14, "Object Attribute \"A\" not set as expected"); - - obj1->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -14, "Object Attribute \"A\" not set as expected"); - - obj2->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -14, "Object Attribute \"A\" not set as expected"); - - obj3->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); - - // - // Try the [x-y] syntax at the other limit - // - Config::Set ("/NodeA/NodeB/NodesB/[1-3]/A", IntegerValue (-15)); - obj0->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -14, "Object Attribute \"A\" unexpectedly set"); - - obj1->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -15, "Object Attribute \"A\" not set as expected"); - - obj2->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -15, "Object Attribute \"A\" not set as expected"); - - obj3->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -15, "Object Attribute \"A\" not set as expected"); - - // - // Combine the [x-y] syntax and the OR sntax - // - Config::Set ("/NodeA/NodeB/NodesB/[0-1]|3/A", IntegerValue (-16)); - obj0->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -16, "Object Attribute \"A\" not set as expected"); - - obj1->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -16, "Object Attribute \"A\" not set as expected"); - - obj2->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -15, "Object Attribute \"A\" unexpectedly set"); - - obj3->GetAttribute ("A", iv); - NS_TEST_ASSERT_MSG_EQ (iv.Get (), -16, "Object Attribute \"A\" not set as expected"); -} - -// =========================================================================== -// Test for the ability to trace configure with vectors of objects. -// =========================================================================== -class ObjectVectorTraceConfigTestCase : public TestCase -{ -public: - ObjectVectorTraceConfigTestCase (); - virtual ~ObjectVectorTraceConfigTestCase () {} - - void Trace (int16_t oldValue, int16_t newValue) {m_newValue = newValue;} - void TraceWithPath (std::string path, int16_t old, int16_t newValue) {m_newValue = newValue; m_path = path;} - -private: - virtual void DoRun (void); - - int16_t m_newValue; - std::string m_path; -}; - -ObjectVectorTraceConfigTestCase::ObjectVectorTraceConfigTestCase () - : TestCase ("Check ability to trace connect through vectors of Object using regular expressions") -{ -} - -void -ObjectVectorTraceConfigTestCase::DoRun (void) -{ - IntegerValue iv; - - // - // Create a root namespace object - // - Ptr root = CreateObject (); - Config::RegisterRootNamespaceObject (root); - - // - // Create an object under the root. - // - Ptr a = CreateObject (); - root->SetNodeA (a); - - // - // Create an object one level down. - // - Ptr b = CreateObject (); - a->SetNodeB (b); - - // - // Add four objects to the ObjectVector Attribute at the bottom of the - // object hierarchy. By this point, we believe that the Attributes - // will be initialized correctly. - // - Ptr obj0 = CreateObject (); - Ptr obj1 = CreateObject (); - Ptr obj2 = CreateObject (); - Ptr obj3 = CreateObject (); - b->AddNodeB (obj0); - b->AddNodeB (obj1); - b->AddNodeB (obj2); - b->AddNodeB (obj3); - - // - // Do a trace connect to some of the sources. We already checked parsing of - // the regular expressions, so we'll concentrate on the tracing part of the - // puzzle here. - // - Config::ConnectWithoutContext ("/NodeA/NodeB/NodesB/[0-1]|3/Source", - MakeCallback (&ObjectVectorTraceConfigTestCase::Trace, this)); - - // - // If we bug the trace source referred to by index '0' above, we should see - // the trace fire. - // - m_newValue = 0; - obj0->SetAttribute ("Source", IntegerValue (-1)); - NS_TEST_ASSERT_MSG_EQ (m_newValue, -1, "Trace 0 did not fire as expected"); - - // - // If we bug the trace source referred to by index '1' above, we should see - // the trace fire. - // - m_newValue = 0; - obj1->SetAttribute ("Source", IntegerValue (-2)); - NS_TEST_ASSERT_MSG_EQ (m_newValue, -2, "Trace 1 did not fire as expected"); - - // - // If we bug the trace source referred to by index '2' which is skipped above, - // we should not see the trace fire. - // - m_newValue = 0; - obj2->SetAttribute ("Source", IntegerValue (-3)); - NS_TEST_ASSERT_MSG_EQ (m_newValue, 0, "Trace 2 fired unexpectedly"); - - // - // If we bug the trace source referred to by index '3' above, we should see - // the trace fire. - // - m_newValue = 0; - obj3->SetAttribute ("Source", IntegerValue (-4)); - NS_TEST_ASSERT_MSG_EQ (m_newValue, -4, "Trace 3 did not fire as expected"); - - // - // Do a trace connect (with context) to some of the sources. - // - Config::Connect ("/NodeA/NodeB/NodesB/[0-1]|3/Source", - MakeCallback (&ObjectVectorTraceConfigTestCase::TraceWithPath, this)); - - // - // If we bug the trace source referred to by index '0' above, we should see - // the trace fire with the expected context path. - // - m_newValue = 0; - m_path = ""; - obj0->SetAttribute ("Source", IntegerValue (-1)); - NS_TEST_ASSERT_MSG_EQ (m_newValue, -1, "Trace 0 did not fire as expected"); - NS_TEST_ASSERT_MSG_EQ (m_path, "/NodeA/NodeB/NodesB/0/Source", "Trace 0 did not provide expected context"); - - // - // If we bug the trace source referred to by index '1' above, we should see - // the trace fire with the expected context path. - // - m_newValue = 0; - m_path = ""; - obj1->SetAttribute ("Source", IntegerValue (-2)); - NS_TEST_ASSERT_MSG_EQ (m_newValue, -2, "Trace 1 did not fire as expected"); - NS_TEST_ASSERT_MSG_EQ (m_path, "/NodeA/NodeB/NodesB/1/Source", "Trace 1 did not provide expected context"); - - // - // If we bug the trace source referred to by index '2' which is skipped above, - // we should not see the trace fire. - // - m_newValue = 0; - m_path = ""; - obj2->SetAttribute ("Source", IntegerValue (-3)); - NS_TEST_ASSERT_MSG_EQ (m_newValue, 0, "Trace 2 fired unexpectedly"); - - // - // If we bug the trace source referred to by index '3' above, we should see - // the trace fire with the expected context path. - // - m_newValue = 0; - m_path = ""; - obj3->SetAttribute ("Source", IntegerValue (-4)); - NS_TEST_ASSERT_MSG_EQ (m_newValue, -4, "Trace 3 did not fire as expected"); - NS_TEST_ASSERT_MSG_EQ (m_path, "/NodeA/NodeB/NodesB/1/Source", "Trace 1 did not provide expected context"); -} - -// =========================================================================== -// The Test Suite that glues all of the Test Cases together. -// =========================================================================== -class ConfigTestSuite : public TestSuite -{ -public: - ConfigTestSuite (); -}; - -ConfigTestSuite::ConfigTestSuite () - : TestSuite ("config", BVT) -{ - AddTestCase (new RootNamespaceConfigTestCase); - AddTestCase (new UnderRootNamespaceConfigTestCase); - AddTestCase (new ObjectVectorConfigTestCase); -} - -static ConfigTestSuite configTestSuite; - } // namespace ns3 diff --git a/src/core/model/global-value.cc b/src/core/model/global-value.cc index 769edbac0..3e17328c9 100644 --- a/src/core/model/global-value.cc +++ b/src/core/model/global-value.cc @@ -22,7 +22,6 @@ #include "attribute.h" #include "string.h" #include "uinteger.h" -#include "test.h" #include "ns3/core-config.h" #ifdef HAVE_STDLIB_H @@ -208,72 +207,5 @@ GlobalValue::GetVector (void) return &vector; } -// =========================================================================== -// Test for the ability to get at a GlobalValue. -// =========================================================================== -class GlobalValueTestCase : public TestCase -{ -public: - GlobalValueTestCase (); - virtual ~GlobalValueTestCase () {} - -private: - virtual void DoRun (void); -}; - -GlobalValueTestCase::GlobalValueTestCase () - : TestCase ("Check GlobalValue mechanism") -{ -} - -void -GlobalValueTestCase::DoRun (void) -{ - // - // Typically these are static globals but we can make one on the stack to - // keep it hidden from the documentation. - // - GlobalValue uint = GlobalValue ("TestUint", "help text", - UintegerValue (10), - MakeUintegerChecker ()); - - // - // Make sure we can get at the value and that it was initialized correctly. - // - UintegerValue uv; - uint.GetValue (uv); - NS_TEST_ASSERT_MSG_EQ (uv.Get (), 10, "GlobalValue \"TestUint\" not initialized as expected"); - - // - // Remove the global value for a valgrind clean run - // - GlobalValue::Vector *vector = GlobalValue::GetVector (); - for (GlobalValue::Vector::iterator i = vector->begin (); i != vector->end (); ++i) - { - if ((*i) == &uint) - { - vector->erase (i); - break; - } - } -} - -// =========================================================================== -// The Test Suite that glues all of the Test Cases together. -// =========================================================================== -class GlobalValueTestSuite : public TestSuite -{ -public: - GlobalValueTestSuite (); -}; - -GlobalValueTestSuite::GlobalValueTestSuite () - : TestSuite ("global-value", BVT) -{ - AddTestCase (new GlobalValueTestCase); -} - -static GlobalValueTestSuite globalValueTestSuite; - } // namespace ns3 diff --git a/src/core/model/object.cc b/src/core/model/object.cc index 657d21922..a8f01d890 100644 --- a/src/core/model/object.cc +++ b/src/core/model/object.cc @@ -18,7 +18,6 @@ * Authors: Gustavo Carneiro , * Mathieu Lacage */ -#include "test.h" #include "object.h" #include "object-factory.h" #include "assert.h" @@ -390,407 +389,3 @@ Object::DoDelete (void) } } // namespace ns3 -namespace { - -class BaseA : public ns3::Object -{ -public: - static ns3::TypeId GetTypeId (void) { - static ns3::TypeId tid = ns3::TypeId ("BaseA") - .SetParent (Object::GetTypeId ()) - .HideFromDocumentation () - .AddConstructor (); - return tid; - } - BaseA () - {} - virtual void Dispose (void) {} -}; - -class DerivedA : public BaseA -{ -public: - static ns3::TypeId GetTypeId (void) { - static ns3::TypeId tid = ns3::TypeId ("DerivedA") - .SetParent (BaseA::GetTypeId ()) - .HideFromDocumentation () - .AddConstructor (); - return tid; - } - DerivedA () - {} - virtual void Dispose (void) { - BaseA::Dispose (); - } -}; - -class BaseB : public ns3::Object -{ -public: - static ns3::TypeId GetTypeId (void) { - static ns3::TypeId tid = ns3::TypeId ("BaseB") - .SetParent (Object::GetTypeId ()) - .HideFromDocumentation () - .AddConstructor (); - return tid; - } - BaseB () - {} - virtual void Dispose (void) {} -}; - -class DerivedB : public BaseB -{ -public: - static ns3::TypeId GetTypeId (void) { - static ns3::TypeId tid = ns3::TypeId ("DerivedB") - .SetParent (BaseB::GetTypeId ()) - .HideFromDocumentation () - .AddConstructor (); - return tid; - } - DerivedB () - {} - virtual void Dispose (void) { - BaseB::Dispose (); - } -}; - -NS_OBJECT_ENSURE_REGISTERED (BaseA); -NS_OBJECT_ENSURE_REGISTERED (DerivedA); -NS_OBJECT_ENSURE_REGISTERED (BaseB); -NS_OBJECT_ENSURE_REGISTERED (DerivedB); - -} // namespace anonymous - -namespace ns3 { - -// =========================================================================== -// Test case to make sure that we can make Objects using CreateObject. -// =========================================================================== -class CreateObjectTestCase : public TestCase -{ -public: - CreateObjectTestCase (); - virtual ~CreateObjectTestCase (); - -private: - virtual void DoRun (void); -}; - -CreateObjectTestCase::CreateObjectTestCase () - : TestCase ("Check CreateObject template function") -{ -} - -CreateObjectTestCase::~CreateObjectTestCase () -{ -} - -void -CreateObjectTestCase::DoRun (void) -{ - Ptr baseA = CreateObject (); - NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject"); - - // - // Since baseA is a BaseA, we must be able to successfully ask for a BaseA. - // - NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (), baseA, "GetObject() of same type returns different Ptr"); - - // - // Since BaseA is a BaseA and not a DerivedA, we must not find a DerivedA if we look. - // - NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (), 0, "GetObject() of unrelated type returns nonzero pointer"); - - // - // Since baseA is not a BaseA, we must not be able to ask for a DerivedA even if we - // try an implied cast back to a BaseA. - // - NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (DerivedA::GetTypeId ()), 0, "GetObject() of unrelated returns nonzero Ptr"); - - baseA = CreateObject (); - NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject with implicit cast to BaseA"); - - // - // If we create a DerivedA and cast it to a BaseA, then if we do a GetObject for - // that BaseA we should get the same address (same Object). - // - NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (), baseA, "Unable to GetObject on BaseA"); - - // - // Since we created a DerivedA and cast it to a BaseA, we should be able to - // get back a DerivedA and it should be the original Ptr. - // - NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (), baseA, "GetObject() of the original type returns different Ptr"); - - // If we created a DerivedA and cast it to a BaseA, then we GetObject for the - // same DerivedA and cast it back to the same BaseA, we should get the same - // object. - // - NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (DerivedA::GetTypeId ()), baseA, "GetObject returns different Ptr"); -} - -// =========================================================================== -// Test case to make sure that we can aggregate Objects. -// =========================================================================== -class AggregateObjectTestCase : public TestCase -{ -public: - AggregateObjectTestCase (); - virtual ~AggregateObjectTestCase (); - -private: - virtual void DoRun (void); -}; - -AggregateObjectTestCase::AggregateObjectTestCase () - : TestCase ("Check Object aggregation functionality") -{ -} - -AggregateObjectTestCase::~AggregateObjectTestCase () -{ -} - -void -AggregateObjectTestCase::DoRun (void) -{ - Ptr baseA = CreateObject (); - NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject"); - - Ptr baseB = CreateObject (); - NS_TEST_ASSERT_MSG_NE (baseB, 0, "Unable to CreateObject"); - - Ptr baseBCopy = baseB; - NS_TEST_ASSERT_MSG_NE (baseBCopy, 0, "Unable to copy BaseB"); - - // - // Make an aggregation of a BaseA object and a BaseB object. - // - baseA->AggregateObject (baseB); - - // - // We should be able to ask the aggregation (through baseA) for the BaseA part - // of the aggregation. - // - NS_TEST_ASSERT_MSG_NE (baseA->GetObject (), 0, "Cannot GetObject (through baseA) for BaseA Object"); - - // - // There is no DerivedA in this picture, so we should not be able to GetObject - // for that type. - // - NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (), 0, "Unexpectedly found a DerivedA through baseA"); - - // - // We should be able to ask the aggregation (through baseA) for the BaseB part - // - NS_TEST_ASSERT_MSG_NE (baseA->GetObject (), 0, "Cannot GetObject (through baseA) for BaseB Object"); - - // - // There is no DerivedB in this picture, so we should not be able to GetObject - // for that type. - // - NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (), 0, "Unexpectedly found a DerivedB through baseA"); - - // - // We should be able to ask the aggregation (through baseA) for the BaseB part - // - NS_TEST_ASSERT_MSG_NE (baseB->GetObject (), 0, "Cannot GetObject (through baseB) for BaseB Object"); - - // - // There is no DerivedB in this picture, so we should not be able to GetObject - // for that type. - // - NS_TEST_ASSERT_MSG_EQ (baseB->GetObject (), 0, "Unexpectedly found a DerivedB through baseB"); - - // - // We should be able to ask the aggregation (through baseB) for the BaseA part - // of the aggregation. - // - NS_TEST_ASSERT_MSG_NE (baseB->GetObject (), 0, "Cannot GetObject (through baseB) for BaseA Object"); - - // - // There is no DerivedA in this picture, so we should not be able to GetObject - // for that type. - // - NS_TEST_ASSERT_MSG_EQ (baseB->GetObject (), 0, "Unexpectedly found a DerivedA through baseB"); - - // - // baseBCopy is a copy of the original Ptr to the Object BaseB. Even though - // we didn't use baseBCopy directly in the aggregations, the object to which - // it points was used, therefore, we should be able to use baseBCopy as if - // it were baseB and get a BaseA out of the aggregation. - // - NS_TEST_ASSERT_MSG_NE (baseBCopy->GetObject (), 0, "Cannot GetObject (through baseBCopy) for a BaseA Object"); - - // - // Now, change the underlying type of the objects to be the derived types. - // - baseA = CreateObject (); - NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject with implicit cast to BaseA"); - - baseB = CreateObject (); - NS_TEST_ASSERT_MSG_NE (baseB, 0, "Unable to CreateObject with implicit cast to BaseB"); - - // - // Create an aggregation of two objects, both of the derived types; and leave - // an unaggregated copy of one lying around. - // - baseBCopy = baseB; - baseA->AggregateObject (baseB); - - // - // We should be able to ask the aggregation (through baseA) for the DerivedB part - // - NS_TEST_ASSERT_MSG_NE (baseA->GetObject (), 0, "Cannot GetObject (through baseA) for DerivedB Object"); - - // - // Since the DerivedB is also a BaseB, we should be able to ask the aggregation - // (through baseA) for the BaseB part - // - NS_TEST_ASSERT_MSG_NE (baseA->GetObject (), 0, "Cannot GetObject (through baseA) for BaseB Object"); - - // - // We should be able to ask the aggregation (through baseB) for the DerivedA part - // - NS_TEST_ASSERT_MSG_NE (baseB->GetObject (), 0, "Cannot GetObject (through baseB) for DerivedA Object"); - - // - // Since the DerivedA is also a BaseA, we should be able to ask the aggregation - // (through baseB) for the BaseA part - // - NS_TEST_ASSERT_MSG_NE (baseB->GetObject (), 0, "Cannot GetObject (through baseB) for BaseA Object"); - - // - // baseBCopy is a copy of the original Ptr to the Object BaseB. Even though - // we didn't use baseBCopy directly in the aggregations, the object to which - // it points was used, therefore, we should be able to use baseBCopy as if - // it were baseB (same underlying Object) and get a BaseA and a DerivedA out - // of the aggregation through baseBCopy. - // - NS_TEST_ASSERT_MSG_NE (baseBCopy->GetObject (), 0, "Cannot GetObject (through baseBCopy) for a BaseA Object"); - NS_TEST_ASSERT_MSG_NE (baseBCopy->GetObject (), 0, "Cannot GetObject (through baseBCopy) for a BaseA Object"); - - // - // Since the Ptr is actually a DerivedB, we should be able to ask the - // aggregation (through baseB) for the DerivedB part - // - NS_TEST_ASSERT_MSG_NE (baseB->GetObject (), 0, "Cannot GetObject (through baseB) for DerivedB Object"); - - // - // Since the DerivedB was cast to a BaseB, we should be able to ask the - // aggregation (through baseB) for the BaseB part - // - NS_TEST_ASSERT_MSG_NE (baseB->GetObject (), 0, "Cannot GetObject (through baseB) for BaseB Object"); - - // - // Make sure reference counting works in the aggregate. Create two Objects - // and aggregate them, then release one of them. The aggregation should - // keep a reference to both and the Object we released should still be there. - // - baseA = CreateObject (); - NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject"); - - baseB = CreateObject (); - NS_TEST_ASSERT_MSG_NE (baseB, 0, "Unable to CreateObject"); - - baseA->AggregateObject (baseB); - baseA = 0; - - baseA = baseB->GetObject (); - NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to GetObject on released object"); -} - -// =========================================================================== -// Test case to make sure that an Object factory can create Objects -// =========================================================================== -class ObjectFactoryTestCase : public TestCase -{ -public: - ObjectFactoryTestCase (); - virtual ~ObjectFactoryTestCase (); - -private: - virtual void DoRun (void); -}; - -ObjectFactoryTestCase::ObjectFactoryTestCase () - : TestCase ("Check ObjectFactory functionality") -{ -} - -ObjectFactoryTestCase::~ObjectFactoryTestCase () -{ -} - -void -ObjectFactoryTestCase::DoRun (void) -{ - ObjectFactory factory; - - // - // Create an Object of type BaseA through an object factory. - // - factory.SetTypeId (BaseA::GetTypeId ()); - Ptr a = factory.Create (); - NS_TEST_ASSERT_MSG_NE (a, 0, "Unable to factory.Create() a BaseA"); - - // - // What we made should be a BaseA, not have anything to do with a DerivedA - // - NS_TEST_ASSERT_MSG_EQ (a->GetObject (DerivedA::GetTypeId ()), 0, "BaseA is unexpectedly a DerivedA also"); - - // - // The BaseA we got should not respond to a GetObject for DerivedA - // - NS_TEST_ASSERT_MSG_EQ (a->GetObject (), 0, "BaseA unexpectedly responds to GetObject for DerivedA"); - - // - // Now tell the factory to make DerivedA Objects and create one with an - // implied cast back to a BaseA - // - factory.SetTypeId (DerivedA::GetTypeId ()); - a = factory.Create (); - - // - // Since the DerivedA has a BaseA part, we should be able to use GetObject to - // dynamically cast back to a BaseA. - // - NS_TEST_ASSERT_MSG_EQ (a->GetObject (), a, "Unable to use GetObject as dynamic_cast()"); - - // - // Since a is already a BaseA and is really a DerivedA, we should be able to - // GetObject for the DerivedA and cast it back to a BaseA getting the same - // value that is there. - // - NS_TEST_ASSERT_MSG_EQ (a->GetObject (DerivedA::GetTypeId ()), a, "GetObject with implied cast returns different Ptr"); - - // - // Since a declared a BaseA, even if it is really a DerivedA, we should not - // be able to GetOBject for a DerivedA since this would break the type - // declaration. - // - NS_TEST_ASSERT_MSG_NE (a->GetObject (), 0, "Unexpectedly able to work around C++ type system"); -} - -// =========================================================================== -// The Test Suite that glues the Test Cases together. -// =========================================================================== -class ObjectTestSuite : public TestSuite -{ -public: - ObjectTestSuite (); -}; - -ObjectTestSuite::ObjectTestSuite () - : TestSuite ("object", BVT) -{ - AddTestCase (new CreateObjectTestCase); - AddTestCase (new AggregateObjectTestCase); - AddTestCase (new ObjectFactoryTestCase); -} - -static ObjectTestSuite objectTestSuite; - -} // namespace ns3 diff --git a/src/core/model/random-variable.cc b/src/core/model/random-variable.cc index be31c39ec..f50dac61d 100644 --- a/src/core/model/random-variable.cc +++ b/src/core/model/random-variable.cc @@ -32,7 +32,6 @@ #include #include -#include "test.h" #include "assert.h" #include "config.h" #include "integer.h" @@ -2046,118 +2045,4 @@ std::istream & operator >> (std::istream &is, RandomVariable &var) return is; } -class BasicRandomNumberTestCase : public TestCase -{ -public: - BasicRandomNumberTestCase (); - virtual ~BasicRandomNumberTestCase () - { - } - -private: - virtual void DoRun (void); -}; - -BasicRandomNumberTestCase::BasicRandomNumberTestCase () - : TestCase ("Check basic random number operation") -{ -} - -void -BasicRandomNumberTestCase::DoRun (void) -{ - const double desiredMean = 1.0; - const double desiredStdDev = 1.0; - - double tmp = log (1 + (desiredStdDev / desiredMean) * (desiredStdDev / desiredMean)); - double sigma = sqrt (tmp); - double mu = log (desiredMean) - 0.5 * tmp; - - // - // Test a custom lognormal instance to see if its moments have any relation - // expected reality. - // - LogNormalVariable lognormal (mu, sigma); - vector samples; - const int NSAMPLES = 10000; - double sum = 0; - - // - // Get and store a bunch of samples. As we go along sum them and then find - // the mean value of the samples. - // - for (int n = NSAMPLES; n; --n) - { - double value = lognormal.GetValue (); - sum += value; - samples.push_back (value); - } - double obtainedMean = sum / NSAMPLES; - NS_TEST_EXPECT_MSG_EQ_TOL (obtainedMean, desiredMean, 0.1, "Got unexpected mean value from LogNormalVariable"); - - // - // Wander back through the saved stamples and find their standard deviation - // - sum = 0; - for (vector::iterator iter = samples.begin (); iter != samples.end (); iter++) - { - double tmp = (*iter - obtainedMean); - sum += tmp * tmp; - } - double obtainedStdDev = sqrt (sum / (NSAMPLES - 1)); - NS_TEST_EXPECT_MSG_EQ_TOL (obtainedStdDev, desiredStdDev, 0.1, "Got unexpected standard deviation from LogNormalVariable"); -} - -class RandomNumberSerializationTestCase : public TestCase -{ -public: - RandomNumberSerializationTestCase (); - virtual ~RandomNumberSerializationTestCase () - { - } - -private: - virtual void DoRun (void); -}; - -RandomNumberSerializationTestCase::RandomNumberSerializationTestCase () - : TestCase ("Check basic random number operation") -{ -} - -void -RandomNumberSerializationTestCase::DoRun (void) -{ - RandomVariableValue val; - val.DeserializeFromString ("Uniform:0.1:0.2", MakeRandomVariableChecker ()); - RandomVariable rng = val.Get (); - NS_TEST_ASSERT_MSG_EQ (val.SerializeToString (MakeRandomVariableChecker ()), "Uniform:0.1:0.2", - "Deserialize and Serialize \"Uniform:0.1:0.2\" mismatch"); - - val.DeserializeFromString ("Normal:0.1:0.2", MakeRandomVariableChecker ()); - rng = val.Get (); - NS_TEST_ASSERT_MSG_EQ (val.SerializeToString (MakeRandomVariableChecker ()), "Normal:0.1:0.2", - "Deserialize and Serialize \"Normal:0.1:0.2\" mismatch"); - - val.DeserializeFromString ("Normal:0.1:0.2:0.15", MakeRandomVariableChecker ()); - rng = val.Get (); - NS_TEST_ASSERT_MSG_EQ (val.SerializeToString (MakeRandomVariableChecker ()), "Normal:0.1:0.2:0.15", - "Deserialize and Serialize \"Normal:0.1:0.2:0.15\" mismatch"); -} - -class BasicRandomNumberTestSuite : public TestSuite -{ -public: - BasicRandomNumberTestSuite (); -}; - -BasicRandomNumberTestSuite::BasicRandomNumberTestSuite () - : TestSuite ("basic-random-number", BVT) -{ - AddTestCase (new BasicRandomNumberTestCase); - AddTestCase (new RandomNumberSerializationTestCase); -} - -static BasicRandomNumberTestSuite BasicRandomNumberTestSuite; - } // namespace ns3 diff --git a/src/core/test/command-line-test-suite.cc b/src/core/test/command-line-test-suite.cc new file mode 100644 index 000000000..e31092949 --- /dev/null +++ b/src/core/test/command-line-test-suite.cc @@ -0,0 +1,230 @@ +/* -*- 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 + */ +#include "ns3/command-line.h" +#include "ns3/log.h" +#include "ns3/config.h" +#include "ns3/global-value.h" +#include "ns3/type-id.h" +#include "ns3/test.h" +#include "ns3/string.h" +#include +#include + +namespace ns3 { + +// =========================================================================== +// A test base class that drives Command Line parsing +// =========================================================================== +class CommandLineTestCaseBase : public TestCase +{ +public: + CommandLineTestCaseBase (std::string description); + virtual ~CommandLineTestCaseBase () {} + + void Parse (const CommandLine &cmd, int n, ...); +}; + +CommandLineTestCaseBase::CommandLineTestCaseBase (std::string description) + : TestCase (description) +{ +} + +void +CommandLineTestCaseBase::Parse (const CommandLine &cmd, int n, ...) +{ + char **args = new char* [n+1]; + args[0] = (char *) "Test"; + va_list ap; + va_start (ap, n); + int i = 0; + while (i < n) + { + char *arg = va_arg (ap, char *); + args[i+1] = arg; + i++; + } + int argc = n + 1; + cmd.Parse (argc, args); + delete [] args; +} + +// =========================================================================== +// Test boolean Command Line processing +// =========================================================================== +class CommandLineBooleanTestCase : public CommandLineTestCaseBase +{ +public: + CommandLineBooleanTestCase (); + virtual ~CommandLineBooleanTestCase () {} + +private: + virtual void DoRun (void); + +}; + +CommandLineBooleanTestCase::CommandLineBooleanTestCase () + : CommandLineTestCaseBase ("Check boolean arguments") +{ +} + +void +CommandLineBooleanTestCase::DoRun (void) +{ + CommandLine cmd; + bool myBool = true; + + cmd.AddValue ("my-bool", "help", myBool); + + Parse (cmd, 1, "--my-bool=0"); + NS_TEST_ASSERT_MSG_EQ (myBool, false, "Command parser did not correctly set a boolean value to false"); + + Parse (cmd, 1, "--my-bool=1"); + NS_TEST_ASSERT_MSG_EQ (myBool, true, "Command parser did not correctly set a boolean value to true"); +} + +// =========================================================================== +// Test int Command Line processing +// =========================================================================== +class CommandLineIntTestCase : public CommandLineTestCaseBase +{ +public: + CommandLineIntTestCase (); + virtual ~CommandLineIntTestCase () {} + +private: + virtual void DoRun (void); + +}; + +CommandLineIntTestCase::CommandLineIntTestCase () + : CommandLineTestCaseBase ("Check int arguments") +{ +} + +void +CommandLineIntTestCase::DoRun (void) +{ + CommandLine cmd; + bool myBool = true; + int32_t myInt32 = 10; + + cmd.AddValue ("my-bool", "help", myBool); + cmd.AddValue ("my-int32", "help", myInt32); + + Parse (cmd, 2, "--my-bool=0", "--my-int32=-3"); + NS_TEST_ASSERT_MSG_EQ (myBool, false, "Command parser did not correctly set a boolean value to false"); + NS_TEST_ASSERT_MSG_EQ (myInt32, -3, "Command parser did not correctly set an integer value to -3"); + + Parse (cmd, 2, "--my-bool=1", "--my-int32=+2"); + NS_TEST_ASSERT_MSG_EQ (myBool, true, "Command parser did not correctly set a boolean value to true"); + NS_TEST_ASSERT_MSG_EQ (myInt32, +2, "Command parser did not correctly set an integer value to +2"); +} + +// =========================================================================== +// Test unsigned int Command Line processing +// =========================================================================== +class CommandLineUnsignedIntTestCase : public CommandLineTestCaseBase +{ +public: + CommandLineUnsignedIntTestCase (); + virtual ~CommandLineUnsignedIntTestCase () {} + +private: + virtual void DoRun (void); + +}; + +CommandLineUnsignedIntTestCase::CommandLineUnsignedIntTestCase () + : CommandLineTestCaseBase ("Check unsigned int arguments") +{ +} + +void +CommandLineUnsignedIntTestCase::DoRun (void) +{ + CommandLine cmd; + bool myBool = true; + uint32_t myUint32 = 10; + + cmd.AddValue ("my-bool", "help", myBool); + cmd.AddValue ("my-uint32", "help", myUint32); + + Parse (cmd, 2, "--my-bool=0", "--my-uint32=9"); + + NS_TEST_ASSERT_MSG_EQ (myBool, false, "Command parser did not correctly set a boolean value to true"); + NS_TEST_ASSERT_MSG_EQ (myUint32, 9, "Command parser did not correctly set an unsigned integer value to 9"); +} + +// =========================================================================== +// Test string Command Line processing +// =========================================================================== +class CommandLineStringTestCase : public CommandLineTestCaseBase +{ +public: + CommandLineStringTestCase (); + virtual ~CommandLineStringTestCase () {} + +private: + virtual void DoRun (void); + +}; + +CommandLineStringTestCase::CommandLineStringTestCase () + : CommandLineTestCaseBase ("Check unsigned int arguments") +{ +} + +void +CommandLineStringTestCase::DoRun (void) +{ + CommandLine cmd; + uint32_t myUint32 = 10; + std::string myStr = "MyStr"; + + cmd.AddValue ("my-uint32", "help", myUint32); + cmd.AddValue ("my-str", "help", myStr); + + Parse (cmd, 2, "--my-uint32=9", "--my-str=XX"); + + NS_TEST_ASSERT_MSG_EQ (myUint32, 9, "Command parser did not correctly set an unsigned integer value to 9"); + NS_TEST_ASSERT_MSG_EQ (myStr, "XX", "Command parser did not correctly set an string value to \"XX\""); +} + +// =========================================================================== +// The Test Suite that glues all of the Test Cases together. +// =========================================================================== +class CommandLineTestSuite : public TestSuite +{ +public: + CommandLineTestSuite (); +}; + +CommandLineTestSuite::CommandLineTestSuite () + : TestSuite ("command-line", BVT) +{ + AddTestCase (new CommandLineBooleanTestCase); + AddTestCase (new CommandLineIntTestCase); + AddTestCase (new CommandLineUnsignedIntTestCase); + AddTestCase (new CommandLineStringTestCase); +} + +static CommandLineTestSuite CommandLineTestSuite; + +} // namespace ns3 diff --git a/src/core/test/config-test-suite.cc b/src/core/test/config-test-suite.cc new file mode 100644 index 000000000..18d11949c --- /dev/null +++ b/src/core/test/config-test-suite.cc @@ -0,0 +1,617 @@ +/* -*- 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 + */ +#include "ns3/config.h" +#include "ns3/test.h" +#include "ns3/integer.h" +#include "ns3/traced-value.h" +#include "ns3/trace-source-accessor.h" +#include "ns3/callback.h" + +#include "ns3/singleton.h" +#include "ns3/object.h" +#include "ns3/object-vector.h" +#include "ns3/names.h" +#include "ns3/pointer.h" +#include "ns3/log.h" + + +#include + +namespace ns3 { + +// =========================================================================== +// An object with some attributes that we can play with using config. +// =========================================================================== +class ConfigTestObject : public Object +{ +public: + static TypeId GetTypeId (void); + + void AddNodeA (Ptr a); + void AddNodeB (Ptr b); + + void SetNodeA (Ptr a); + void SetNodeB (Ptr b); + + int8_t GetA (void) const; + int8_t GetB (void) const; + +private: + std::vector > m_nodesA; + std::vector > m_nodesB; + Ptr m_nodeA; + Ptr m_nodeB; + int8_t m_a; + int8_t m_b; + TracedValue m_trace; +}; + +TypeId +ConfigTestObject::GetTypeId (void) +{ + static TypeId tid = TypeId ("ConfigTestObject") + .SetParent () + .AddAttribute ("NodesA", "", + ObjectVectorValue (), + MakeObjectVectorAccessor (&ConfigTestObject::m_nodesA), + MakeObjectVectorChecker ()) + .AddAttribute ("NodesB", "", + ObjectVectorValue (), + MakeObjectVectorAccessor (&ConfigTestObject::m_nodesB), + MakeObjectVectorChecker ()) + .AddAttribute ("NodeA", "", + PointerValue (), + MakePointerAccessor (&ConfigTestObject::m_nodeA), + MakePointerChecker ()) + .AddAttribute ("NodeB", "", + PointerValue (), + MakePointerAccessor (&ConfigTestObject::m_nodeB), + MakePointerChecker ()) + .AddAttribute ("A", "", + IntegerValue (10), + MakeIntegerAccessor (&ConfigTestObject::m_a), + MakeIntegerChecker ()) + .AddAttribute ("B", "", + IntegerValue (9), + MakeIntegerAccessor (&ConfigTestObject::m_b), + MakeIntegerChecker ()) + .AddAttribute ("Source", "XX", + IntegerValue (-1), + MakeIntegerAccessor (&ConfigTestObject::m_trace), + MakeIntegerChecker ()) + .AddTraceSource ("Source", "XX", + MakeTraceSourceAccessor (&ConfigTestObject::m_trace)) + ; + return tid; +} + +void +ConfigTestObject::SetNodeA (Ptr a) +{ + m_nodeA = a; +} + +void +ConfigTestObject::SetNodeB (Ptr b) +{ + m_nodeB = b; +} + +void +ConfigTestObject::AddNodeA (Ptr a) +{ + m_nodesA.push_back (a); +} + +void +ConfigTestObject::AddNodeB (Ptr b) +{ + m_nodesB.push_back (b); +} + +int8_t +ConfigTestObject::GetA (void) const +{ + return m_a; +} + +int8_t +ConfigTestObject::GetB (void) const +{ + return m_b; +} + +// =========================================================================== +// Test for the ability to register and use a root namespace +// =========================================================================== +class RootNamespaceConfigTestCase : public TestCase +{ +public: + RootNamespaceConfigTestCase (); + virtual ~RootNamespaceConfigTestCase () {} + +private: + virtual void DoRun (void); +}; + +RootNamespaceConfigTestCase::RootNamespaceConfigTestCase () + : TestCase ("Check ability to register a root namespace and use it") +{ +} + +void +RootNamespaceConfigTestCase::DoRun (void) +{ + IntegerValue iv; + // + // Create an object and register its attributes directly in the root + // namespace. + // + Ptr root = CreateObject (); + Config::RegisterRootNamespaceObject (root); + + // + // We should find the default values there. + // + root->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" not initialized as expected"); + + // + // Now use the config mechanism to set the attribute; and we should find the + // new value. + // + Config::Set ("/A", IntegerValue (1)); + root->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 1, "Object Attribute \"A\" not set correctly"); + + // + // We should find the default values of "B" too. + // + root->GetAttribute ("B", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 9, "Object Attribute \"B\" not initialized as expected"); + + // + // Now use the config mechanism to set the attribute; and we should find the + // new value. + // + Config::Set ("/B", IntegerValue (-1)); + root->GetAttribute ("B", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -1, "Object Attribute \"B\" not set correctly"); +} + +// =========================================================================== +// Test for the ability to add an object under the root namespace. +// =========================================================================== +class UnderRootNamespaceConfigTestCase : public TestCase +{ +public: + UnderRootNamespaceConfigTestCase (); + virtual ~UnderRootNamespaceConfigTestCase () {} + +private: + virtual void DoRun (void); +}; + +UnderRootNamespaceConfigTestCase::UnderRootNamespaceConfigTestCase () + : TestCase ("Check ability to register an object under the root namespace and use it") +{ +} + +void +UnderRootNamespaceConfigTestCase::DoRun (void) +{ + IntegerValue iv; + // + // Create an object and register its attributes directly in the root + // namespace. + // + Ptr root = CreateObject (); + Config::RegisterRootNamespaceObject (root); + + Ptr a = CreateObject (); + root->SetNodeA (a); + + // + // We should find the default values there. + // + a->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" not initialized as expected"); + + // + // Now use the config mechanism to set the attribute; and we should find the + // new value. + // + Config::Set ("/NodeA/A", IntegerValue (1)); + a->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 1, "Object Attribute \"A\" not set correctly"); + + // + // We should find the default values of "B" too. + // + a->GetAttribute ("B", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 9, "Object Attribute \"B\" not initialized as expected"); + + // + // Now use the config mechanism to set the attribute; and we should find the + // new value. + // + Config::Set ("/NodeA/B", IntegerValue (-1)); + a->GetAttribute ("B", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -1, "Object Attribute \"B\" not set correctly"); + + // + // Try and set through a nonexistent path. Should do nothing. + // + Config::Set ("/NodeB/A", IntegerValue (1234)); + a->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 1, "Object Attribute \"A\" unexpectedly set via bad path"); + + Config::Set ("/NodeB/B", IntegerValue (1234)); + a->GetAttribute ("B", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -1, "Object Attribute \"B\" unexpectedly set via bad path"); + + // + // Step down one level of recursion and try again + // + Ptr b = CreateObject (); + + // + // We should find the default values there. + // + b->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" not initialized as expected"); + b->GetAttribute ("B", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 9, "Object Attribute \"B\" not initialized as expected"); + + // + // Now tell A that it has a B; and we should be able to set this new object's + // Attributes. + // + a->SetNodeB (b); + + Config::Set ("/NodeA/NodeB/A", IntegerValue (4)); + Config::Set ("/NodeA/NodeB/B", IntegerValue (-4)); + b->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 4, "Object Attribute \"A\" not set as expected"); + b->GetAttribute ("B", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -4, "Object Attribute \"B\" not set as expected"); +} + +// =========================================================================== +// Test for the ability to deal configure with vectors of objects. +// =========================================================================== +class ObjectVectorConfigTestCase : public TestCase +{ +public: + ObjectVectorConfigTestCase (); + virtual ~ObjectVectorConfigTestCase () {} + +private: + virtual void DoRun (void); +}; + +ObjectVectorConfigTestCase::ObjectVectorConfigTestCase () + : TestCase ("Check ability to configure vectors of Object using regular expressions") +{ +} + +void +ObjectVectorConfigTestCase::DoRun (void) +{ + IntegerValue iv; + + // + // Create a root namespace object + // + Ptr root = CreateObject (); + Config::RegisterRootNamespaceObject (root); + + // + // Create an object under the root. + // + Ptr a = CreateObject (); + root->SetNodeA (a); + + // + // Create an object one level down. + // + Ptr b = CreateObject (); + a->SetNodeB (b); + + // + // Add four objects to the ObjectVector Attribute at the bottom of the + // object hierarchy. By this point, we believe that the Attributes + // will be initialized correctly. + // + Ptr obj0 = CreateObject (); + Ptr obj1 = CreateObject (); + Ptr obj2 = CreateObject (); + Ptr obj3 = CreateObject (); + b->AddNodeB (obj0); + b->AddNodeB (obj1); + b->AddNodeB (obj2); + b->AddNodeB (obj3); + + // + // Set an Attribute of the zeroth Object in the vector by explicitly writing + // the '0' and make sure that only the one thing changed. + // + Config::Set ("/NodeA/NodeB/NodesB/0/A", IntegerValue (-11)); + obj0->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -11, "Object Attribute \"A\" not set as expected"); + + obj1->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); + + obj2->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); + + obj3->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); + + // + // Start using regular expression-like syntax to set Attributes. First try + // the OR syntax. Make sure that the two objects changed and nothing else + // + Config::Set ("/NodeA/NodeB/NodesB/0|1/A", IntegerValue (-12)); + obj0->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -12, "Object Attribute \"A\" not set as expected"); + + obj1->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -12, "Object Attribute \"A\" not set as expected"); + + obj2->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); + + obj3->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); + + // + // Make sure that extra '|' are allowed at the start and end of the regular expression + // + Config::Set ("/NodeA/NodeB/NodesB/|0|1|/A", IntegerValue (-13)); + obj0->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -13, "Object Attribute \"A\" not set as expected"); + + obj1->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -13, "Object Attribute \"A\" not set as expected"); + + obj2->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); + + obj3->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); + + // + // Try the [x-y] syntax + // + Config::Set ("/NodeA/NodeB/NodesB/[0-2]/A", IntegerValue (-14)); + obj0->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -14, "Object Attribute \"A\" not set as expected"); + + obj1->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -14, "Object Attribute \"A\" not set as expected"); + + obj2->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -14, "Object Attribute \"A\" not set as expected"); + + obj3->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), 10, "Object Attribute \"A\" unexpectedly set"); + + // + // Try the [x-y] syntax at the other limit + // + Config::Set ("/NodeA/NodeB/NodesB/[1-3]/A", IntegerValue (-15)); + obj0->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -14, "Object Attribute \"A\" unexpectedly set"); + + obj1->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -15, "Object Attribute \"A\" not set as expected"); + + obj2->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -15, "Object Attribute \"A\" not set as expected"); + + obj3->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -15, "Object Attribute \"A\" not set as expected"); + + // + // Combine the [x-y] syntax and the OR sntax + // + Config::Set ("/NodeA/NodeB/NodesB/[0-1]|3/A", IntegerValue (-16)); + obj0->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -16, "Object Attribute \"A\" not set as expected"); + + obj1->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -16, "Object Attribute \"A\" not set as expected"); + + obj2->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -15, "Object Attribute \"A\" unexpectedly set"); + + obj3->GetAttribute ("A", iv); + NS_TEST_ASSERT_MSG_EQ (iv.Get (), -16, "Object Attribute \"A\" not set as expected"); +} + +// =========================================================================== +// Test for the ability to trace configure with vectors of objects. +// =========================================================================== +class ObjectVectorTraceConfigTestCase : public TestCase +{ +public: + ObjectVectorTraceConfigTestCase (); + virtual ~ObjectVectorTraceConfigTestCase () {} + + void Trace (int16_t oldValue, int16_t newValue) {m_newValue = newValue;} + void TraceWithPath (std::string path, int16_t old, int16_t newValue) {m_newValue = newValue; m_path = path;} + +private: + virtual void DoRun (void); + + int16_t m_newValue; + std::string m_path; +}; + +ObjectVectorTraceConfigTestCase::ObjectVectorTraceConfigTestCase () + : TestCase ("Check ability to trace connect through vectors of Object using regular expressions") +{ +} + +void +ObjectVectorTraceConfigTestCase::DoRun (void) +{ + IntegerValue iv; + + // + // Create a root namespace object + // + Ptr root = CreateObject (); + Config::RegisterRootNamespaceObject (root); + + // + // Create an object under the root. + // + Ptr a = CreateObject (); + root->SetNodeA (a); + + // + // Create an object one level down. + // + Ptr b = CreateObject (); + a->SetNodeB (b); + + // + // Add four objects to the ObjectVector Attribute at the bottom of the + // object hierarchy. By this point, we believe that the Attributes + // will be initialized correctly. + // + Ptr obj0 = CreateObject (); + Ptr obj1 = CreateObject (); + Ptr obj2 = CreateObject (); + Ptr obj3 = CreateObject (); + b->AddNodeB (obj0); + b->AddNodeB (obj1); + b->AddNodeB (obj2); + b->AddNodeB (obj3); + + // + // Do a trace connect to some of the sources. We already checked parsing of + // the regular expressions, so we'll concentrate on the tracing part of the + // puzzle here. + // + Config::ConnectWithoutContext ("/NodeA/NodeB/NodesB/[0-1]|3/Source", + MakeCallback (&ObjectVectorTraceConfigTestCase::Trace, this)); + + // + // If we bug the trace source referred to by index '0' above, we should see + // the trace fire. + // + m_newValue = 0; + obj0->SetAttribute ("Source", IntegerValue (-1)); + NS_TEST_ASSERT_MSG_EQ (m_newValue, -1, "Trace 0 did not fire as expected"); + + // + // If we bug the trace source referred to by index '1' above, we should see + // the trace fire. + // + m_newValue = 0; + obj1->SetAttribute ("Source", IntegerValue (-2)); + NS_TEST_ASSERT_MSG_EQ (m_newValue, -2, "Trace 1 did not fire as expected"); + + // + // If we bug the trace source referred to by index '2' which is skipped above, + // we should not see the trace fire. + // + m_newValue = 0; + obj2->SetAttribute ("Source", IntegerValue (-3)); + NS_TEST_ASSERT_MSG_EQ (m_newValue, 0, "Trace 2 fired unexpectedly"); + + // + // If we bug the trace source referred to by index '3' above, we should see + // the trace fire. + // + m_newValue = 0; + obj3->SetAttribute ("Source", IntegerValue (-4)); + NS_TEST_ASSERT_MSG_EQ (m_newValue, -4, "Trace 3 did not fire as expected"); + + // + // Do a trace connect (with context) to some of the sources. + // + Config::Connect ("/NodeA/NodeB/NodesB/[0-1]|3/Source", + MakeCallback (&ObjectVectorTraceConfigTestCase::TraceWithPath, this)); + + // + // If we bug the trace source referred to by index '0' above, we should see + // the trace fire with the expected context path. + // + m_newValue = 0; + m_path = ""; + obj0->SetAttribute ("Source", IntegerValue (-1)); + NS_TEST_ASSERT_MSG_EQ (m_newValue, -1, "Trace 0 did not fire as expected"); + NS_TEST_ASSERT_MSG_EQ (m_path, "/NodeA/NodeB/NodesB/0/Source", "Trace 0 did not provide expected context"); + + // + // If we bug the trace source referred to by index '1' above, we should see + // the trace fire with the expected context path. + // + m_newValue = 0; + m_path = ""; + obj1->SetAttribute ("Source", IntegerValue (-2)); + NS_TEST_ASSERT_MSG_EQ (m_newValue, -2, "Trace 1 did not fire as expected"); + NS_TEST_ASSERT_MSG_EQ (m_path, "/NodeA/NodeB/NodesB/1/Source", "Trace 1 did not provide expected context"); + + // + // If we bug the trace source referred to by index '2' which is skipped above, + // we should not see the trace fire. + // + m_newValue = 0; + m_path = ""; + obj2->SetAttribute ("Source", IntegerValue (-3)); + NS_TEST_ASSERT_MSG_EQ (m_newValue, 0, "Trace 2 fired unexpectedly"); + + // + // If we bug the trace source referred to by index '3' above, we should see + // the trace fire with the expected context path. + // + m_newValue = 0; + m_path = ""; + obj3->SetAttribute ("Source", IntegerValue (-4)); + NS_TEST_ASSERT_MSG_EQ (m_newValue, -4, "Trace 3 did not fire as expected"); + NS_TEST_ASSERT_MSG_EQ (m_path, "/NodeA/NodeB/NodesB/1/Source", "Trace 1 did not provide expected context"); +} + +// =========================================================================== +// The Test Suite that glues all of the Test Cases together. +// =========================================================================== +class ConfigTestSuite : public TestSuite +{ +public: + ConfigTestSuite (); +}; + +ConfigTestSuite::ConfigTestSuite () + : TestSuite ("config", BVT) +{ + AddTestCase (new RootNamespaceConfigTestCase); + AddTestCase (new UnderRootNamespaceConfigTestCase); + AddTestCase (new ObjectVectorConfigTestCase); +} + +static ConfigTestSuite configTestSuite; + +} // namespace ns3 diff --git a/src/core/test/global-value-test-suite.cc b/src/core/test/global-value-test-suite.cc new file mode 100644 index 000000000..407541134 --- /dev/null +++ b/src/core/test/global-value-test-suite.cc @@ -0,0 +1,94 @@ +/* -*- 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 + */ +#include "ns3/global-value.h" +#include "ns3/test.h" +#include "ns3/uinteger.h" + +namespace ns3 { + +// =========================================================================== +// Test for the ability to get at a GlobalValue. +// =========================================================================== +class GlobalValueTestCase : public TestCase +{ +public: + GlobalValueTestCase (); + virtual ~GlobalValueTestCase () {} + +private: + virtual void DoRun (void); +}; + +GlobalValueTestCase::GlobalValueTestCase () + : TestCase ("Check GlobalValue mechanism") +{ +} + +void +GlobalValueTestCase::DoRun (void) +{ + // + // Typically these are static globals but we can make one on the stack to + // keep it hidden from the documentation. + // + GlobalValue uint = GlobalValue ("TestUint", "help text", + UintegerValue (10), + MakeUintegerChecker ()); + + // + // Make sure we can get at the value and that it was initialized correctly. + // + UintegerValue uv; + uint.GetValue (uv); + NS_TEST_ASSERT_MSG_EQ (uv.Get (), 10, "GlobalValue \"TestUint\" not initialized as expected"); + + // + // Remove the global value for a valgrind clean run + // + GlobalValue::Vector *vector = GlobalValue::GetVector (); + for (GlobalValue::Vector::iterator i = vector->begin (); i != vector->end (); ++i) + { + if ((*i) == &uint) + { + vector->erase (i); + break; + } + } +} + +// =========================================================================== +// The Test Suite that glues all of the Test Cases together. +// =========================================================================== +class GlobalValueTestSuite : public TestSuite +{ +public: + GlobalValueTestSuite (); +}; + +GlobalValueTestSuite::GlobalValueTestSuite () + : TestSuite ("global-value", BVT) +{ + AddTestCase (new GlobalValueTestCase); +} + +static GlobalValueTestSuite globalValueTestSuite; + +} // namespace ns3 + diff --git a/src/core/test/object-test-suite.cc b/src/core/test/object-test-suite.cc new file mode 100644 index 000000000..2c899976e --- /dev/null +++ b/src/core/test/object-test-suite.cc @@ -0,0 +1,429 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INRIA, Gustavo Carneiro + * + * 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: Gustavo Carneiro , + * Mathieu Lacage + */ +#include "ns3/test.h" +#include "ns3/object.h" +#include "ns3/object-factory.h" +#include "ns3/assert.h" + +namespace { + +class BaseA : public ns3::Object +{ +public: + static ns3::TypeId GetTypeId (void) { + static ns3::TypeId tid = ns3::TypeId ("BaseA") + .SetParent (Object::GetTypeId ()) + .HideFromDocumentation () + .AddConstructor (); + return tid; + } + BaseA () + {} + virtual void Dispose (void) {} +}; + +class DerivedA : public BaseA +{ +public: + static ns3::TypeId GetTypeId (void) { + static ns3::TypeId tid = ns3::TypeId ("DerivedA") + .SetParent (BaseA::GetTypeId ()) + .HideFromDocumentation () + .AddConstructor (); + return tid; + } + DerivedA () + {} + virtual void Dispose (void) { + BaseA::Dispose (); + } +}; + +class BaseB : public ns3::Object +{ +public: + static ns3::TypeId GetTypeId (void) { + static ns3::TypeId tid = ns3::TypeId ("BaseB") + .SetParent (Object::GetTypeId ()) + .HideFromDocumentation () + .AddConstructor (); + return tid; + } + BaseB () + {} + virtual void Dispose (void) {} +}; + +class DerivedB : public BaseB +{ +public: + static ns3::TypeId GetTypeId (void) { + static ns3::TypeId tid = ns3::TypeId ("DerivedB") + .SetParent (BaseB::GetTypeId ()) + .HideFromDocumentation () + .AddConstructor (); + return tid; + } + DerivedB () + {} + virtual void Dispose (void) { + BaseB::Dispose (); + } +}; + +NS_OBJECT_ENSURE_REGISTERED (BaseA); +NS_OBJECT_ENSURE_REGISTERED (DerivedA); +NS_OBJECT_ENSURE_REGISTERED (BaseB); +NS_OBJECT_ENSURE_REGISTERED (DerivedB); + +} // namespace anonymous + +namespace ns3 { + +// =========================================================================== +// Test case to make sure that we can make Objects using CreateObject. +// =========================================================================== +class CreateObjectTestCase : public TestCase +{ +public: + CreateObjectTestCase (); + virtual ~CreateObjectTestCase (); + +private: + virtual void DoRun (void); +}; + +CreateObjectTestCase::CreateObjectTestCase () + : TestCase ("Check CreateObject template function") +{ +} + +CreateObjectTestCase::~CreateObjectTestCase () +{ +} + +void +CreateObjectTestCase::DoRun (void) +{ + Ptr baseA = CreateObject (); + NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject"); + + // + // Since baseA is a BaseA, we must be able to successfully ask for a BaseA. + // + NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (), baseA, "GetObject() of same type returns different Ptr"); + + // + // Since BaseA is a BaseA and not a DerivedA, we must not find a DerivedA if we look. + // + NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (), 0, "GetObject() of unrelated type returns nonzero pointer"); + + // + // Since baseA is not a BaseA, we must not be able to ask for a DerivedA even if we + // try an implied cast back to a BaseA. + // + NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (DerivedA::GetTypeId ()), 0, "GetObject() of unrelated returns nonzero Ptr"); + + baseA = CreateObject (); + NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject with implicit cast to BaseA"); + + // + // If we create a DerivedA and cast it to a BaseA, then if we do a GetObject for + // that BaseA we should get the same address (same Object). + // + NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (), baseA, "Unable to GetObject on BaseA"); + + // + // Since we created a DerivedA and cast it to a BaseA, we should be able to + // get back a DerivedA and it should be the original Ptr. + // + NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (), baseA, "GetObject() of the original type returns different Ptr"); + + // If we created a DerivedA and cast it to a BaseA, then we GetObject for the + // same DerivedA and cast it back to the same BaseA, we should get the same + // object. + // + NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (DerivedA::GetTypeId ()), baseA, "GetObject returns different Ptr"); +} + +// =========================================================================== +// Test case to make sure that we can aggregate Objects. +// =========================================================================== +class AggregateObjectTestCase : public TestCase +{ +public: + AggregateObjectTestCase (); + virtual ~AggregateObjectTestCase (); + +private: + virtual void DoRun (void); +}; + +AggregateObjectTestCase::AggregateObjectTestCase () + : TestCase ("Check Object aggregation functionality") +{ +} + +AggregateObjectTestCase::~AggregateObjectTestCase () +{ +} + +void +AggregateObjectTestCase::DoRun (void) +{ + Ptr baseA = CreateObject (); + NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject"); + + Ptr baseB = CreateObject (); + NS_TEST_ASSERT_MSG_NE (baseB, 0, "Unable to CreateObject"); + + Ptr baseBCopy = baseB; + NS_TEST_ASSERT_MSG_NE (baseBCopy, 0, "Unable to copy BaseB"); + + // + // Make an aggregation of a BaseA object and a BaseB object. + // + baseA->AggregateObject (baseB); + + // + // We should be able to ask the aggregation (through baseA) for the BaseA part + // of the aggregation. + // + NS_TEST_ASSERT_MSG_NE (baseA->GetObject (), 0, "Cannot GetObject (through baseA) for BaseA Object"); + + // + // There is no DerivedA in this picture, so we should not be able to GetObject + // for that type. + // + NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (), 0, "Unexpectedly found a DerivedA through baseA"); + + // + // We should be able to ask the aggregation (through baseA) for the BaseB part + // + NS_TEST_ASSERT_MSG_NE (baseA->GetObject (), 0, "Cannot GetObject (through baseA) for BaseB Object"); + + // + // There is no DerivedB in this picture, so we should not be able to GetObject + // for that type. + // + NS_TEST_ASSERT_MSG_EQ (baseA->GetObject (), 0, "Unexpectedly found a DerivedB through baseA"); + + // + // We should be able to ask the aggregation (through baseA) for the BaseB part + // + NS_TEST_ASSERT_MSG_NE (baseB->GetObject (), 0, "Cannot GetObject (through baseB) for BaseB Object"); + + // + // There is no DerivedB in this picture, so we should not be able to GetObject + // for that type. + // + NS_TEST_ASSERT_MSG_EQ (baseB->GetObject (), 0, "Unexpectedly found a DerivedB through baseB"); + + // + // We should be able to ask the aggregation (through baseB) for the BaseA part + // of the aggregation. + // + NS_TEST_ASSERT_MSG_NE (baseB->GetObject (), 0, "Cannot GetObject (through baseB) for BaseA Object"); + + // + // There is no DerivedA in this picture, so we should not be able to GetObject + // for that type. + // + NS_TEST_ASSERT_MSG_EQ (baseB->GetObject (), 0, "Unexpectedly found a DerivedA through baseB"); + + // + // baseBCopy is a copy of the original Ptr to the Object BaseB. Even though + // we didn't use baseBCopy directly in the aggregations, the object to which + // it points was used, therefore, we should be able to use baseBCopy as if + // it were baseB and get a BaseA out of the aggregation. + // + NS_TEST_ASSERT_MSG_NE (baseBCopy->GetObject (), 0, "Cannot GetObject (through baseBCopy) for a BaseA Object"); + + // + // Now, change the underlying type of the objects to be the derived types. + // + baseA = CreateObject (); + NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject with implicit cast to BaseA"); + + baseB = CreateObject (); + NS_TEST_ASSERT_MSG_NE (baseB, 0, "Unable to CreateObject with implicit cast to BaseB"); + + // + // Create an aggregation of two objects, both of the derived types; and leave + // an unaggregated copy of one lying around. + // + baseBCopy = baseB; + baseA->AggregateObject (baseB); + + // + // We should be able to ask the aggregation (through baseA) for the DerivedB part + // + NS_TEST_ASSERT_MSG_NE (baseA->GetObject (), 0, "Cannot GetObject (through baseA) for DerivedB Object"); + + // + // Since the DerivedB is also a BaseB, we should be able to ask the aggregation + // (through baseA) for the BaseB part + // + NS_TEST_ASSERT_MSG_NE (baseA->GetObject (), 0, "Cannot GetObject (through baseA) for BaseB Object"); + + // + // We should be able to ask the aggregation (through baseB) for the DerivedA part + // + NS_TEST_ASSERT_MSG_NE (baseB->GetObject (), 0, "Cannot GetObject (through baseB) for DerivedA Object"); + + // + // Since the DerivedA is also a BaseA, we should be able to ask the aggregation + // (through baseB) for the BaseA part + // + NS_TEST_ASSERT_MSG_NE (baseB->GetObject (), 0, "Cannot GetObject (through baseB) for BaseA Object"); + + // + // baseBCopy is a copy of the original Ptr to the Object BaseB. Even though + // we didn't use baseBCopy directly in the aggregations, the object to which + // it points was used, therefore, we should be able to use baseBCopy as if + // it were baseB (same underlying Object) and get a BaseA and a DerivedA out + // of the aggregation through baseBCopy. + // + NS_TEST_ASSERT_MSG_NE (baseBCopy->GetObject (), 0, "Cannot GetObject (through baseBCopy) for a BaseA Object"); + NS_TEST_ASSERT_MSG_NE (baseBCopy->GetObject (), 0, "Cannot GetObject (through baseBCopy) for a BaseA Object"); + + // + // Since the Ptr is actually a DerivedB, we should be able to ask the + // aggregation (through baseB) for the DerivedB part + // + NS_TEST_ASSERT_MSG_NE (baseB->GetObject (), 0, "Cannot GetObject (through baseB) for DerivedB Object"); + + // + // Since the DerivedB was cast to a BaseB, we should be able to ask the + // aggregation (through baseB) for the BaseB part + // + NS_TEST_ASSERT_MSG_NE (baseB->GetObject (), 0, "Cannot GetObject (through baseB) for BaseB Object"); + + // + // Make sure reference counting works in the aggregate. Create two Objects + // and aggregate them, then release one of them. The aggregation should + // keep a reference to both and the Object we released should still be there. + // + baseA = CreateObject (); + NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject"); + + baseB = CreateObject (); + NS_TEST_ASSERT_MSG_NE (baseB, 0, "Unable to CreateObject"); + + baseA->AggregateObject (baseB); + baseA = 0; + + baseA = baseB->GetObject (); + NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to GetObject on released object"); +} + +// =========================================================================== +// Test case to make sure that an Object factory can create Objects +// =========================================================================== +class ObjectFactoryTestCase : public TestCase +{ +public: + ObjectFactoryTestCase (); + virtual ~ObjectFactoryTestCase (); + +private: + virtual void DoRun (void); +}; + +ObjectFactoryTestCase::ObjectFactoryTestCase () + : TestCase ("Check ObjectFactory functionality") +{ +} + +ObjectFactoryTestCase::~ObjectFactoryTestCase () +{ +} + +void +ObjectFactoryTestCase::DoRun (void) +{ + ObjectFactory factory; + + // + // Create an Object of type BaseA through an object factory. + // + factory.SetTypeId (BaseA::GetTypeId ()); + Ptr a = factory.Create (); + NS_TEST_ASSERT_MSG_NE (a, 0, "Unable to factory.Create() a BaseA"); + + // + // What we made should be a BaseA, not have anything to do with a DerivedA + // + NS_TEST_ASSERT_MSG_EQ (a->GetObject (DerivedA::GetTypeId ()), 0, "BaseA is unexpectedly a DerivedA also"); + + // + // The BaseA we got should not respond to a GetObject for DerivedA + // + NS_TEST_ASSERT_MSG_EQ (a->GetObject (), 0, "BaseA unexpectedly responds to GetObject for DerivedA"); + + // + // Now tell the factory to make DerivedA Objects and create one with an + // implied cast back to a BaseA + // + factory.SetTypeId (DerivedA::GetTypeId ()); + a = factory.Create (); + + // + // Since the DerivedA has a BaseA part, we should be able to use GetObject to + // dynamically cast back to a BaseA. + // + NS_TEST_ASSERT_MSG_EQ (a->GetObject (), a, "Unable to use GetObject as dynamic_cast()"); + + // + // Since a is already a BaseA and is really a DerivedA, we should be able to + // GetObject for the DerivedA and cast it back to a BaseA getting the same + // value that is there. + // + NS_TEST_ASSERT_MSG_EQ (a->GetObject (DerivedA::GetTypeId ()), a, "GetObject with implied cast returns different Ptr"); + + // + // Since a declared a BaseA, even if it is really a DerivedA, we should not + // be able to GetOBject for a DerivedA since this would break the type + // declaration. + // + NS_TEST_ASSERT_MSG_NE (a->GetObject (), 0, "Unexpectedly able to work around C++ type system"); +} + +// =========================================================================== +// The Test Suite that glues the Test Cases together. +// =========================================================================== +class ObjectTestSuite : public TestSuite +{ +public: + ObjectTestSuite (); +}; + +ObjectTestSuite::ObjectTestSuite () + : TestSuite ("object", BVT) +{ + AddTestCase (new CreateObjectTestCase); + AddTestCase (new AggregateObjectTestCase); + AddTestCase (new ObjectFactoryTestCase); +} + +static ObjectTestSuite objectTestSuite; + +} // namespace ns3 diff --git a/src/core/test/random-variable-test-suite.cc b/src/core/test/random-variable-test-suite.cc new file mode 100644 index 000000000..d2ad40496 --- /dev/null +++ b/src/core/test/random-variable-test-suite.cc @@ -0,0 +1,147 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +// +// Copyright (c) 2006 Georgia Tech Research Corporation +// +// 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 +// +// Author: Rajib Bhattacharjea +// Author: Hadi Arbabi +// + +#include +#include + +#include "ns3/test.h" +#include "ns3/assert.h" +#include "ns3/integer.h" +#include "ns3/random-variable.h" + +using namespace std; + +namespace ns3 { +class BasicRandomNumberTestCase : public TestCase +{ +public: + BasicRandomNumberTestCase (); + virtual ~BasicRandomNumberTestCase () + { + } + +private: + virtual void DoRun (void); +}; + +BasicRandomNumberTestCase::BasicRandomNumberTestCase () + : TestCase ("Check basic random number operation") +{ +} + +void +BasicRandomNumberTestCase::DoRun (void) +{ + const double desiredMean = 1.0; + const double desiredStdDev = 1.0; + + double tmp = log (1 + (desiredStdDev / desiredMean) * (desiredStdDev / desiredMean)); + double sigma = sqrt (tmp); + double mu = log (desiredMean) - 0.5 * tmp; + + // + // Test a custom lognormal instance to see if its moments have any relation + // expected reality. + // + LogNormalVariable lognormal (mu, sigma); + vector samples; + const int NSAMPLES = 10000; + double sum = 0; + + // + // Get and store a bunch of samples. As we go along sum them and then find + // the mean value of the samples. + // + for (int n = NSAMPLES; n; --n) + { + double value = lognormal.GetValue (); + sum += value; + samples.push_back (value); + } + double obtainedMean = sum / NSAMPLES; + NS_TEST_EXPECT_MSG_EQ_TOL (obtainedMean, desiredMean, 0.1, "Got unexpected mean value from LogNormalVariable"); + + // + // Wander back through the saved stamples and find their standard deviation + // + sum = 0; + for (vector::iterator iter = samples.begin (); iter != samples.end (); iter++) + { + double tmp = (*iter - obtainedMean); + sum += tmp * tmp; + } + double obtainedStdDev = sqrt (sum / (NSAMPLES - 1)); + NS_TEST_EXPECT_MSG_EQ_TOL (obtainedStdDev, desiredStdDev, 0.1, "Got unexpected standard deviation from LogNormalVariable"); +} + +class RandomNumberSerializationTestCase : public TestCase +{ +public: + RandomNumberSerializationTestCase (); + virtual ~RandomNumberSerializationTestCase () + { + } + +private: + virtual void DoRun (void); +}; + +RandomNumberSerializationTestCase::RandomNumberSerializationTestCase () + : TestCase ("Check basic random number operation") +{ +} + +void +RandomNumberSerializationTestCase::DoRun (void) +{ + RandomVariableValue val; + val.DeserializeFromString ("Uniform:0.1:0.2", MakeRandomVariableChecker ()); + RandomVariable rng = val.Get (); + NS_TEST_ASSERT_MSG_EQ (val.SerializeToString (MakeRandomVariableChecker ()), "Uniform:0.1:0.2", + "Deserialize and Serialize \"Uniform:0.1:0.2\" mismatch"); + + val.DeserializeFromString ("Normal:0.1:0.2", MakeRandomVariableChecker ()); + rng = val.Get (); + NS_TEST_ASSERT_MSG_EQ (val.SerializeToString (MakeRandomVariableChecker ()), "Normal:0.1:0.2", + "Deserialize and Serialize \"Normal:0.1:0.2\" mismatch"); + + val.DeserializeFromString ("Normal:0.1:0.2:0.15", MakeRandomVariableChecker ()); + rng = val.Get (); + NS_TEST_ASSERT_MSG_EQ (val.SerializeToString (MakeRandomVariableChecker ()), "Normal:0.1:0.2:0.15", + "Deserialize and Serialize \"Normal:0.1:0.2:0.15\" mismatch"); +} + +class BasicRandomNumberTestSuite : public TestSuite +{ +public: + BasicRandomNumberTestSuite (); +}; + +BasicRandomNumberTestSuite::BasicRandomNumberTestSuite () + : TestSuite ("basic-random-number", BVT) +{ + AddTestCase (new BasicRandomNumberTestCase); + AddTestCase (new RandomNumberSerializationTestCase); +} + +static BasicRandomNumberTestSuite BasicRandomNumberTestSuite; + +} // namespace ns3 diff --git a/src/core/wscript b/src/core/wscript index 2193233ca..e288f20cc 100644 --- a/src/core/wscript +++ b/src/core/wscript @@ -144,9 +144,14 @@ def build(bld): core_test.source = [ 'test/attribute-test-suite.cc', 'test/callback-test-suite.cc', + 'test/command-line-test-suite.cc', + 'test/config-test-suite.cc', + 'test/global-value-test-suite.cc', 'test/high-precision-test-suite.cc', 'test/names-test-suite.cc', + 'test/object-test-suite.cc', 'test/ptr-test-suite.cc', + 'test/random-variable-test-suite.cc', 'test/simulator-test-suite.cc', 'test/time-test-suite.cc', 'test/timer-test-suite.cc', @@ -173,6 +178,7 @@ def build(bld): 'model/calendar-scheduler.h', 'model/ns2-calendar-scheduler.h', 'model/simulation-singleton.h', + 'model/singleton.h', 'model/timer.h', 'model/timer-impl.h', 'model/watchdog.h',