From b3933a2fe497fdfd01e26720c8d208dabbd530ef Mon Sep 17 00:00:00 2001 From: Mitch Watrous Date: Thu, 7 Apr 2011 10:07:46 -0700 Subject: [PATCH] Move tests from mobility module to its test library --- src/mobility/helper/ns2-mobility-helper.cc | 368 ---------------- .../test/ns2-mobility-helper-test-suite.cc | 417 ++++++++++++++++++ src/mobility/wscript | 1 + 3 files changed, 418 insertions(+), 368 deletions(-) create mode 100644 src/mobility/test/ns2-mobility-helper-test-suite.cc diff --git a/src/mobility/helper/ns2-mobility-helper.cc b/src/mobility/helper/ns2-mobility-helper.cc index 4a0e73438..9153bbaf9 100644 --- a/src/mobility/helper/ns2-mobility-helper.cc +++ b/src/mobility/helper/ns2-mobility-helper.cc @@ -41,16 +41,11 @@ #include #include #include -#include #include "ns3/log.h" #include "ns3/simulator.h" #include "ns3/node-list.h" #include "ns3/node.h" #include "ns3/constant-velocity-mobility-model.h" -#include "ns3/test.h" -#include "ns3/node-container.h" -#include "ns3/names.h" -#include "ns3/config.h" #include "ns2-mobility-helper.h" NS_LOG_COMPONENT_DEFINE ("Ns2MobilityHelper"); @@ -663,367 +658,4 @@ Ns2MobilityHelper::Install (void) const Install (NodeList::Begin (), NodeList::End ()); } -// ----------------------------------------------------------------------------- -// Testing -// ----------------------------------------------------------------------------- -bool operator== (Vector const & a, Vector const & b) -{ - return (a.x == b.x && a.y == b.y && a.z == b.z); -} -/** - * Every test case is supposed to: - * 1. Generate short mobility trace file - * 2. Read it back using Ns2MobilityHelper - * 3. Check initial node positions and speeds. - * 4. Run simulation listening for all CourseChange events and compare actual mobility with the reference - */ -class Ns2MobilityHelperTest : public TestCase -{ -public: - /// Single record in mobility reference - struct ReferencePoint - { - std::string node; ///< node ID as string, e.g. "1" - Time time; ///< timestamp - Vector pos; ///< reference position - Vector vel; ///< reference velocity - - ReferencePoint (std::string const & id, Time t, Vector const & p, Vector const & v) - : node (id), - time (t), - pos (p), - vel (v) - { - } - /// Sort by timestamp - bool operator< (ReferencePoint const & o) const - { - return (time < o.time); - } - }; - /** - * Create new test case. To make it useful SetTrace () and AddReferencePoint () must be called - * - * \param name Short description - * \param nodes Number of nodes used in the test trace, 1 by default - */ - Ns2MobilityHelperTest (std::string const & name, Time timeLimit, uint32_t nodes = 1) - : TestCase (name), - m_timeLimit (timeLimit), - m_nodeCount (nodes), - m_nextRefPoint (0) - { - } - /// Empty - virtual ~Ns2MobilityHelperTest () - { - } - /// Set NS-2 trace to read as single large string (don't forget to add \n and quote ") - void SetTrace (std::string const & trace) - { - m_trace = trace; - } - /// Add next reference point - void AddReferencePoint (ReferencePoint const & r) - { - m_reference.push_back (r); - } - /// Sugar - void AddReferencePoint (const char * id, double sec, Vector const & p, Vector const & v) - { - AddReferencePoint (ReferencePoint (id, Seconds (sec), p, v)); - } - -private: - /// Test time limit - Time m_timeLimit; - /// Number of nodes used in the test - uint32_t m_nodeCount; - /// Trace as string - std::string m_trace; - /// Reference mobility - std::vector m_reference; - /// Next reference point to be checked - size_t m_nextRefPoint; - /// TMP trace file name - std::string m_traceFile; - -private: - /// Dump NS-2 trace to tmp file - bool WriteTrace () - { - m_traceFile = GetTempDir () + "Ns2MobilityHelperTest.tcl"; - std::ofstream of (m_traceFile.c_str ()); - NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL (of.is_open (), true, "Need to write tmp. file"); - of << m_trace; - of.close (); - return false; // no errors - } - /// Create and name nodes - void CreateNodes () - { - NodeContainer nodes; - nodes.Create (m_nodeCount); - for (uint32_t i = 0; i < m_nodeCount; ++i) - { - std::ostringstream os; - os << i; - Names::Add (os.str (), nodes.Get (i)); - } - } - /// Check that all initial positions are correct - bool CheckInitialPositions () - { - std::stable_sort (m_reference.begin (), m_reference.end ()); - while (m_nextRefPoint < m_reference.size () && m_reference[m_nextRefPoint].time == Seconds (0)) - { - ReferencePoint const & rp = m_reference[m_nextRefPoint]; - Ptr node = Names::Find (rp.node); - NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL (node, 0, "Can't find node with id " << rp.node); - Ptr mob = node->GetObject (); - NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL (mob, 0, "Can't find mobility for node " << rp.node); - - NS_TEST_EXPECT_MSG_EQ (rp.pos, mob->GetPosition (), "Initial position mismatch for node " << rp.node); - NS_TEST_EXPECT_MSG_EQ (rp.vel, mob->GetVelocity (), "Initial velocity mismatch for node " << rp.node); - - m_nextRefPoint++; - } - return GetErrorStatus (); - } - /// Listen for course change events - void CourseChange (std::string context, Ptr mobility) - { - Time time = Simulator::Now (); - Ptr node = mobility->GetObject (); - NS_ASSERT (node); - std::string id = Names::FindName (node); - NS_ASSERT (!id.empty ()); - Vector pos = mobility->GetPosition (); - Vector vel = mobility->GetVelocity (); - - NS_TEST_EXPECT_MSG_LT (m_nextRefPoint, m_reference.size (), "Not enough reference points"); - if (m_nextRefPoint >= m_reference.size ()) - { - return; - } - - ReferencePoint const & ref = m_reference [m_nextRefPoint++]; - NS_TEST_EXPECT_MSG_EQ (time, ref.time, "Time mismatch"); - NS_TEST_EXPECT_MSG_EQ (id, ref.node, "Node ID mismatch at time " << time.GetSeconds () << " s"); - NS_TEST_EXPECT_MSG_EQ (pos, ref.pos, "Position mismatch at time " << time.GetSeconds () << " s for node " << id); - NS_TEST_EXPECT_MSG_EQ (vel, ref.vel, "Velocity mismatch at time " << time.GetSeconds () << " s for node " << id); - } - /// Go - void DoRun () - { - NS_TEST_ASSERT_MSG_EQ (m_trace.empty (), false, "Need trace"); - NS_TEST_ASSERT_MSG_EQ (m_reference.empty (), false, "Need reference"); - - if (WriteTrace ()) - { - return; - } - CreateNodes (); - Ns2MobilityHelper mobility (m_traceFile); - mobility.Install (); - if (CheckInitialPositions ()) - { - return; - } - Config::Connect ("/NodeList/*/$ns3::MobilityModel/CourseChange", - MakeCallback (&Ns2MobilityHelperTest::CourseChange, this)); - Simulator::Stop (m_timeLimit); - Simulator::Run (); - Names::Clear (); - std::remove (m_traceFile.c_str ()); - Simulator::Destroy (); - } -}; - -/// The test suite -class Ns2MobilityHelperTestSuite : public TestSuite -{ -public: - Ns2MobilityHelperTestSuite () : TestSuite ("mobility-ns2-trace-helper", UNIT) - { - // to be used as temporary variable for test cases. - // Note that test suite takes care of deleting all test cases. - Ns2MobilityHelperTest * t (0); - - // Initial position - t = new Ns2MobilityHelperTest ("initial position", Seconds (1)); - t->SetTrace ("$node_(0) set X_ 1.0\n" - "$node_(0) set Y_ 2.0\n" - "$node_(0) set Z_ 3.0\n" - ); - t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0)); - AddTestCase (t); - - // Check parsing comments, empty lines and no EOF at the end of file - t = new Ns2MobilityHelperTest ("comments", Seconds (1)); - t->SetTrace ("# comment\n" - "\n\n" // empty lines - "$node_(0) set X_ 1.0 # comment \n" - "$node_(0) set Y_ 2.0 ### \n" - "$node_(0) set Z_ 3.0 # $node_(0) set Z_ 3.0\n" - "#$node_(0) set Z_ 100 #" - ); - t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0)); - AddTestCase (t); - - // Simple setdest. Arguments are interpreted as x, y, speed by default - t = new Ns2MobilityHelperTest ("simple setdest", Seconds (10)); - t->SetTrace ("$ns_ at 1.0 \"$node_(0) setdest 25 0 5\""); - // id t position velocity - t->AddReferencePoint ("0", 0, Vector (0, 0, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 1, Vector (0, 0, 0), Vector (5, 0, 0)); - t->AddReferencePoint ("0", 6, Vector (25, 0, 0), Vector (0, 0, 0)); - AddTestCase (t); - - // Several set and setdest. Arguments are interpreted as x, y, speed by default - t = new Ns2MobilityHelperTest ("square setdest", Seconds (6)); - t->SetTrace ("$node_(0) set X_ 0.0\n" - "$node_(0) set Y_ 0.0\n" - "$ns_ at 1.0 \"$node_(0) setdest 5 0 5\"\n" - "$ns_ at 2.0 \"$node_(0) setdest 5 5 5\"\n" - "$ns_ at 3.0 \"$node_(0) setdest 0 5 5\"\n" - "$ns_ at 4.0 \"$node_(0) setdest 0 0 5\"\n" - ); - // id t position velocity - t->AddReferencePoint ("0", 0, Vector (0, 0, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 1, Vector (0, 0, 0), Vector (5, 0, 0)); - t->AddReferencePoint ("0", 2, Vector (5, 0, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 2, Vector (5, 0, 0), Vector (0, 5, 0)); - t->AddReferencePoint ("0", 3, Vector (5, 5, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 3, Vector (5, 5, 0), Vector (-5, 0, 0)); - t->AddReferencePoint ("0", 4, Vector (0, 5, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 4, Vector (0, 5, 0), Vector (0, -5, 0)); - t->AddReferencePoint ("0", 5, Vector (0, 0, 0), Vector (0, 0, 0)); - AddTestCase (t); - - // Scheduled set position - t = new Ns2MobilityHelperTest ("scheduled set position", Seconds (2)); - t->SetTrace ("$ns_ at 1.0 \"$node_(0) set X_ 10\"\n" - "$ns_ at 1.0 \"$node_(0) set Z_ 10\"\n" - "$ns_ at 1.0 \"$node_(0) set Y_ 10\""); - // id t position velocity - t->AddReferencePoint ("0", 1, Vector (10, 0, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 1, Vector (10, 0, 10), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 1, Vector (10, 10, 10), Vector (0, 0, 0)); - AddTestCase (t); - - // Malformed lines - t = new Ns2MobilityHelperTest ("malformed lines", Seconds (2)); - t->SetTrace ("$node() set X_ 1 # node id is not present\n" - "$node # incoplete line\"\n" - "$node this line is not correct\n" - "$node_(0) set X_ 1 # line OK \n" - "$node_(0) set Y_ 2 # line OK \n" - "$node_(0) set Z_ 3 # line OK \n" - "$ns_ at \"$node_(0) setdest 4 4 4\" # time not present\n" - "$ns_ at 1 \"$node_(0) setdest 2 2 1 \" # line OK \n"); - // id t position velocity - t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 1, Vector (1, 2, 3), Vector (1, 0, 0)); - t->AddReferencePoint ("0", 2, Vector (2, 2, 3), Vector (0, 0, 0)); - AddTestCase (t); - - // Non possible values - t = new Ns2MobilityHelperTest ("non possible values", Seconds (2)); - t->SetTrace ("$node_(0) set X_ 1 # line OK \n" - "$node_(0) set Y_ 2 # line OK \n" - "$node_(0) set Z_ 3 # line OK \n" - "$node_(-22) set Y_ 3 # node id not correct\n" - "$node_(3.3) set Y_ 1111 # node id not correct\n" - "$ns_ at sss \"$node_(0) setdest 5 5 5\" # time is not a number\n" - "$ns_ at 1 \"$node_(0) setdest 2 2 1\" # line OK \n" - "$ns_ at 1 \"$node_(0) setdest 2 2 -1\" # negative speed is not correct\n" - "$ns_ at 1 \"$node_(0) setdest 2 2 sdfs\" # speed is not a number\n" - "$ns_ at 1 \"$node_(0) setdest 2 2 s232dfs\" # speed is not a number\n" - "$ns_ at 1 \"$node_(0) setdest 233 2.. s232dfs\" # more than one non numbers\n" - "$ns_ at -12 \"$node_(0) setdest 11 22 33\" # time should not be negative\n"); - // id t position velocity - t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 1, Vector (1, 2, 3), Vector (1, 0, 0)); - t->AddReferencePoint ("0", 2, Vector (2, 2, 3), Vector (0, 0, 0)); - AddTestCase (t); - - // More than one node - t = new Ns2MobilityHelperTest ("few nodes, combinations of set and setdest", Seconds (10), 3); - t->SetTrace ("$node_(0) set X_ 1.0\n" - "$node_(0) set Y_ 2.0\n" - "$node_(0) set Z_ 3.0\n" - "$ns_ at 1.0 \"$node_(1) setdest 25 0 5\"\n" - "$node_(2) set X_ 0.0\n" - "$node_(2) set Y_ 0.0\n" - "$ns_ at 1.0 \"$node_(2) setdest 5 0 5\"\n" - "$ns_ at 2.0 \"$node_(2) setdest 5 5 5\"\n" - "$ns_ at 3.0 \"$node_(2) setdest 0 5 5\"\n" - "$ns_ at 4.0 \"$node_(2) setdest 0 0 5\"\n"); - // id t position velocity - t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0)); - t->AddReferencePoint ("1", 0, Vector (0, 0, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("1", 1, Vector (0, 0, 0), Vector (5, 0, 0)); - t->AddReferencePoint ("1", 6, Vector (25, 0, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("2", 0, Vector (0, 0, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("2", 1, Vector (0, 0, 0), Vector (5, 0, 0)); - t->AddReferencePoint ("2", 2, Vector (5, 0, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("2", 2, Vector (5, 0, 0), Vector (0, 5, 0)); - t->AddReferencePoint ("2", 3, Vector (5, 5, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("2", 3, Vector (5, 5, 0), Vector (-5, 0, 0)); - t->AddReferencePoint ("2", 4, Vector (0, 5, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("2", 4, Vector (0, 5, 0), Vector (0, -5, 0)); - t->AddReferencePoint ("2", 5, Vector (0, 0, 0), Vector (0, 0, 0)); - AddTestCase (t); - - // Test for Speed == 0, that acts as stop the node. - t = new Ns2MobilityHelperTest ("setdest with speed cero", Seconds (10)); - t->SetTrace ("$ns_ at 1.0 \"$node_(0) setdest 25 0 5\"\n" - "$ns_ at 7.0 \"$node_(0) setdest 11 22 0\"\n"); - // id t position velocity - t->AddReferencePoint ("0", 0, Vector (0, 0, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 1, Vector (0, 0, 0), Vector (5, 0, 0)); - t->AddReferencePoint ("0", 6, Vector (25, 0, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 7, Vector (25, 0, 0), Vector (0, 0, 0)); - AddTestCase (t); - - - // Test negative positions - t = new Ns2MobilityHelperTest ("test negative positions", Seconds (10)); - t->SetTrace ("$node_(0) set X_ -1.0\n" - "$node_(0) set Y_ 0\n" - "$ns_ at 1.0 \"$node_(0) setdest 0 0 1\"\n" - "$ns_ at 2.0 \"$node_(0) setdest 0 -1 1\"\n"); - // id t position velocity - t->AddReferencePoint ("0", 0, Vector (-1, 0, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 1, Vector (-1, 0, 0), Vector (1, 0, 0)); - t->AddReferencePoint ("0", 2, Vector (0, 0, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 2, Vector (0, 0, 0), Vector (0, -1, 0)); - t->AddReferencePoint ("0", 3, Vector (0, -1, 0), Vector (0, 0, 0)); - AddTestCase (t); - - // Sqare setdest with values in the form 1.0e+2 - t = new Ns2MobilityHelperTest ("Foalt numbers in 1.0e+2 format", Seconds (6)); - t->SetTrace ("$node_(0) set X_ 0.0\n" - "$node_(0) set Y_ 0.0\n" - "$ns_ at 1.0 \"$node_(0) setdest 1.0e+2 0 1.0e+2\"\n" - "$ns_ at 2.0 \"$node_(0) setdest 1.0e+2 1.0e+2 1.0e+2\"\n" - "$ns_ at 3.0 \"$node_(0) setdest 0 1.0e+2 1.0e+2\"\n" - "$ns_ at 4.0 \"$node_(0) setdest 0 0 1.0e+2\"\n"); - // id t position velocity - t->AddReferencePoint ("0", 0, Vector (0, 0, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 1, Vector (0, 0, 0), Vector (100, 0, 0)); - t->AddReferencePoint ("0", 2, Vector (100, 0, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 2, Vector (100, 0, 0), Vector (0, 100, 0)); - t->AddReferencePoint ("0", 3, Vector (100, 100, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 3, Vector (100, 100, 0), Vector (-100, 0, 0)); - t->AddReferencePoint ("0", 4, Vector (0, 100, 0), Vector (0, 0, 0)); - t->AddReferencePoint ("0", 4, Vector (0, 100, 0), Vector (0, -100, 0)); - t->AddReferencePoint ("0", 5, Vector (0, 0, 0), Vector (0, 0, 0)); - AddTestCase (t); - - } -} g_ns2TransmobilityHelperTestSuite; - - } // namespace ns3 diff --git a/src/mobility/test/ns2-mobility-helper-test-suite.cc b/src/mobility/test/ns2-mobility-helper-test-suite.cc new file mode 100644 index 000000000..113303462 --- /dev/null +++ b/src/mobility/test/ns2-mobility-helper-test-suite.cc @@ -0,0 +1,417 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INRIA + * 2009,2010 Contributors + * + * 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 + * Contributors: Thomas Waldecker + * Martín Giachino + * + * Brief description: Implementation of a ns2 movement trace file reader. + * + * This implementation is based on the ns2 movement documentation of ns2 + * as described in http://www.isi.edu/nsnam/ns/doc/node174.html + * + * Valid trace files use the following ns2 statements: + * + * $node set X_ x1 + * $node set Y_ y1 + * $node set Z_ z1 + * $ns at $time $node setdest x2 y2 speed + * $ns at $time $node set X_ x1 + * $ns at $time $node set Y_ Y1 + * $ns at $time $node set Z_ Z1 + * + */ + +#include +#include "ns3/log.h" +#include "ns3/simulator.h" +#include "ns3/node-list.h" +#include "ns3/node.h" +#include "ns3/constant-velocity-mobility-model.h" +#include "ns3/test.h" +#include "ns3/node-container.h" +#include "ns3/names.h" +#include "ns3/config.h" +#include "ns3/ns2-mobility-helper.h" + +namespace ns3 { + +// ----------------------------------------------------------------------------- +// Testing +// ----------------------------------------------------------------------------- +bool operator== (Vector const & a, Vector const & b) +{ + return (a.x == b.x && a.y == b.y && a.z == b.z); +} +/** + * Every test case is supposed to: + * 1. Generate short mobility trace file + * 2. Read it back using Ns2MobilityHelper + * 3. Check initial node positions and speeds. + * 4. Run simulation listening for all CourseChange events and compare actual mobility with the reference + */ +class Ns2MobilityHelperTest : public TestCase +{ +public: + /// Single record in mobility reference + struct ReferencePoint + { + std::string node; ///< node ID as string, e.g. "1" + Time time; ///< timestamp + Vector pos; ///< reference position + Vector vel; ///< reference velocity + + ReferencePoint (std::string const & id, Time t, Vector const & p, Vector const & v) + : node (id), + time (t), + pos (p), + vel (v) + { + } + /// Sort by timestamp + bool operator< (ReferencePoint const & o) const + { + return (time < o.time); + } + }; + /** + * Create new test case. To make it useful SetTrace () and AddReferencePoint () must be called + * + * \param name Short description + * \param nodes Number of nodes used in the test trace, 1 by default + */ + Ns2MobilityHelperTest (std::string const & name, Time timeLimit, uint32_t nodes = 1) + : TestCase (name), + m_timeLimit (timeLimit), + m_nodeCount (nodes), + m_nextRefPoint (0) + { + } + /// Empty + virtual ~Ns2MobilityHelperTest () + { + } + /// Set NS-2 trace to read as single large string (don't forget to add \n and quote ") + void SetTrace (std::string const & trace) + { + m_trace = trace; + } + /// Add next reference point + void AddReferencePoint (ReferencePoint const & r) + { + m_reference.push_back (r); + } + /// Sugar + void AddReferencePoint (const char * id, double sec, Vector const & p, Vector const & v) + { + AddReferencePoint (ReferencePoint (id, Seconds (sec), p, v)); + } + +private: + /// Test time limit + Time m_timeLimit; + /// Number of nodes used in the test + uint32_t m_nodeCount; + /// Trace as string + std::string m_trace; + /// Reference mobility + std::vector m_reference; + /// Next reference point to be checked + size_t m_nextRefPoint; + /// TMP trace file name + std::string m_traceFile; + +private: + /// Dump NS-2 trace to tmp file + bool WriteTrace () + { + m_traceFile = GetTempDir () + "Ns2MobilityHelperTest.tcl"; + std::ofstream of (m_traceFile.c_str ()); + NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL (of.is_open (), true, "Need to write tmp. file"); + of << m_trace; + of.close (); + return false; // no errors + } + /// Create and name nodes + void CreateNodes () + { + NodeContainer nodes; + nodes.Create (m_nodeCount); + for (uint32_t i = 0; i < m_nodeCount; ++i) + { + std::ostringstream os; + os << i; + Names::Add (os.str (), nodes.Get (i)); + } + } + /// Check that all initial positions are correct + bool CheckInitialPositions () + { + std::stable_sort (m_reference.begin (), m_reference.end ()); + while (m_nextRefPoint < m_reference.size () && m_reference[m_nextRefPoint].time == Seconds (0)) + { + ReferencePoint const & rp = m_reference[m_nextRefPoint]; + Ptr node = Names::Find (rp.node); + NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL (node, 0, "Can't find node with id " << rp.node); + Ptr mob = node->GetObject (); + NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL (mob, 0, "Can't find mobility for node " << rp.node); + + NS_TEST_EXPECT_MSG_EQ (rp.pos, mob->GetPosition (), "Initial position mismatch for node " << rp.node); + NS_TEST_EXPECT_MSG_EQ (rp.vel, mob->GetVelocity (), "Initial velocity mismatch for node " << rp.node); + + m_nextRefPoint++; + } + return GetErrorStatus (); + } + /// Listen for course change events + void CourseChange (std::string context, Ptr mobility) + { + Time time = Simulator::Now (); + Ptr node = mobility->GetObject (); + NS_ASSERT (node); + std::string id = Names::FindName (node); + NS_ASSERT (!id.empty ()); + Vector pos = mobility->GetPosition (); + Vector vel = mobility->GetVelocity (); + + NS_TEST_EXPECT_MSG_LT (m_nextRefPoint, m_reference.size (), "Not enough reference points"); + if (m_nextRefPoint >= m_reference.size ()) + { + return; + } + + ReferencePoint const & ref = m_reference [m_nextRefPoint++]; + NS_TEST_EXPECT_MSG_EQ (time, ref.time, "Time mismatch"); + NS_TEST_EXPECT_MSG_EQ (id, ref.node, "Node ID mismatch at time " << time.GetSeconds () << " s"); + NS_TEST_EXPECT_MSG_EQ (pos, ref.pos, "Position mismatch at time " << time.GetSeconds () << " s for node " << id); + NS_TEST_EXPECT_MSG_EQ (vel, ref.vel, "Velocity mismatch at time " << time.GetSeconds () << " s for node " << id); + } + /// Go + void DoRun () + { + NS_TEST_ASSERT_MSG_EQ (m_trace.empty (), false, "Need trace"); + NS_TEST_ASSERT_MSG_EQ (m_reference.empty (), false, "Need reference"); + + if (WriteTrace ()) + { + return; + } + CreateNodes (); + Ns2MobilityHelper mobility (m_traceFile); + mobility.Install (); + if (CheckInitialPositions ()) + { + return; + } + Config::Connect ("/NodeList/*/$ns3::MobilityModel/CourseChange", + MakeCallback (&Ns2MobilityHelperTest::CourseChange, this)); + Simulator::Stop (m_timeLimit); + Simulator::Run (); + Names::Clear (); + std::remove (m_traceFile.c_str ()); + Simulator::Destroy (); + } +}; + +/// The test suite +class Ns2MobilityHelperTestSuite : public TestSuite +{ +public: + Ns2MobilityHelperTestSuite () : TestSuite ("mobility-ns2-trace-helper", UNIT) + { + // to be used as temporary variable for test cases. + // Note that test suite takes care of deleting all test cases. + Ns2MobilityHelperTest * t (0); + + // Initial position + t = new Ns2MobilityHelperTest ("initial position", Seconds (1)); + t->SetTrace ("$node_(0) set X_ 1.0\n" + "$node_(0) set Y_ 2.0\n" + "$node_(0) set Z_ 3.0\n" + ); + t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0)); + AddTestCase (t); + + // Check parsing comments, empty lines and no EOF at the end of file + t = new Ns2MobilityHelperTest ("comments", Seconds (1)); + t->SetTrace ("# comment\n" + "\n\n" // empty lines + "$node_(0) set X_ 1.0 # comment \n" + "$node_(0) set Y_ 2.0 ### \n" + "$node_(0) set Z_ 3.0 # $node_(0) set Z_ 3.0\n" + "#$node_(0) set Z_ 100 #" + ); + t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0)); + AddTestCase (t); + + // Simple setdest. Arguments are interpreted as x, y, speed by default + t = new Ns2MobilityHelperTest ("simple setdest", Seconds (10)); + t->SetTrace ("$ns_ at 1.0 \"$node_(0) setdest 25 0 5\""); + // id t position velocity + t->AddReferencePoint ("0", 0, Vector (0, 0, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 1, Vector (0, 0, 0), Vector (5, 0, 0)); + t->AddReferencePoint ("0", 6, Vector (25, 0, 0), Vector (0, 0, 0)); + AddTestCase (t); + + // Several set and setdest. Arguments are interpreted as x, y, speed by default + t = new Ns2MobilityHelperTest ("square setdest", Seconds (6)); + t->SetTrace ("$node_(0) set X_ 0.0\n" + "$node_(0) set Y_ 0.0\n" + "$ns_ at 1.0 \"$node_(0) setdest 5 0 5\"\n" + "$ns_ at 2.0 \"$node_(0) setdest 5 5 5\"\n" + "$ns_ at 3.0 \"$node_(0) setdest 0 5 5\"\n" + "$ns_ at 4.0 \"$node_(0) setdest 0 0 5\"\n" + ); + // id t position velocity + t->AddReferencePoint ("0", 0, Vector (0, 0, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 1, Vector (0, 0, 0), Vector (5, 0, 0)); + t->AddReferencePoint ("0", 2, Vector (5, 0, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 2, Vector (5, 0, 0), Vector (0, 5, 0)); + t->AddReferencePoint ("0", 3, Vector (5, 5, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 3, Vector (5, 5, 0), Vector (-5, 0, 0)); + t->AddReferencePoint ("0", 4, Vector (0, 5, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 4, Vector (0, 5, 0), Vector (0, -5, 0)); + t->AddReferencePoint ("0", 5, Vector (0, 0, 0), Vector (0, 0, 0)); + AddTestCase (t); + + // Scheduled set position + t = new Ns2MobilityHelperTest ("scheduled set position", Seconds (2)); + t->SetTrace ("$ns_ at 1.0 \"$node_(0) set X_ 10\"\n" + "$ns_ at 1.0 \"$node_(0) set Z_ 10\"\n" + "$ns_ at 1.0 \"$node_(0) set Y_ 10\""); + // id t position velocity + t->AddReferencePoint ("0", 1, Vector (10, 0, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 1, Vector (10, 0, 10), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 1, Vector (10, 10, 10), Vector (0, 0, 0)); + AddTestCase (t); + + // Malformed lines + t = new Ns2MobilityHelperTest ("malformed lines", Seconds (2)); + t->SetTrace ("$node() set X_ 1 # node id is not present\n" + "$node # incoplete line\"\n" + "$node this line is not correct\n" + "$node_(0) set X_ 1 # line OK \n" + "$node_(0) set Y_ 2 # line OK \n" + "$node_(0) set Z_ 3 # line OK \n" + "$ns_ at \"$node_(0) setdest 4 4 4\" # time not present\n" + "$ns_ at 1 \"$node_(0) setdest 2 2 1 \" # line OK \n"); + // id t position velocity + t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 1, Vector (1, 2, 3), Vector (1, 0, 0)); + t->AddReferencePoint ("0", 2, Vector (2, 2, 3), Vector (0, 0, 0)); + AddTestCase (t); + + // Non possible values + t = new Ns2MobilityHelperTest ("non possible values", Seconds (2)); + t->SetTrace ("$node_(0) set X_ 1 # line OK \n" + "$node_(0) set Y_ 2 # line OK \n" + "$node_(0) set Z_ 3 # line OK \n" + "$node_(-22) set Y_ 3 # node id not correct\n" + "$node_(3.3) set Y_ 1111 # node id not correct\n" + "$ns_ at sss \"$node_(0) setdest 5 5 5\" # time is not a number\n" + "$ns_ at 1 \"$node_(0) setdest 2 2 1\" # line OK \n" + "$ns_ at 1 \"$node_(0) setdest 2 2 -1\" # negative speed is not correct\n" + "$ns_ at 1 \"$node_(0) setdest 2 2 sdfs\" # speed is not a number\n" + "$ns_ at 1 \"$node_(0) setdest 2 2 s232dfs\" # speed is not a number\n" + "$ns_ at 1 \"$node_(0) setdest 233 2.. s232dfs\" # more than one non numbers\n" + "$ns_ at -12 \"$node_(0) setdest 11 22 33\" # time should not be negative\n"); + // id t position velocity + t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 1, Vector (1, 2, 3), Vector (1, 0, 0)); + t->AddReferencePoint ("0", 2, Vector (2, 2, 3), Vector (0, 0, 0)); + AddTestCase (t); + + // More than one node + t = new Ns2MobilityHelperTest ("few nodes, combinations of set and setdest", Seconds (10), 3); + t->SetTrace ("$node_(0) set X_ 1.0\n" + "$node_(0) set Y_ 2.0\n" + "$node_(0) set Z_ 3.0\n" + "$ns_ at 1.0 \"$node_(1) setdest 25 0 5\"\n" + "$node_(2) set X_ 0.0\n" + "$node_(2) set Y_ 0.0\n" + "$ns_ at 1.0 \"$node_(2) setdest 5 0 5\"\n" + "$ns_ at 2.0 \"$node_(2) setdest 5 5 5\"\n" + "$ns_ at 3.0 \"$node_(2) setdest 0 5 5\"\n" + "$ns_ at 4.0 \"$node_(2) setdest 0 0 5\"\n"); + // id t position velocity + t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0)); + t->AddReferencePoint ("1", 0, Vector (0, 0, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("1", 1, Vector (0, 0, 0), Vector (5, 0, 0)); + t->AddReferencePoint ("1", 6, Vector (25, 0, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("2", 0, Vector (0, 0, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("2", 1, Vector (0, 0, 0), Vector (5, 0, 0)); + t->AddReferencePoint ("2", 2, Vector (5, 0, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("2", 2, Vector (5, 0, 0), Vector (0, 5, 0)); + t->AddReferencePoint ("2", 3, Vector (5, 5, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("2", 3, Vector (5, 5, 0), Vector (-5, 0, 0)); + t->AddReferencePoint ("2", 4, Vector (0, 5, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("2", 4, Vector (0, 5, 0), Vector (0, -5, 0)); + t->AddReferencePoint ("2", 5, Vector (0, 0, 0), Vector (0, 0, 0)); + AddTestCase (t); + + // Test for Speed == 0, that acts as stop the node. + t = new Ns2MobilityHelperTest ("setdest with speed cero", Seconds (10)); + t->SetTrace ("$ns_ at 1.0 \"$node_(0) setdest 25 0 5\"\n" + "$ns_ at 7.0 \"$node_(0) setdest 11 22 0\"\n"); + // id t position velocity + t->AddReferencePoint ("0", 0, Vector (0, 0, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 1, Vector (0, 0, 0), Vector (5, 0, 0)); + t->AddReferencePoint ("0", 6, Vector (25, 0, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 7, Vector (25, 0, 0), Vector (0, 0, 0)); + AddTestCase (t); + + + // Test negative positions + t = new Ns2MobilityHelperTest ("test negative positions", Seconds (10)); + t->SetTrace ("$node_(0) set X_ -1.0\n" + "$node_(0) set Y_ 0\n" + "$ns_ at 1.0 \"$node_(0) setdest 0 0 1\"\n" + "$ns_ at 2.0 \"$node_(0) setdest 0 -1 1\"\n"); + // id t position velocity + t->AddReferencePoint ("0", 0, Vector (-1, 0, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 1, Vector (-1, 0, 0), Vector (1, 0, 0)); + t->AddReferencePoint ("0", 2, Vector (0, 0, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 2, Vector (0, 0, 0), Vector (0, -1, 0)); + t->AddReferencePoint ("0", 3, Vector (0, -1, 0), Vector (0, 0, 0)); + AddTestCase (t); + + // Sqare setdest with values in the form 1.0e+2 + t = new Ns2MobilityHelperTest ("Foalt numbers in 1.0e+2 format", Seconds (6)); + t->SetTrace ("$node_(0) set X_ 0.0\n" + "$node_(0) set Y_ 0.0\n" + "$ns_ at 1.0 \"$node_(0) setdest 1.0e+2 0 1.0e+2\"\n" + "$ns_ at 2.0 \"$node_(0) setdest 1.0e+2 1.0e+2 1.0e+2\"\n" + "$ns_ at 3.0 \"$node_(0) setdest 0 1.0e+2 1.0e+2\"\n" + "$ns_ at 4.0 \"$node_(0) setdest 0 0 1.0e+2\"\n"); + // id t position velocity + t->AddReferencePoint ("0", 0, Vector (0, 0, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 1, Vector (0, 0, 0), Vector (100, 0, 0)); + t->AddReferencePoint ("0", 2, Vector (100, 0, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 2, Vector (100, 0, 0), Vector (0, 100, 0)); + t->AddReferencePoint ("0", 3, Vector (100, 100, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 3, Vector (100, 100, 0), Vector (-100, 0, 0)); + t->AddReferencePoint ("0", 4, Vector (0, 100, 0), Vector (0, 0, 0)); + t->AddReferencePoint ("0", 4, Vector (0, 100, 0), Vector (0, -100, 0)); + t->AddReferencePoint ("0", 5, Vector (0, 0, 0), Vector (0, 0, 0)); + AddTestCase (t); + + } +} g_ns2TransmobilityHelperTestSuite; + + +} // namespace ns3 diff --git a/src/mobility/wscript b/src/mobility/wscript index ad76150b7..b065ae20c 100644 --- a/src/mobility/wscript +++ b/src/mobility/wscript @@ -25,6 +25,7 @@ def build(bld): mobility_test = bld.create_ns3_module_test_library('mobility') mobility_test.source = [ + 'test/ns2-mobility-helper-test-suite.cc', 'test/steady-state-random-waypoint-mobility-model-test.cc', 'test/waypoint-mobility-model-test.cc', ]