Move tests from core module to its test library and update CHANGES.html

This commit is contained in:
Mitch Watrous
2011-04-06 15:32:12 -07:00
parent e54bd196ec
commit a0ab62ad90
12 changed files with 1528 additions and 1371 deletions

View File

@@ -62,6 +62,11 @@ You can now make tests be built in ns-3 in two ways.
</pre>
</ol>
</p></li>
<li><b> Subsets of modules can be enabled using the ns-3 configuration file</b>
<p>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.
</p></li>
</ul>
<h2>New API:</h2>

View File

@@ -22,7 +22,6 @@
#include "config.h"
#include "global-value.h"
#include "type-id.h"
#include "test.h"
#include "string.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -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

View File

@@ -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 <sstream>
NS_LOG_COMPONENT_DEFINE ("Config");
@@ -654,582 +648,4 @@ Ptr<Object> 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<ConfigTestObject> a);
void AddNodeB (Ptr<ConfigTestObject> b);
void SetNodeA (Ptr<ConfigTestObject> a);
void SetNodeB (Ptr<ConfigTestObject> b);
int8_t GetA (void) const;
int8_t GetB (void) const;
private:
std::vector<Ptr<ConfigTestObject> > m_nodesA;
std::vector<Ptr<ConfigTestObject> > m_nodesB;
Ptr<ConfigTestObject> m_nodeA;
Ptr<ConfigTestObject> m_nodeB;
int8_t m_a;
int8_t m_b;
TracedValue<int16_t> m_trace;
};
TypeId
ConfigTestObject::GetTypeId (void)
{
static TypeId tid = TypeId ("ConfigTestObject")
.SetParent<Object> ()
.AddAttribute ("NodesA", "",
ObjectVectorValue (),
MakeObjectVectorAccessor (&ConfigTestObject::m_nodesA),
MakeObjectVectorChecker<ConfigTestObject> ())
.AddAttribute ("NodesB", "",
ObjectVectorValue (),
MakeObjectVectorAccessor (&ConfigTestObject::m_nodesB),
MakeObjectVectorChecker<ConfigTestObject> ())
.AddAttribute ("NodeA", "",
PointerValue (),
MakePointerAccessor (&ConfigTestObject::m_nodeA),
MakePointerChecker<ConfigTestObject> ())
.AddAttribute ("NodeB", "",
PointerValue (),
MakePointerAccessor (&ConfigTestObject::m_nodeB),
MakePointerChecker<ConfigTestObject> ())
.AddAttribute ("A", "",
IntegerValue (10),
MakeIntegerAccessor (&ConfigTestObject::m_a),
MakeIntegerChecker<int8_t> ())
.AddAttribute ("B", "",
IntegerValue (9),
MakeIntegerAccessor (&ConfigTestObject::m_b),
MakeIntegerChecker<int8_t> ())
.AddAttribute ("Source", "XX",
IntegerValue (-1),
MakeIntegerAccessor (&ConfigTestObject::m_trace),
MakeIntegerChecker<int16_t> ())
.AddTraceSource ("Source", "XX",
MakeTraceSourceAccessor (&ConfigTestObject::m_trace))
;
return tid;
}
void
ConfigTestObject::SetNodeA (Ptr<ConfigTestObject> a)
{
m_nodeA = a;
}
void
ConfigTestObject::SetNodeB (Ptr<ConfigTestObject> b)
{
m_nodeB = b;
}
void
ConfigTestObject::AddNodeA (Ptr<ConfigTestObject> a)
{
m_nodesA.push_back (a);
}
void
ConfigTestObject::AddNodeB (Ptr<ConfigTestObject> 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<ConfigTestObject> root = CreateObject<ConfigTestObject> ();
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<ConfigTestObject> root = CreateObject<ConfigTestObject> ();
Config::RegisterRootNamespaceObject (root);
Ptr<ConfigTestObject> a = CreateObject<ConfigTestObject> ();
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<ConfigTestObject> b = CreateObject<ConfigTestObject> ();
//
// 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<ConfigTestObject> root = CreateObject<ConfigTestObject> ();
Config::RegisterRootNamespaceObject (root);
//
// Create an object under the root.
//
Ptr<ConfigTestObject> a = CreateObject<ConfigTestObject> ();
root->SetNodeA (a);
//
// Create an object one level down.
//
Ptr<ConfigTestObject> b = CreateObject<ConfigTestObject> ();
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<ConfigTestObject> obj0 = CreateObject<ConfigTestObject> ();
Ptr<ConfigTestObject> obj1 = CreateObject<ConfigTestObject> ();
Ptr<ConfigTestObject> obj2 = CreateObject<ConfigTestObject> ();
Ptr<ConfigTestObject> obj3 = CreateObject<ConfigTestObject> ();
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<ConfigTestObject> root = CreateObject<ConfigTestObject> ();
Config::RegisterRootNamespaceObject (root);
//
// Create an object under the root.
//
Ptr<ConfigTestObject> a = CreateObject<ConfigTestObject> ();
root->SetNodeA (a);
//
// Create an object one level down.
//
Ptr<ConfigTestObject> b = CreateObject<ConfigTestObject> ();
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<ConfigTestObject> obj0 = CreateObject<ConfigTestObject> ();
Ptr<ConfigTestObject> obj1 = CreateObject<ConfigTestObject> ();
Ptr<ConfigTestObject> obj2 = CreateObject<ConfigTestObject> ();
Ptr<ConfigTestObject> obj3 = CreateObject<ConfigTestObject> ();
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

View File

@@ -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<uint32_t> ());
//
// 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

