From 39b60cdc2fa4ea584a03f44b2937e05e1ee4b9df Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Tue, 5 Oct 2010 01:28:49 -0700 Subject: [PATCH] add mobility model test suite with more waypoint mobility model tests --- src/test/mobility-test-suite.cc | 376 ++++++++++++++++++++++++++++++++ src/test/wscript | 1 + 2 files changed, 377 insertions(+) create mode 100644 src/test/mobility-test-suite.cc diff --git a/src/test/mobility-test-suite.cc b/src/test/mobility-test-suite.cc new file mode 100644 index 000000000..ec1d86214 --- /dev/null +++ b/src/test/mobility-test-suite.cc @@ -0,0 +1,376 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright 2010 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 + * + */ + +/* + * This test suite is intended to test mobility use cases in general, + * as typically used by user programs (i.e. with the helper layer + * involved). + */ + +#include "ns3/test.h" +#include "ns3/boolean.h" +#include "ns3/simulator.h" +#include "ns3/scheduler.h" +#include "ns3/vector.h" +#include "ns3/mobility-model.h" +#include "ns3/waypoint-mobility-model.h" +#include "ns3/mobility-helper.h" + +using namespace ns3; + +// Test whether course change notifications occur regardless of calls +// to Update() position (which are triggered by calls to GetPosition()) +class WaypointLazyNotifyFalse : public TestCase +{ +public: + WaypointLazyNotifyFalse (); + virtual ~WaypointLazyNotifyFalse (); + +private: + void TestXPosition (double expectedXPos); + void CourseChangeCallback (std::string path, Ptr model); + virtual bool DoRun (void); + Ptr m_node; + Ptr m_mob; + int m_courseChanges; +}; + +WaypointLazyNotifyFalse::WaypointLazyNotifyFalse () + : TestCase ("Test behavior when LazyNotify is false"), + m_courseChanges (0) +{ +} + +WaypointLazyNotifyFalse::~WaypointLazyNotifyFalse () +{ +} + +void +WaypointLazyNotifyFalse::TestXPosition (double expectedXPos) +{ + Vector pos = m_mob->GetPosition (); + NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (pos.x, expectedXPos, 0.001, "Position not equal", __FILE__, __LINE__); +} + +void +WaypointLazyNotifyFalse::CourseChangeCallback (std::string path, Ptr model) +{ + // All waypoints (at 10 second intervals) should trigger a course change + NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (m_courseChanges * 10.0, Simulator::Now ().GetSeconds (), 0.001, "Course change not notified correctly", __FILE__, __LINE__); + m_courseChanges++; +} + +bool +WaypointLazyNotifyFalse::DoRun (void) +{ + m_node = CreateObject (); + m_mob = CreateObject (); + // LazyNotify should by default be false + m_node->AggregateObject (m_mob); + Waypoint wpt (Seconds (0.0), Vector (0.0, 0.0, 0.0)); + m_mob->AddWaypoint (wpt); + Waypoint wpt2 (Seconds (10.0), Vector (10.0, 10.0, 10.0)); + m_mob->AddWaypoint (wpt2); + Waypoint wpt3 (Seconds (20.0), Vector (20.0, 20.0, 20.0)); + m_mob->AddWaypoint (wpt3); + + Simulator::Schedule (Seconds (5.0), &WaypointLazyNotifyFalse::TestXPosition, this, 5); + Simulator::Run (); + Simulator::Destroy (); + return GetErrorStatus (); +} + +class WaypointLazyNotifyTrue : public TestCase +{ +public: + WaypointLazyNotifyTrue (); + virtual ~WaypointLazyNotifyTrue (); + +private: + void TestXPosition (double expectedXPos); + void CourseChangeCallback (std::string path, Ptr model); + virtual bool DoRun (void); + Ptr m_node; + Ptr m_mob; +}; + +WaypointLazyNotifyTrue::WaypointLazyNotifyTrue () + : TestCase ("Test behavior when LazyNotify is true") +{ +} + +WaypointLazyNotifyTrue::~WaypointLazyNotifyTrue () +{ +} + +void +WaypointLazyNotifyTrue::TestXPosition (double expectedXPos) +{ + Vector pos = m_mob->GetPosition (); + NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (pos.x, expectedXPos, 0.001, "Position not equal", __FILE__, __LINE__); +} + +void +WaypointLazyNotifyTrue::CourseChangeCallback (std::string path, Ptr model) +{ + // This should trigger at time 15 only, since that is the first time that + // position is updated due to LazyNotify + NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (15, Simulator::Now ().GetSeconds (), 0.001, "Course change not notified correctly", __FILE__, __LINE__); +} + +bool +WaypointLazyNotifyTrue::DoRun (void) +{ + m_node = CreateObject (); + m_mob = CreateObject (); + m_mob->SetAttributeFailSafe ("LazyNotify", BooleanValue (true)); + m_node->AggregateObject (m_mob); + Waypoint wpt (Seconds (0.0), Vector (0.0, 0.0, 0.0)); + m_mob->AddWaypoint (wpt); + Waypoint wpt2 (Seconds (10.0), Vector (10.0, 10.0, 10.0)); + m_mob->AddWaypoint (wpt2); + Waypoint wpt3 (Seconds (20.0), Vector (20.0, 20.0, 20.0)); + m_mob->AddWaypoint (wpt3); + + Simulator::Schedule (Seconds (15.0), &WaypointLazyNotifyTrue::TestXPosition, this, 15); + Simulator::Run (); + Simulator::Destroy (); + return GetErrorStatus (); +} + +class WaypointInitialPositionIsWaypoint : public TestCase +{ +public: + WaypointInitialPositionIsWaypoint (); + virtual ~WaypointInitialPositionIsWaypoint (); + +private: + void TestXPosition (Ptr model, double expectedXPos); + void TestNumWaypoints (Ptr model, uint32_t num); + virtual bool DoRun (void); + Ptr m_mob1; + Ptr m_mob2; + Ptr m_mob3; + Ptr m_mob4; + Ptr m_mob5; +}; + +WaypointInitialPositionIsWaypoint::WaypointInitialPositionIsWaypoint () + : TestCase ("Test behavior of Waypoint InitialPositionIsWaypoint") +{ +} + +WaypointInitialPositionIsWaypoint::~WaypointInitialPositionIsWaypoint () +{ +} + +void +WaypointInitialPositionIsWaypoint::TestXPosition (Ptr model, double expectedXPos) +{ + Vector pos = model->GetPosition (); + NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (pos.x, expectedXPos, 0.001, "Position not equal", __FILE__, __LINE__); +} + +void +WaypointInitialPositionIsWaypoint::TestNumWaypoints (Ptr model, uint32_t num) +{ + NS_TEST_EXPECT_MSG_EQ (model->WaypointsLeft (), num, "Unexpected number of waypoints left"); +} + +bool +WaypointInitialPositionIsWaypoint::DoRun (void) +{ + // Case 1: InitialPositionIsWaypoint == false, and we call SetPosition + // without any waypoints added. There should be no waypoints after + // time 0 + m_mob1 = CreateObject (); + m_mob1->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (false)); + m_mob1->SetPosition (Vector (10.0, 10.0, 10.0)); + // At time 1s, there should be no waypoints + Simulator::Schedule (Seconds (1.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob1, 0); + // At time 15s, the model should still be at x position 10.0 + Simulator::Schedule (Seconds (15.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob1, 10.0); + + // Case 2: InitialPositionIsWaypoint == false, and we call SetPosition + // after adding a waypoint. + m_mob2 = CreateObject (); + m_mob2->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (false)); + Waypoint wpt21 (Seconds (5.0), Vector (15.0, 15.0, 15.0)); + m_mob2->AddWaypoint (wpt21); + Waypoint wpt22 (Seconds (10.0), Vector (20.0, 20.0, 20.0)); + m_mob2->AddWaypoint (wpt22); + m_mob2->SetPosition (Vector (10.0, 10.0, 10.0)); + // At time 3, no waypoints have been hit, so position should be 10 and + // numWaypoints should be 2, or 1 excluding the next one + Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob2, 10.0); + Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob2, 1); + // At time 8, check that X position is 18 (i.e. position is interpolating + // between 15 and 20) and there is one waypoint left, but we exclude + // the next one so we test for zero waypoints + Simulator::Schedule (Seconds (8.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob2, 18.0); + Simulator::Schedule (Seconds (8.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob2, 0); + + // Case 3: InitialPositionIsWaypoint == true, and we call SetPosition + // without any waypoints added. + m_mob3 = CreateObject (); + m_mob3->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (true)); + m_mob3->SetPosition (Vector (10.0, 10.0, 10.0)); + // At time 1s, there should be zero waypoints not counting the next one + Simulator::Schedule (Seconds (1.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob3, 0); + // At time 15s, the model should still be at x position 10.0 + Simulator::Schedule (Seconds (15.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob3, 10.0); + + // Case 4: InitialPositionIsWaypoint == true, and we call SetPosition + // after adding a waypoint. + m_mob4 = CreateObject (); + m_mob4->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (true)); + Waypoint wpt41 (Seconds (5.0), Vector (15.0, 15.0, 15.0)); + m_mob4->AddWaypoint (wpt41); + Waypoint wpt42 (Seconds (10.0), Vector (20.0, 20.0, 20.0)); + m_mob4->AddWaypoint (wpt42); + // Here, SetPosition() is called after waypoints have been added. In + // this case, the initial position is set until the time of the first + // waypoint, at which time it jumps to the waypoint and begins moving + m_mob4->SetPosition (Vector (10.0, 10.0, 10.0)); + // At time 3, position should be fixed still at 10 + Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob4, 10.0); + Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob4, 1); + // At time 6, we should be moving between 15 and 20 + Simulator::Schedule (Seconds (6.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob4, 16.0); + // At time 15, we should be fixed at 20 + Simulator::Schedule (Seconds (15.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob4, 20.0); + + // case 5: If waypoint and SetPosition both called at time 0, + // SetPosition takes precedence + m_mob5 = CreateObject (); + m_mob5->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (true)); + // Note: The below statement would result in a crash, because it would + // violate the rule that waypoints must increase in start time + // m_mob5->SetPosition (Vector (10.0, 10.0, 10.0)); + Waypoint wpt51 (Seconds (0.0), Vector (200.0, 200.0, 200.0)); + m_mob5->AddWaypoint (wpt51); + Waypoint wpt52 (Seconds (5.0), Vector (15.0, 15.0, 15.0)); + m_mob5->AddWaypoint (wpt52); + Waypoint wpt53 (Seconds (10.0), Vector (20.0, 20.0, 20.0)); + m_mob5->AddWaypoint (wpt53); + // Here, since waypoints already exist, the below SetPosition will cancel + // out wpt51 above, and model will stay at initial position until time 5 + m_mob5->SetPosition (Vector (10.0, 10.0, 10.0)); + Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob5, 10.0); + + Simulator::Run (); + Simulator::Destroy (); + return GetErrorStatus (); +} + +class WaypointMobilityModelViaHelper : public TestCase +{ +public: + WaypointMobilityModelViaHelper (); + virtual ~WaypointMobilityModelViaHelper (); + +private: + void TestXPosition (Ptr mob, double expectedXPos); + virtual bool DoRun (void); +}; + +WaypointMobilityModelViaHelper::WaypointMobilityModelViaHelper () + : TestCase ("Test behavior using MobilityHelper and PositionAllocator") +{ +} + +WaypointMobilityModelViaHelper::~WaypointMobilityModelViaHelper () +{ +} + +void +WaypointMobilityModelViaHelper::TestXPosition (Ptr mob, double expectedXPos) +{ + Vector pos = mob->GetPosition (); + NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (pos.x, expectedXPos, 0.001, "Position not equal", __FILE__, __LINE__); +} + +// WaypointMobilityModel tests using the helper +bool +WaypointMobilityModelViaHelper::DoRun (void) +{ + NodeContainer c; + c.Create (1); + MobilityHelper mobility; + Ptr positionAlloc = CreateObject (); + positionAlloc->Add (Vector (0.0, 0.0, 0.0)); + mobility.SetPositionAllocator (positionAlloc); + // When InitialPositionIsWaypoint is false (default), the position + // set by the position allocator is ignored. The first waypoint set will + // set the initial position (with velocity 0 until first waypoint time) + mobility.SetMobilityModel ("ns3::WaypointMobilityModel", + "InitialPositionIsWaypoint", BooleanValue (false)); + mobility.Install (c); + + // Get back a pointer to this + Ptr mob = c.Get (0)->GetObject (); + // Waypoint added at time 0 will override initial position + Waypoint wpt (Seconds (5.0), Vector (20.0, 20.0, 20.0)); + Waypoint wpt2 (Seconds (10.0), Vector (10.0, 10.0, 10.0)); + mob->AddWaypoint (wpt); + mob->AddWaypoint (wpt2); + // At time 3 (before first waypoint, position is 20 + Simulator::Schedule (Seconds (3), &WaypointMobilityModelViaHelper::TestXPosition, this, mob, 20); + // At time 7.5 (midway between points 1 and 2, position is 15 + Simulator::Schedule (Seconds (7.5), &WaypointMobilityModelViaHelper::TestXPosition, this, mob, 15); + + // When InitialPositionIsWaypoint is true, the position allocator creates + // the first waypoint, and movement occurs between this origin and the + // initial waypoint below at 5 seconds + NodeContainer c2; + c2.Create (1); + MobilityHelper mobility2; + Ptr positionAlloc2 = CreateObject (); + positionAlloc2->Add (Vector (0.0, 0.0, 0.0)); + mobility2.SetPositionAllocator (positionAlloc2); + mobility2.SetMobilityModel ("ns3::WaypointMobilityModel", + "InitialPositionIsWaypoint", BooleanValue (true)); + mobility2.Install (c2); + Ptr mob2 = c2.Get (0)->GetObject (); + Waypoint wpt3 (Seconds (5.0), Vector (20.0, 20.0, 20.0)); + mob2->AddWaypoint (wpt3); + // Move to position 12 at 3 seconds + Simulator::Schedule (Seconds (3), &WaypointMobilityModelViaHelper::TestXPosition, this, mob2, 12); + + Simulator::Run (); + Simulator::Destroy (); + return GetErrorStatus (); +} + +class MobilityTestSuite : public TestSuite +{ +public: + MobilityTestSuite (); +}; + +MobilityTestSuite::MobilityTestSuite () + : TestSuite ("mobility", BVT) +{ + AddTestCase (new WaypointLazyNotifyFalse); + AddTestCase (new WaypointLazyNotifyTrue); + AddTestCase (new WaypointInitialPositionIsWaypoint); + AddTestCase (new WaypointMobilityModelViaHelper); +} + +static MobilityTestSuite mobilityTestSuite; diff --git a/src/test/wscript b/src/test/wscript index b890dcdc1..6c72c5161 100644 --- a/src/test/wscript +++ b/src/test/wscript @@ -8,6 +8,7 @@ def build(bld): test.source = [ 'sample-test-suite.cc', 'error-model-test-suite.cc', + 'mobility-test-suite.cc', ] headers = bld.new_task_gen('ns3header')