merge with HEAD
This commit is contained in:
@@ -18,7 +18,9 @@
|
||||
* 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"
|
||||
#include "singleton.h"
|
||||
#include "attribute.h"
|
||||
@@ -266,15 +268,8 @@ Object::MaybeDelete (void) const
|
||||
current = next;
|
||||
} while (current != end);
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
#ifdef RUN_SELF_TESTS
|
||||
|
||||
#include "test.h"
|
||||
#include "object-factory.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class BaseA : public ns3::Object
|
||||
@@ -350,87 +345,338 @@ NS_OBJECT_ENSURE_REGISTERED (DerivedB);
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class ObjectTest : public Test
|
||||
// ===========================================================================
|
||||
// Test case to make sure that we can make Objects using CreateObject.
|
||||
// ===========================================================================
|
||||
class CreateObjectTestCase : public TestCase
|
||||
{
|
||||
public:
|
||||
ObjectTest ();
|
||||
virtual bool RunTests (void);
|
||||
CreateObjectTestCase ();
|
||||
virtual ~CreateObjectTestCase ();
|
||||
|
||||
private:
|
||||
virtual bool DoRun (void);
|
||||
};
|
||||
|
||||
ObjectTest::ObjectTest ()
|
||||
: Test ("Object")
|
||||
{}
|
||||
|
||||
bool
|
||||
ObjectTest::RunTests (void)
|
||||
CreateObjectTestCase::CreateObjectTestCase ()
|
||||
: TestCase ("Check CreateObject<Type> template function")
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
Ptr<BaseA> baseA = CreateObject<BaseA> ();
|
||||
NS_TEST_ASSERT_EQUAL (baseA->GetObject<BaseA> (), baseA);
|
||||
NS_TEST_ASSERT_EQUAL (baseA->GetObject<BaseA> (DerivedA::GetTypeId ()), 0);
|
||||
NS_TEST_ASSERT_EQUAL (baseA->GetObject<DerivedA> (), 0);
|
||||
baseA = CreateObject<DerivedA> ();
|
||||
NS_TEST_ASSERT_EQUAL (baseA->GetObject<BaseA> (), baseA);
|
||||
NS_TEST_ASSERT_EQUAL (baseA->GetObject<BaseA> (DerivedA::GetTypeId ()), baseA);
|
||||
NS_TEST_ASSERT_UNEQUAL (baseA->GetObject<DerivedA> (), 0);
|
||||
|
||||
baseA = CreateObject<BaseA> ();
|
||||
Ptr<BaseB> baseB = CreateObject<BaseB> ();
|
||||
Ptr<BaseB> baseBCopy = baseB;
|
||||
baseA->AggregateObject (baseB);
|
||||
NS_TEST_ASSERT_UNEQUAL (baseA->GetObject<BaseA> (), 0);
|
||||
NS_TEST_ASSERT_EQUAL (baseA->GetObject<DerivedA> (), 0);
|
||||
NS_TEST_ASSERT_UNEQUAL (baseA->GetObject<BaseB> (), 0);
|
||||
NS_TEST_ASSERT_EQUAL (baseA->GetObject<DerivedB> (), 0);
|
||||
NS_TEST_ASSERT_UNEQUAL (baseB->GetObject<BaseB> (), 0);
|
||||
NS_TEST_ASSERT_EQUAL (baseB->GetObject<DerivedB> (), 0);
|
||||
NS_TEST_ASSERT_UNEQUAL (baseB->GetObject<BaseA> (), 0);
|
||||
NS_TEST_ASSERT_EQUAL (baseB->GetObject<DerivedA> (), 0);
|
||||
NS_TEST_ASSERT_UNEQUAL (baseBCopy->GetObject<BaseA> (), 0);
|
||||
|
||||
baseA = CreateObject<DerivedA> ();
|
||||
baseB = CreateObject<DerivedB> ();
|
||||
baseBCopy = baseB;
|
||||
baseA->AggregateObject (baseB);
|
||||
NS_TEST_ASSERT_UNEQUAL (baseA->GetObject<DerivedB> (), 0);
|
||||
NS_TEST_ASSERT_UNEQUAL (baseA->GetObject<BaseB> (), 0);
|
||||
NS_TEST_ASSERT_UNEQUAL (baseB->GetObject<DerivedA> (), 0);
|
||||
NS_TEST_ASSERT_UNEQUAL (baseB->GetObject<BaseA> (), 0);
|
||||
NS_TEST_ASSERT_UNEQUAL (baseBCopy->GetObject<DerivedA> (), 0);
|
||||
NS_TEST_ASSERT_UNEQUAL (baseBCopy->GetObject<BaseA> (), 0);
|
||||
NS_TEST_ASSERT_UNEQUAL (baseB->GetObject<DerivedB> (), 0);
|
||||
NS_TEST_ASSERT_UNEQUAL (baseB->GetObject<BaseB> (), 0);
|
||||
|
||||
baseA = CreateObject<BaseA> ();
|
||||
baseB = CreateObject<BaseB> ();
|
||||
baseA->AggregateObject (baseB);
|
||||
baseA = 0;
|
||||
baseA = baseB->GetObject<BaseA> ();
|
||||
|
||||
|
||||
// Test the object creation code of TypeId
|
||||
ObjectFactory factory;
|
||||
factory.SetTypeId (BaseA::GetTypeId ());
|
||||
Ptr<Object> a = factory.Create ();
|
||||
NS_TEST_ASSERT_EQUAL (a->GetObject<BaseA> (), a);
|
||||
NS_TEST_ASSERT_EQUAL (a->GetObject<BaseA> (DerivedA::GetTypeId ()), 0);
|
||||
NS_TEST_ASSERT_EQUAL (a->GetObject<DerivedA> (), 0);
|
||||
factory.SetTypeId (DerivedA::GetTypeId ());
|
||||
a = factory.Create ();
|
||||
NS_TEST_ASSERT_EQUAL (a->GetObject<BaseA> (), a);
|
||||
NS_TEST_ASSERT_EQUAL (a->GetObject<BaseA> (DerivedA::GetTypeId ()), a);
|
||||
NS_TEST_ASSERT_UNEQUAL (a->GetObject<DerivedA> (), 0);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static ObjectTest g_interfaceObjectTests;
|
||||
CreateObjectTestCase::~CreateObjectTestCase ()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
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");
|
||||
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Test case to make sure that we can aggregate Objects.
|
||||
// ===========================================================================
|
||||
class AggregateObjectTestCase : public TestCase
|
||||
{
|
||||
public:
|
||||
AggregateObjectTestCase ();
|
||||
virtual ~AggregateObjectTestCase ();
|
||||
|
||||
private:
|
||||
virtual bool DoRun (void);
|
||||
};
|
||||
|
||||
AggregateObjectTestCase::AggregateObjectTestCase ()
|
||||
: TestCase ("Check Object aggregation functionality")
|
||||
{
|
||||
}
|
||||
|
||||
AggregateObjectTestCase::~AggregateObjectTestCase ()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
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");
|
||||
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Test case to make sure that an Object factory can create Objects
|
||||
// ===========================================================================
|
||||
class ObjectFactoryTestCase : public TestCase
|
||||
{
|
||||
public:
|
||||
ObjectFactoryTestCase ();
|
||||
virtual ~ObjectFactoryTestCase ();
|
||||
|
||||
private:
|
||||
virtual bool DoRun (void);
|
||||
};
|
||||
|
||||
ObjectFactoryTestCase::ObjectFactoryTestCase ()
|
||||
: TestCase ("Check ObjectFactory functionality")
|
||||
{
|
||||
}
|
||||
|
||||
ObjectFactoryTestCase::~ObjectFactoryTestCase ()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
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");
|
||||
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// 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);
|
||||
}
|
||||
|
||||
ObjectTestSuite objectTestSuite;
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* RUN_SELF_TESTS */
|
||||
|
||||
|
||||
|
||||
@@ -30,8 +30,9 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "test.h"
|
||||
#include "assert.h"
|
||||
#include "config.h"
|
||||
#include "integer.h"
|
||||
@@ -1710,96 +1711,118 @@ std::istream &operator >> (std::istream &is, RandomVariable &var)
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
|
||||
|
||||
#ifdef RUN_SELF_TESTS
|
||||
#include "test.h"
|
||||
#include <vector>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
class RandomVariableTest : public Test
|
||||
class BasicRandomNumberTestCase : public TestCase
|
||||
{
|
||||
public:
|
||||
RandomVariableTest () : Test ("RandomVariable") {}
|
||||
virtual bool RunTests (void)
|
||||
{
|
||||
bool result = true;
|
||||
const double desired_mean = 1.0;
|
||||
const double desired_stddev = 1.0;
|
||||
double tmp = log (1 + (desired_stddev/desired_mean)*(desired_stddev/desired_mean));
|
||||
double sigma = sqrt (tmp);
|
||||
double mu = log (desired_mean) - 0.5*tmp;
|
||||
BasicRandomNumberTestCase ();
|
||||
virtual ~BasicRandomNumberTestCase () {}
|
||||
|
||||
// Test a custom lognormal instance
|
||||
{
|
||||
LogNormalVariable lognormal (mu, sigma);
|
||||
vector<double> samples;
|
||||
const int NSAMPLES = 10000;
|
||||
double sum = 0;
|
||||
for (int n = NSAMPLES; n; --n)
|
||||
{
|
||||
double value = lognormal.GetValue ();
|
||||
sum += value;
|
||||
samples.push_back (value);
|
||||
}
|
||||
double obtained_mean = sum / NSAMPLES;
|
||||
sum = 0;
|
||||
for (vector<double>::iterator iter = samples.begin (); iter != samples.end (); iter++)
|
||||
{
|
||||
double tmp = (*iter - obtained_mean);
|
||||
sum += tmp*tmp;
|
||||
}
|
||||
double obtained_stddev = sqrt (sum / (NSAMPLES - 1));
|
||||
|
||||
if (not (obtained_mean/desired_mean > 0.90 and obtained_mean/desired_mean < 1.10))
|
||||
{
|
||||
result = false;
|
||||
Failure () << "Obtained lognormal mean value " << obtained_mean << ", expected " << desired_mean << std::endl;
|
||||
}
|
||||
|
||||
if (not (obtained_stddev/desired_stddev > 0.90 and obtained_stddev/desired_stddev < 1.10))
|
||||
{
|
||||
result = false;
|
||||
Failure () << "Obtained lognormal stddev value " << obtained_stddev <<
|
||||
", expected " << desired_stddev << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Test attribute serialization
|
||||
{
|
||||
{
|
||||
RandomVariableValue val;
|
||||
val.DeserializeFromString ("Uniform:0.1:0.2", MakeRandomVariableChecker ());
|
||||
RandomVariable rng = val.Get ();
|
||||
NS_TEST_ASSERT_EQUAL (val.SerializeToString (MakeRandomVariableChecker ()), "Uniform:0.1:0.2");
|
||||
}
|
||||
{
|
||||
RandomVariableValue val;
|
||||
val.DeserializeFromString ("Normal:0.1:0.2", MakeRandomVariableChecker ());
|
||||
RandomVariable rng = val.Get ();
|
||||
NS_TEST_ASSERT_EQUAL (val.SerializeToString (MakeRandomVariableChecker ()), "Normal:0.1:0.2");
|
||||
}
|
||||
{
|
||||
RandomVariableValue val;
|
||||
val.DeserializeFromString ("Normal:0.1:0.2:0.15", MakeRandomVariableChecker ());
|
||||
RandomVariable rng = val.Get ();
|
||||
NS_TEST_ASSERT_EQUAL (val.SerializeToString (MakeRandomVariableChecker ()), "Normal:0.1:0.2:0.15");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
private:
|
||||
virtual bool DoRun (void);
|
||||
};
|
||||
|
||||
BasicRandomNumberTestCase::BasicRandomNumberTestCase ()
|
||||
: TestCase ("Check basic random number operation")
|
||||
{
|
||||
}
|
||||
|
||||
static RandomVariableTest g_random_variable_tests;
|
||||
bool
|
||||
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");
|
||||
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
|
||||
class RandomNumberSerializationTestCase : public TestCase
|
||||
{
|
||||
public:
|
||||
RandomNumberSerializationTestCase ();
|
||||
virtual ~RandomNumberSerializationTestCase () {}
|
||||
|
||||
private:
|
||||
virtual bool DoRun (void);
|
||||
};
|
||||
|
||||
RandomNumberSerializationTestCase::RandomNumberSerializationTestCase ()
|
||||
: TestCase ("Check basic random number operation")
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
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");
|
||||
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
|
||||
class BasicRandomNumberTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
BasicRandomNumberTestSuite ();
|
||||
};
|
||||
|
||||
BasicRandomNumberTestSuite::BasicRandomNumberTestSuite ()
|
||||
: TestSuite ("basic-random-number", BVT)
|
||||
{
|
||||
AddTestCase (new BasicRandomNumberTestCase);
|
||||
AddTestCase (new RandomNumberSerializationTestCase);
|
||||
}
|
||||
|
||||
BasicRandomNumberTestSuite BasicRandomNumberTestSuite;
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
#endif /* RUN_SELF_TESTS */
|
||||
|
||||
125
src/core/traced-callback-test-suite.cc
Normal file
125
src/core/traced-callback-test-suite.cc
Normal file
@@ -0,0 +1,125 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 University of Washington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
#include "traced-callback.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
class BasicTracedCallbackTestCase : public TestCase
|
||||
{
|
||||
public:
|
||||
BasicTracedCallbackTestCase ();
|
||||
virtual ~BasicTracedCallbackTestCase () {}
|
||||
|
||||
private:
|
||||
virtual bool DoRun (void);
|
||||
|
||||
void CbOne (uint8_t a, double b);
|
||||
void CbTwo (uint8_t a, double b);
|
||||
|
||||
bool m_one;
|
||||
bool m_two;
|
||||
};
|
||||
|
||||
BasicTracedCallbackTestCase::BasicTracedCallbackTestCase ()
|
||||
: TestCase ("Check basic TracedCallback operation")
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
BasicTracedCallbackTestCase::CbOne (uint8_t a, double b)
|
||||
{
|
||||
m_one = true;
|
||||
}
|
||||
|
||||
void
|
||||
BasicTracedCallbackTestCase::CbTwo (uint8_t a, double b)
|
||||
{
|
||||
m_two = true;
|
||||
}
|
||||
|
||||
bool
|
||||
BasicTracedCallbackTestCase::DoRun (void)
|
||||
{
|
||||
//
|
||||
// Create a traced callback and connect it up to our target methods. All that
|
||||
// these methods do is to set corresponding member variables m_one and m_two.
|
||||
//
|
||||
TracedCallback<uint8_t, double> trace;
|
||||
|
||||
//
|
||||
// Connect both callbacks to their respective test methods. If we hit the
|
||||
// trace, both callbacks should be called and the two variables should be set
|
||||
// to true.
|
||||
//
|
||||
trace.ConnectWithoutContext (MakeCallback (&BasicTracedCallbackTestCase::CbOne, this));
|
||||
trace.ConnectWithoutContext (MakeCallback (&BasicTracedCallbackTestCase::CbTwo, this));
|
||||
m_one = false;
|
||||
m_two = false;
|
||||
trace (1, 2);
|
||||
NS_TEST_ASSERT_MSG_EQ (m_one, true, "Callback CbOne not called");
|
||||
NS_TEST_ASSERT_MSG_EQ (m_two, true, "Callback CbTwo not called");
|
||||
|
||||
//
|
||||
// If we now disconnect callback one then only callback two should be called.
|
||||
//
|
||||
trace.DisconnectWithoutContext (MakeCallback (&BasicTracedCallbackTestCase::CbOne, this));
|
||||
m_one = false;
|
||||
m_two = false;
|
||||
trace (1, 2);
|
||||
NS_TEST_ASSERT_MSG_EQ (m_one, false, "Callback CbOne unexpectedly called");
|
||||
NS_TEST_ASSERT_MSG_EQ (m_two, true, "Callback CbTwo not called");
|
||||
|
||||
//
|
||||
// If we now disconnect callback two then neither callback should be called.
|
||||
//
|
||||
trace.DisconnectWithoutContext (MakeCallback (&BasicTracedCallbackTestCase::CbTwo, this));
|
||||
m_one = false;
|
||||
m_two = false;
|
||||
trace (1, 2);
|
||||
NS_TEST_ASSERT_MSG_EQ (m_one, false, "Callback CbOne unexpectedly called");
|
||||
NS_TEST_ASSERT_MSG_EQ (m_two, false, "Callback CbTwo unexpectedly called");
|
||||
|
||||
//
|
||||
// If we connect them back up, then both callbacks should be called.
|
||||
//
|
||||
trace.ConnectWithoutContext (MakeCallback (&BasicTracedCallbackTestCase::CbOne, this));
|
||||
trace.ConnectWithoutContext (MakeCallback (&BasicTracedCallbackTestCase::CbTwo, this));
|
||||
m_one = false;
|
||||
m_two = false;
|
||||
trace (1, 2);
|
||||
NS_TEST_ASSERT_MSG_EQ (m_one, true, "Callback CbOne not called");
|
||||
NS_TEST_ASSERT_MSG_EQ (m_two, true, "Callback CbTwo not called");
|
||||
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
|
||||
class TracedCallbackTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
TracedCallbackTestSuite ();
|
||||
};
|
||||
|
||||
TracedCallbackTestSuite::TracedCallbackTestSuite ()
|
||||
: TestSuite ("traced-callback", UNIT)
|
||||
{
|
||||
AddTestCase (new BasicTracedCallbackTestCase);
|
||||
}
|
||||
|
||||
TracedCallbackTestSuite tracedCallbackTestSuite;
|
||||
@@ -1,99 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 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
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "traced-callback.h"
|
||||
|
||||
#ifdef RUN_SELF_TESTS
|
||||
|
||||
#include "test.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class TracedCallbackTest : public Test
|
||||
{
|
||||
public:
|
||||
TracedCallbackTest ();
|
||||
virtual ~TracedCallbackTest ();
|
||||
virtual bool RunTests (void);
|
||||
private:
|
||||
void CbOne (uint8_t a, double b);
|
||||
void CbTwo (uint8_t a, double b);
|
||||
|
||||
bool m_one;
|
||||
bool m_two;
|
||||
};
|
||||
|
||||
TracedCallbackTest::TracedCallbackTest ()
|
||||
: Test ("TracedCallback")
|
||||
{}
|
||||
TracedCallbackTest::~TracedCallbackTest ()
|
||||
{}
|
||||
void
|
||||
TracedCallbackTest::CbOne (uint8_t a, double b)
|
||||
{
|
||||
m_one = true;
|
||||
}
|
||||
void
|
||||
TracedCallbackTest::CbTwo (uint8_t a, double b)
|
||||
{
|
||||
m_two = true;
|
||||
}
|
||||
bool
|
||||
TracedCallbackTest::RunTests (void)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
TracedCallback<uint8_t,double> trace;
|
||||
trace.ConnectWithoutContext (MakeCallback (&TracedCallbackTest::CbOne, this));
|
||||
trace.ConnectWithoutContext (MakeCallback (&TracedCallbackTest::CbTwo, this));
|
||||
m_one = false;
|
||||
m_two = false;
|
||||
trace (1, 2);
|
||||
NS_TEST_ASSERT (m_one);
|
||||
NS_TEST_ASSERT (m_two);
|
||||
|
||||
trace.DisconnectWithoutContext (MakeCallback (&TracedCallbackTest::CbOne, this));
|
||||
m_one = false;
|
||||
m_two = false;
|
||||
trace (1, 2);
|
||||
NS_TEST_ASSERT (!m_one);
|
||||
NS_TEST_ASSERT (m_two);
|
||||
trace.DisconnectWithoutContext (MakeCallback (&TracedCallbackTest::CbTwo, this));
|
||||
m_one = false;
|
||||
m_two = false;
|
||||
trace (1, 2);
|
||||
NS_TEST_ASSERT (!m_one);
|
||||
NS_TEST_ASSERT (!m_two);
|
||||
|
||||
trace.ConnectWithoutContext (MakeCallback (&TracedCallbackTest::CbOne, this));
|
||||
trace.ConnectWithoutContext (MakeCallback (&TracedCallbackTest::CbTwo, this));
|
||||
m_one = false;
|
||||
m_two = false;
|
||||
trace (1, 2);
|
||||
NS_TEST_ASSERT (m_one);
|
||||
NS_TEST_ASSERT (m_two);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static TracedCallbackTest g_eventTraceTest;
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
#endif /* RUN_SELF_TESTS */
|
||||
@@ -70,7 +70,6 @@ def build(bld):
|
||||
'object-vector.cc',
|
||||
'object-factory.cc',
|
||||
'global-value.cc',
|
||||
'traced-callback.cc',
|
||||
'trace-source-accessor.cc',
|
||||
'config.cc',
|
||||
'callback.cc',
|
||||
@@ -80,6 +79,7 @@ def build(bld):
|
||||
'callback-test-suite.cc',
|
||||
'names-test-suite.cc',
|
||||
'type-traits-test-suite.cc',
|
||||
'traced-callback-test-suite.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
|
||||
@@ -391,7 +391,7 @@ WifiPhy::Get9mb5Mhz (void)
|
||||
{
|
||||
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-9mbs-5Mhz",
|
||||
false,
|
||||
10000000, 9000000, 12000000,
|
||||
5000000, 9000000, 12000000,
|
||||
WIFI_PHY_STANDARD_80211_5Mhz);
|
||||
return mode;
|
||||
}
|
||||
@@ -401,7 +401,7 @@ WifiPhy::Get12mb5Mhz (void)
|
||||
{
|
||||
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-12mbs-5Mhz",
|
||||
false,
|
||||
10000000, 12000000, 18000000,
|
||||
5000000, 12000000, 18000000,
|
||||
WIFI_PHY_STANDARD_80211_5Mhz);
|
||||
return mode;
|
||||
}
|
||||
@@ -411,7 +411,7 @@ WifiPhy::Get13_5mb5Mhz (void)
|
||||
{
|
||||
static WifiMode mode = WifiModeFactory::CreateBpsk ("wifi-13.5mbs-5Mhz",
|
||||
false,
|
||||
10000000, 13500000, 18000000,
|
||||
5000000, 13500000, 18000000,
|
||||
WIFI_PHY_STANDARD_80211_5Mhz);
|
||||
return mode;
|
||||
}
|
||||
|
||||
13
test.py
13
test.py
@@ -41,20 +41,13 @@ import shutil
|
||||
interesting_config_items = [
|
||||
"NS3_BUILDDIR",
|
||||
"NS3_MODULE_PATH",
|
||||
"ENABLE_EMU",
|
||||
"ENABLE_GSL",
|
||||
"ENABLE_GTK_CONFIG_STORE",
|
||||
"ENABLE_LIBXML2",
|
||||
"ENABLE_NSC",
|
||||
"ENABLE_PYTHON_BINDINGS",
|
||||
"ENABLE_PYTHON_SCANNING",
|
||||
"ENABLE_REAL_TIME",
|
||||
"ENABLE_STATIC_NS3",
|
||||
"ENABLE_SUDO",
|
||||
"ENABLE_TAP",
|
||||
"ENABLE_THREADING",
|
||||
]
|
||||
|
||||
ENABLE_NSC = False
|
||||
ENABLE_REAL_TIME = False
|
||||
|
||||
#
|
||||
# A list of examples to run as smoke tests just to ensure that they remain
|
||||
# buildable and runnable over time. Also a condition under which to run
|
||||
|
||||
@@ -230,6 +230,7 @@ main (int argc, char *argv[])
|
||||
// but we'll do it if asked.
|
||||
//
|
||||
bool result = false;
|
||||
bool suiteRan = false;
|
||||
|
||||
for (uint32_t i = 0; i < TestRunner::GetNTestSuites (); ++i)
|
||||
{
|
||||
@@ -240,9 +241,19 @@ main (int argc, char *argv[])
|
||||
testSuite->SetStream (pofs);
|
||||
testSuite->SetVerbose (doVerbose);
|
||||
result |= testSuite->Run ();
|
||||
suiteRan = true;
|
||||
}
|
||||
}
|
||||
|
||||
ofs.close();
|
||||
|
||||
//
|
||||
// If we couldn't figure out how to run at least one test, then return an error
|
||||
//
|
||||
if (suiteRan == false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user