View File

@@ -18,7 +18,6 @@
* Authors: Gustavo Carneiro <gjcarneiro@gmail.com>,
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#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<BaseA> ();
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<DerivedA> ();
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<BaseB> ();
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<DerivedB> ();
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<Type> template function")
{
}
CreateObjectTestCase::~CreateObjectTestCase ()
{
}
void
CreateObjectTestCase::DoRun (void)
{
Ptr<BaseA> baseA = CreateObject<BaseA> ();
NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject<BaseA>");
//
// Since baseA is a BaseA, we must be able to successfully ask for a BaseA.
//
NS_TEST_ASSERT_MSG_EQ (baseA->GetObject<BaseA> (), 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<DerivedA> (), 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<BaseA> (DerivedA::GetTypeId ()), 0, "GetObject() of unrelated returns nonzero Ptr");
baseA = CreateObject<DerivedA> ();
NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject<DerivedA> 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> (), baseA, "Unable to GetObject<BaseA> 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<DerivedA> (), 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<BaseA> (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> baseA = CreateObject<BaseA> ();
NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject<BaseA>");
Ptr<BaseB> baseB = CreateObject<BaseB> ();
NS_TEST_ASSERT_MSG_NE (baseB, 0, "Unable to CreateObject<BaseB>");
Ptr<BaseB> 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<BaseA> (), 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<DerivedA> (), 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<BaseB> (), 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<DerivedB> (), 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<BaseB> (), 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<DerivedB> (), 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<BaseA> (), 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<DerivedA> (), 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<BaseA> (), 0, "Cannot GetObject (through baseBCopy) for a BaseA Object");
//
// Now, change the underlying type of the objects to be the derived types.
//
baseA = CreateObject<DerivedA> ();
NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject<DerivedA> with implicit cast to BaseA");
baseB = CreateObject<DerivedB> ();
NS_TEST_ASSERT_MSG_NE (baseB, 0, "Unable to CreateObject<DerivedB> 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<DerivedB> (), 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<BaseB> (), 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<DerivedA> (), 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<BaseA> (), 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<BaseA> (), 0, "Cannot GetObject (through baseBCopy) for a BaseA Object");
NS_TEST_ASSERT_MSG_NE (baseBCopy->GetObject<DerivedA> (), 0, "Cannot GetObject (through baseBCopy) for a BaseA Object");
//
// Since the Ptr<BaseB> 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<DerivedB> (), 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<BaseB> (), 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<BaseA> ();
NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject<BaseA>");
baseB = CreateObject<BaseB> ();
NS_TEST_ASSERT_MSG_NE (baseB, 0, "Unable to CreateObject<BaseA>");
baseA->AggregateObject (baseB);
baseA = 0;
baseA = baseB->GetObject<BaseA> ();
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<Object> 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<BaseA> (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<DerivedA> (), 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<BaseA> (), a, "Unable to use GetObject as dynamic_cast<BaseA>()");
//
// 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<BaseA> (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<DerivedA> (), 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

View File

@@ -32,7 +32,6 @@
#include <sstream>
#include <vector>
#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<double> 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<double>::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

View File

@@ -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 <mathieu.lacage@sophia.inria.fr>
*/
#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 <stdlib.h>
#include <stdarg.h>
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

View File

@@ -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 <mathieu.lacage@sophia.inria.fr>
*/
#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 <sstream>
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<ConfigTestObject> a);
void AddNodeB (Ptr<ConfigTestObject> b);
void SetNodeA (Ptr<ConfigTestObject> a);
void SetNodeB (Ptr<ConfigTestObject> b);
int8_t GetA (void) const;
int8_t GetB (void) const;
private:
std::vector<Ptr<ConfigTestObject> > m_nodesA;
std::vector<Ptr<ConfigTestObject> > m_nodesB;
Ptr<ConfigTestObject> m_nodeA;
Ptr<ConfigTestObject> m_nodeB;
int8_t m_a;
int8_t m_b;
TracedValue<int16_t> m_trace;
};
TypeId
ConfigTestObject::GetTypeId (void)
{
static TypeId tid = TypeId ("ConfigTestObject")
.SetParent<Object> ()
.AddAttribute ("NodesA", "",
ObjectVectorValue (),
MakeObjectVectorAccessor (&ConfigTestObject::m_nodesA),
MakeObjectVectorChecker<ConfigTestObject> ())
.AddAttribute ("NodesB", "",
ObjectVectorValue (),
MakeObjectVectorAccessor (&ConfigTestObject::m_nodesB),
MakeObjectVectorChecker<ConfigTestObject> ())
.AddAttribute ("NodeA", "",
PointerValue (),
MakePointerAccessor (&ConfigTestObject::m_nodeA),
MakePointerChecker<ConfigTestObject> ())
.AddAttribute ("NodeB", "",
PointerValue (),
MakePointerAccessor (&ConfigTestObject::m_nodeB),
MakePointerChecker<ConfigTestObject> ())
.AddAttribute ("A", "",
IntegerValue (10),
MakeIntegerAccessor (&ConfigTestObject::m_a),
MakeIntegerChecker<int8_t> ())
.AddAttribute ("B", "",
IntegerValue (9),
MakeIntegerAccessor (&ConfigTestObject::m_b),
MakeIntegerChecker<int8_t> ())
.AddAttribute ("Source", "XX",
IntegerValue (-1),
MakeIntegerAccessor (&ConfigTestObject::m_trace),
MakeIntegerChecker<int16_t> ())
.AddTraceSource ("Source", "XX",
MakeTraceSourceAccessor (&ConfigTestObject::m_trace))
;
return tid;
}
void
ConfigTestObject::SetNodeA (Ptr<ConfigTestObject> a)
{
m_nodeA = a;
}
void
ConfigTestObject::SetNodeB (Ptr<ConfigTestObject> b)
{
m_nodeB = b;
}
void
ConfigTestObject::AddNodeA (Ptr<ConfigTestObject> a)
{
m_nodesA.push_back (a);
}
void
ConfigTestObject::AddNodeB (Ptr<ConfigTestObject> 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<ConfigTestObject> root = CreateObject<ConfigTestObject> ();
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<ConfigTestObject> root = CreateObject<ConfigTestObject> ();
Config::RegisterRootNamespaceObject (root);
Ptr<ConfigTestObject> a = CreateObject<ConfigTestObject> ();
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<ConfigTestObject> b = CreateObject<ConfigTestObject> ();
//
// 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<ConfigTestObject> root = CreateObject<ConfigTestObject> ();
Config::RegisterRootNamespaceObject (root);
//
// Create an object under the root.
//
Ptr<ConfigTestObject> a = CreateObject<ConfigTestObject> ();
root->SetNodeA (a);
//
// Create an object one level down.
//
Ptr<ConfigTestObject> b = CreateObject<ConfigTestObject> ();
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<ConfigTestObject> obj0 = CreateObject<ConfigTestObject> ();
Ptr<ConfigTestObject> obj1 = CreateObject<ConfigTestObject> ();
Ptr<ConfigTestObject> obj2 = CreateObject<ConfigTestObject> ();
Ptr<ConfigTestObject> obj3 = CreateObject<ConfigTestObject> ();
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<ConfigTestObject> root = CreateObject<ConfigTestObject> ();
Config::RegisterRootNamespaceObject (root);
//
// Create an object under the root.
//
Ptr<ConfigTestObject> a = CreateObject<ConfigTestObject> ();
root->SetNodeA (a);
//
// Create an object one level down.
//
Ptr<ConfigTestObject> b = CreateObject<ConfigTestObject> ();
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<ConfigTestObject> obj0 = CreateObject<ConfigTestObject> ();
Ptr<ConfigTestObject> obj1 = CreateObject<ConfigTestObject> ();
Ptr<ConfigTestObject> obj2 = CreateObject<ConfigTestObject> ();
Ptr<ConfigTestObject> obj3 = CreateObject<ConfigTestObject> ();
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

View File

@@ -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 <mathieu.lacage@sophia.inria.fr>
*/
#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<uint32_t> ());
//
// 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

View File

@@ -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 <gjcarneiro@gmail.com>,
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#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<BaseA> ();
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<DerivedA> ();
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<BaseB> ();
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<DerivedB> ();
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<Type> template function")
{
}
CreateObjectTestCase::~CreateObjectTestCase ()
{
}
void
CreateObjectTestCase::DoRun (void)
{
Ptr<BaseA> baseA = CreateObject<BaseA> ();
NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject<BaseA>");
//
// Since baseA is a BaseA, we must be able to successfully ask for a BaseA.
//
NS_TEST_ASSERT_MSG_EQ (baseA->GetObject<BaseA> (), 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<DerivedA> (), 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<BaseA> (DerivedA::GetTypeId ()), 0, "GetObject() of unrelated returns nonzero Ptr");
baseA = CreateObject<DerivedA> ();
NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject<DerivedA> 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> (), baseA, "Unable to GetObject<BaseA> 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<DerivedA> (), 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<BaseA> (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> baseA = CreateObject<BaseA> ();
NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject<BaseA>");
Ptr<BaseB> baseB = CreateObject<BaseB> ();
NS_TEST_ASSERT_MSG_NE (baseB, 0, "Unable to CreateObject<BaseB>");
Ptr<BaseB> 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<BaseA> (), 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<DerivedA> (), 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<BaseB> (), 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<DerivedB> (), 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<BaseB> (), 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<DerivedB> (), 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<BaseA> (), 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<DerivedA> (), 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<BaseA> (), 0, "Cannot GetObject (through baseBCopy) for a BaseA Object");
//
// Now, change the underlying type of the objects to be the derived types.
//
baseA = CreateObject<DerivedA> ();
NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject<DerivedA> with implicit cast to BaseA");
baseB = CreateObject<DerivedB> ();
NS_TEST_ASSERT_MSG_NE (baseB, 0, "Unable to CreateObject<DerivedB> 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<DerivedB> (), 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<BaseB> (), 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<DerivedA> (), 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<BaseA> (), 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<BaseA> (), 0, "Cannot GetObject (through baseBCopy) for a BaseA Object");
NS_TEST_ASSERT_MSG_NE (baseBCopy->GetObject<DerivedA> (), 0, "Cannot GetObject (through baseBCopy) for a BaseA Object");
//
// Since the Ptr<BaseB> 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<DerivedB> (), 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<BaseB> (), 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<BaseA> ();
NS_TEST_ASSERT_MSG_NE (baseA, 0, "Unable to CreateObject<BaseA>");
baseB = CreateObject<BaseB> ();
NS_TEST_ASSERT_MSG_NE (baseB, 0, "Unable to CreateObject<BaseA>");
baseA->AggregateObject (baseB);
baseA = 0;
baseA = baseB->GetObject<BaseA> ();
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<Object> 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<BaseA> (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<DerivedA> (), 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<BaseA> (), a, "Unable to use GetObject as dynamic_cast<BaseA>()");
//
// 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<BaseA> (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<DerivedA> (), 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

View File

@@ -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<raj.b@gatech.edu>
// Author: Hadi Arbabi<marbabi@cs.odu.edu>
//
#include <iostream>
#include <math.h>
#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<double> 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<double>::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

View File

@@ -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',