A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ns2-mobility-helper-test-suite.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007 INRIA
4  * 2009,2010 Contributors
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  * Contributors: Thomas Waldecker <twaldecker@rocketmail.com>
21  * Martín Giachino <martin.giachino@gmail.com>
22  *
23  * Brief description: Implementation of a ns2 movement trace file reader.
24  *
25  * This implementation is based on the ns2 movement documentation of ns2
26  * as described in http://www.isi.edu/nsnam/ns/doc/node174.html
27  *
28  * Valid trace files use the following ns2 statements:
29  *
30  * $node set X_ x1
31  * $node set Y_ y1
32  * $node set Z_ z1
33  * $ns at $time $node setdest x2 y2 speed
34  * $ns at $time $node set X_ x1
35  * $ns at $time $node set Y_ Y1
36  * $ns at $time $node set Z_ Z1
37  *
38  */
39 
40 #include <algorithm>
41 #include "ns3/log.h"
42 #include "ns3/simulator.h"
43 #include "ns3/node-list.h"
44 #include "ns3/node.h"
45 #include "ns3/constant-velocity-mobility-model.h"
46 #include "ns3/test.h"
47 #include "ns3/node-container.h"
48 #include "ns3/names.h"
49 #include "ns3/config.h"
50 #include "ns3/ns2-mobility-helper.h"
51 
52 namespace ns3 {
53 
54 // -----------------------------------------------------------------------------
55 // Testing
56 // -----------------------------------------------------------------------------
57 bool operator== (Vector const & a, Vector const & b)
58 {
59  return (a.x == b.x && a.y == b.y && a.z == b.z);
60 }
69 {
70 public:
73  {
74  std::string node;
78 
79  ReferencePoint (std::string const & id, Time t, Vector const & p, Vector const & v)
80  : node (id),
81  time (t),
82  pos (p),
83  vel (v)
84  {
85  }
87  bool operator< (ReferencePoint const & o) const
88  {
89  return (time < o.time);
90  }
91  };
99  Ns2MobilityHelperTest (std::string const & name, Time timeLimit, uint32_t nodes = 1)
100  : TestCase (name),
101  m_timeLimit (timeLimit),
102  m_nodeCount (nodes),
103  m_nextRefPoint (0)
104  {
105  }
108  {
109  }
111  void SetTrace (std::string const & trace)
112  {
113  m_trace = trace;
114  }
117  {
118  m_reference.push_back (r);
119  }
121  void AddReferencePoint (const char * id, double sec, Vector const & p, Vector const & v)
122  {
123  AddReferencePoint (ReferencePoint (id, Seconds (sec), p, v));
124  }
125 
126 private:
130  uint32_t m_nodeCount;
132  std::string m_trace;
134  std::vector<ReferencePoint> m_reference;
138  std::string m_traceFile;
139 
140 private:
142  bool WriteTrace ()
143  {
144  m_traceFile = CreateTempDirFilename ("Ns2MobilityHelperTest.tcl");
145  std::ofstream of (m_traceFile.c_str ());
146  NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL (of.is_open (), true, "Need to write tmp. file");
147  of << m_trace;
148  of.close ();
149  return false; // no errors
150  }
152  void CreateNodes ()
153  {
154  NodeContainer nodes;
155  nodes.Create (m_nodeCount);
156  for (uint32_t i = 0; i < m_nodeCount; ++i)
157  {
158  std::ostringstream os;
159  os << i;
160  Names::Add (os.str (), nodes.Get (i));
161  }
162  }
165  {
166  std::stable_sort (m_reference.begin (), m_reference.end ());
167  while (m_nextRefPoint < m_reference.size () && m_reference[m_nextRefPoint].time == Seconds (0))
168  {
170  Ptr<Node> node = Names::Find<Node> (rp.node);
171  NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL (node, 0, "Can't find node with id " << rp.node);
173  NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL (mob, 0, "Can't find mobility for node " << rp.node);
174 
175  NS_TEST_EXPECT_MSG_EQ (rp.pos, mob->GetPosition (), "Initial position mismatch for node " << rp.node);
176  NS_TEST_EXPECT_MSG_EQ (rp.vel, mob->GetVelocity (), "Initial velocity mismatch for node " << rp.node);
177 
178  m_nextRefPoint++;
179  }
180  return IsStatusFailure ();
181  }
183  void CourseChange (std::string context, Ptr<const MobilityModel> mobility)
184  {
185  Time time = Simulator::Now ();
186  Ptr<Node> node = mobility->GetObject<Node> ();
187  NS_ASSERT (node);
188  std::string id = Names::FindName (node);
189  NS_ASSERT (!id.empty ());
190  Vector pos = mobility->GetPosition ();
191  Vector vel = mobility->GetVelocity ();
192 
193  NS_TEST_EXPECT_MSG_LT (m_nextRefPoint, m_reference.size (), "Not enough reference points");
194  if (m_nextRefPoint >= m_reference.size ())
195  {
196  return;
197  }
198 
199  ReferencePoint const & ref = m_reference [m_nextRefPoint++];
200  NS_TEST_EXPECT_MSG_EQ (time, ref.time, "Time mismatch");
201  NS_TEST_EXPECT_MSG_EQ (id, ref.node, "Node ID mismatch at time " << time.GetSeconds () << " s");
202  NS_TEST_EXPECT_MSG_EQ (pos, ref.pos, "Position mismatch at time " << time.GetSeconds () << " s for node " << id);
203  NS_TEST_EXPECT_MSG_EQ (vel, ref.vel, "Velocity mismatch at time " << time.GetSeconds () << " s for node " << id);
204  }
205 
206  void DoSetup ()
207  {
208  CreateNodes ();
209  }
210 
211  void DoTeardown ()
212  {
213  Names::Clear ();
214  std::remove (m_traceFile.c_str ());
216  }
217 
219  void DoRun ()
220  {
221  NS_TEST_ASSERT_MSG_EQ (m_trace.empty (), false, "Need trace");
222  NS_TEST_ASSERT_MSG_EQ (m_reference.empty (), false, "Need reference");
223 
224  if (WriteTrace ())
225  {
226  return;
227  }
228  Ns2MobilityHelper mobility (m_traceFile);
229  mobility.Install ();
230  if (CheckInitialPositions ())
231  {
232  return;
233  }
234  Config::Connect ("/NodeList/*/$ns3::MobilityModel/CourseChange",
237  Simulator::Run ();
238  }
239 };
240 
243 {
244 public:
245  Ns2MobilityHelperTestSuite () : TestSuite ("mobility-ns2-trace-helper", UNIT)
246  {
247  SetDataDir (NS_TEST_SOURCEDIR);
248 
249  // to be used as temporary variable for test cases.
250  // Note that test suite takes care of deleting all test cases.
251  Ns2MobilityHelperTest * t (0);
252 
253  // Initial position
254  t = new Ns2MobilityHelperTest ("initial position", Seconds (1));
255  t->SetTrace ("$node_(0) set X_ 1.0\n"
256  "$node_(0) set Y_ 2.0\n"
257  "$node_(0) set Z_ 3.0\n"
258  );
259  t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0));
260  AddTestCase (t);
261 
262  // Check parsing comments, empty lines and no EOF at the end of file
263  t = new Ns2MobilityHelperTest ("comments", Seconds (1));
264  t->SetTrace ("# comment\n"
265  "\n\n" // empty lines
266  "$node_(0) set X_ 1.0 # comment \n"
267  "$node_(0) set Y_ 2.0 ### \n"
268  "$node_(0) set Z_ 3.0 # $node_(0) set Z_ 3.0\n"
269  "#$node_(0) set Z_ 100 #"
270  );
271  t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0));
272  AddTestCase (t);
273 
274  // Simple setdest. Arguments are interpreted as x, y, speed by default
275  t = new Ns2MobilityHelperTest ("simple setdest", Seconds (10));
276  t->SetTrace ("$ns_ at 1.0 \"$node_(0) setdest 25 0 5\"");
277  // id t position velocity
278  t->AddReferencePoint ("0", 0, Vector (0, 0, 0), Vector (0, 0, 0));
279  t->AddReferencePoint ("0", 1, Vector (0, 0, 0), Vector (5, 0, 0));
280  t->AddReferencePoint ("0", 6, Vector (25, 0, 0), Vector (0, 0, 0));
281  AddTestCase (t);
282 
283  // Several set and setdest. Arguments are interpreted as x, y, speed by default
284  t = new Ns2MobilityHelperTest ("square setdest", Seconds (6));
285  t->SetTrace ("$node_(0) set X_ 0.0\n"
286  "$node_(0) set Y_ 0.0\n"
287  "$ns_ at 1.0 \"$node_(0) setdest 5 0 5\"\n"
288  "$ns_ at 2.0 \"$node_(0) setdest 5 5 5\"\n"
289  "$ns_ at 3.0 \"$node_(0) setdest 0 5 5\"\n"
290  "$ns_ at 4.0 \"$node_(0) setdest 0 0 5\"\n"
291  );
292  // id t position velocity
293  t->AddReferencePoint ("0", 0, Vector (0, 0, 0), Vector (0, 0, 0));
294  t->AddReferencePoint ("0", 1, Vector (0, 0, 0), Vector (5, 0, 0));
295  t->AddReferencePoint ("0", 2, Vector (5, 0, 0), Vector (0, 0, 0));
296  t->AddReferencePoint ("0", 2, Vector (5, 0, 0), Vector (0, 5, 0));
297  t->AddReferencePoint ("0", 3, Vector (5, 5, 0), Vector (0, 0, 0));
298  t->AddReferencePoint ("0", 3, Vector (5, 5, 0), Vector (-5, 0, 0));
299  t->AddReferencePoint ("0", 4, Vector (0, 5, 0), Vector (0, 0, 0));
300  t->AddReferencePoint ("0", 4, Vector (0, 5, 0), Vector (0, -5, 0));
301  t->AddReferencePoint ("0", 5, Vector (0, 0, 0), Vector (0, 0, 0));
302  AddTestCase (t);
303 
304  // Copy of previous test case but with the initial positions at
305  // the end of the trace rather than at the beginning.
306  //
307  // Several set and setdest. Arguments are interpreted as x, y, speed by default
308  t = new Ns2MobilityHelperTest ("square setdest (initial positions at end)", Seconds (6));
309  t->SetTrace ("$ns_ at 1.0 \"$node_(0) setdest 15 10 5\"\n"
310  "$ns_ at 2.0 \"$node_(0) setdest 15 15 5\"\n"
311  "$ns_ at 3.0 \"$node_(0) setdest 10 15 5\"\n"
312  "$ns_ at 4.0 \"$node_(0) setdest 10 10 5\"\n"
313  "$node_(0) set X_ 10.0\n"
314  "$node_(0) set Y_ 10.0\n"
315  );
316  // id t position velocity
317  t->AddReferencePoint ("0", 0, Vector (10, 10, 0), Vector (0, 0, 0));
318  t->AddReferencePoint ("0", 1, Vector (10, 10, 0), Vector (5, 0, 0));
319  t->AddReferencePoint ("0", 2, Vector (15, 10, 0), Vector (0, 0, 0));
320  t->AddReferencePoint ("0", 2, Vector (15, 10, 0), Vector (0, 5, 0));
321  t->AddReferencePoint ("0", 3, Vector (15, 15, 0), Vector (0, 0, 0));
322  t->AddReferencePoint ("0", 3, Vector (15, 15, 0), Vector (-5, 0, 0));
323  t->AddReferencePoint ("0", 4, Vector (10, 15, 0), Vector (0, 0, 0));
324  t->AddReferencePoint ("0", 4, Vector (10, 15, 0), Vector (0, -5, 0));
325  t->AddReferencePoint ("0", 5, Vector (10, 10, 0), Vector (0, 0, 0));
326  AddTestCase (t);
327 
328  // Scheduled set position
329  t = new Ns2MobilityHelperTest ("scheduled set position", Seconds (2));
330  t->SetTrace ("$ns_ at 1.0 \"$node_(0) set X_ 10\"\n"
331  "$ns_ at 1.0 \"$node_(0) set Z_ 10\"\n"
332  "$ns_ at 1.0 \"$node_(0) set Y_ 10\"");
333  // id t position velocity
334  t->AddReferencePoint ("0", 1, Vector (10, 0, 0), Vector (0, 0, 0));
335  t->AddReferencePoint ("0", 1, Vector (10, 0, 10), Vector (0, 0, 0));
336  t->AddReferencePoint ("0", 1, Vector (10, 10, 10), Vector (0, 0, 0));
337  AddTestCase (t);
338 
339  // Malformed lines
340  t = new Ns2MobilityHelperTest ("malformed lines", Seconds (2));
341  t->SetTrace ("$node() set X_ 1 # node id is not present\n"
342  "$node # incoplete line\"\n"
343  "$node this line is not correct\n"
344  "$node_(0) set X_ 1 # line OK \n"
345  "$node_(0) set Y_ 2 # line OK \n"
346  "$node_(0) set Z_ 3 # line OK \n"
347  "$ns_ at \"$node_(0) setdest 4 4 4\" # time not present\n"
348  "$ns_ at 1 \"$node_(0) setdest 2 2 1 \" # line OK \n");
349  // id t position velocity
350  t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0));
351  t->AddReferencePoint ("0", 1, Vector (1, 2, 3), Vector (1, 0, 0));
352  t->AddReferencePoint ("0", 2, Vector (2, 2, 3), Vector (0, 0, 0));
353  AddTestCase (t);
354 
355  // Non possible values
356  t = new Ns2MobilityHelperTest ("non possible values", Seconds (2));
357  t->SetTrace ("$node_(0) set X_ 1 # line OK \n"
358  "$node_(0) set Y_ 2 # line OK \n"
359  "$node_(0) set Z_ 3 # line OK \n"
360  "$node_(-22) set Y_ 3 # node id not correct\n"
361  "$node_(3.3) set Y_ 1111 # node id not correct\n"
362  "$ns_ at sss \"$node_(0) setdest 5 5 5\" # time is not a number\n"
363  "$ns_ at 1 \"$node_(0) setdest 2 2 1\" # line OK \n"
364  "$ns_ at 1 \"$node_(0) setdest 2 2 -1\" # negative speed is not correct\n"
365  "$ns_ at 1 \"$node_(0) setdest 2 2 sdfs\" # speed is not a number\n"
366  "$ns_ at 1 \"$node_(0) setdest 2 2 s232dfs\" # speed is not a number\n"
367  "$ns_ at 1 \"$node_(0) setdest 233 2.. s232dfs\" # more than one non numbers\n"
368  "$ns_ at -12 \"$node_(0) setdest 11 22 33\" # time should not be negative\n");
369  // id t position velocity
370  t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0));
371  t->AddReferencePoint ("0", 1, Vector (1, 2, 3), Vector (1, 0, 0));
372  t->AddReferencePoint ("0", 2, Vector (2, 2, 3), Vector (0, 0, 0));
373  AddTestCase (t);
374 
375  // More than one node
376  t = new Ns2MobilityHelperTest ("few nodes, combinations of set and setdest", Seconds (10), 3);
377  t->SetTrace ("$node_(0) set X_ 1.0\n"
378  "$node_(0) set Y_ 2.0\n"
379  "$node_(0) set Z_ 3.0\n"
380  "$ns_ at 1.0 \"$node_(1) setdest 25 0 5\"\n"
381  "$node_(2) set X_ 0.0\n"
382  "$node_(2) set Y_ 0.0\n"
383  "$ns_ at 1.0 \"$node_(2) setdest 5 0 5\"\n"
384  "$ns_ at 2.0 \"$node_(2) setdest 5 5 5\"\n"
385  "$ns_ at 3.0 \"$node_(2) setdest 0 5 5\"\n"
386  "$ns_ at 4.0 \"$node_(2) setdest 0 0 5\"\n");
387  // id t position velocity
388  t->AddReferencePoint ("0", 0, Vector (1, 2, 3), Vector (0, 0, 0));
389  t->AddReferencePoint ("1", 0, Vector (0, 0, 0), Vector (0, 0, 0));
390  t->AddReferencePoint ("1", 1, Vector (0, 0, 0), Vector (5, 0, 0));
391  t->AddReferencePoint ("1", 6, Vector (25, 0, 0), Vector (0, 0, 0));
392  t->AddReferencePoint ("2", 0, Vector (0, 0, 0), Vector (0, 0, 0));
393  t->AddReferencePoint ("2", 1, Vector (0, 0, 0), Vector (5, 0, 0));
394  t->AddReferencePoint ("2", 2, Vector (5, 0, 0), Vector (0, 0, 0));
395  t->AddReferencePoint ("2", 2, Vector (5, 0, 0), Vector (0, 5, 0));
396  t->AddReferencePoint ("2", 3, Vector (5, 5, 0), Vector (0, 0, 0));
397  t->AddReferencePoint ("2", 3, Vector (5, 5, 0), Vector (-5, 0, 0));
398  t->AddReferencePoint ("2", 4, Vector (0, 5, 0), Vector (0, 0, 0));
399  t->AddReferencePoint ("2", 4, Vector (0, 5, 0), Vector (0, -5, 0));
400  t->AddReferencePoint ("2", 5, Vector (0, 0, 0), Vector (0, 0, 0));
401  AddTestCase (t);
402 
403  // Test for Speed == 0, that acts as stop the node.
404  t = new Ns2MobilityHelperTest ("setdest with speed cero", Seconds (10));
405  t->SetTrace ("$ns_ at 1.0 \"$node_(0) setdest 25 0 5\"\n"
406  "$ns_ at 7.0 \"$node_(0) setdest 11 22 0\"\n");
407  // id t position velocity
408  t->AddReferencePoint ("0", 0, Vector (0, 0, 0), Vector (0, 0, 0));
409  t->AddReferencePoint ("0", 1, Vector (0, 0, 0), Vector (5, 0, 0));
410  t->AddReferencePoint ("0", 6, Vector (25, 0, 0), Vector (0, 0, 0));
411  t->AddReferencePoint ("0", 7, Vector (25, 0, 0), Vector (0, 0, 0));
412  AddTestCase (t);
413 
414 
415  // Test negative positions
416  t = new Ns2MobilityHelperTest ("test negative positions", Seconds (10));
417  t->SetTrace ("$node_(0) set X_ -1.0\n"
418  "$node_(0) set Y_ 0\n"
419  "$ns_ at 1.0 \"$node_(0) setdest 0 0 1\"\n"
420  "$ns_ at 2.0 \"$node_(0) setdest 0 -1 1\"\n");
421  // id t position velocity
422  t->AddReferencePoint ("0", 0, Vector (-1, 0, 0), Vector (0, 0, 0));
423  t->AddReferencePoint ("0", 1, Vector (-1, 0, 0), Vector (1, 0, 0));
424  t->AddReferencePoint ("0", 2, Vector (0, 0, 0), Vector (0, 0, 0));
425  t->AddReferencePoint ("0", 2, Vector (0, 0, 0), Vector (0, -1, 0));
426  t->AddReferencePoint ("0", 3, Vector (0, -1, 0), Vector (0, 0, 0));
427  AddTestCase (t);
428 
429  // Sqare setdest with values in the form 1.0e+2
430  t = new Ns2MobilityHelperTest ("Foalt numbers in 1.0e+2 format", Seconds (6));
431  t->SetTrace ("$node_(0) set X_ 0.0\n"
432  "$node_(0) set Y_ 0.0\n"
433  "$ns_ at 1.0 \"$node_(0) setdest 1.0e+2 0 1.0e+2\"\n"
434  "$ns_ at 2.0 \"$node_(0) setdest 1.0e+2 1.0e+2 1.0e+2\"\n"
435  "$ns_ at 3.0 \"$node_(0) setdest 0 1.0e+2 1.0e+2\"\n"
436  "$ns_ at 4.0 \"$node_(0) setdest 0 0 1.0e+2\"\n");
437  // id t position velocity
438  t->AddReferencePoint ("0", 0, Vector (0, 0, 0), Vector (0, 0, 0));
439  t->AddReferencePoint ("0", 1, Vector (0, 0, 0), Vector (100, 0, 0));
440  t->AddReferencePoint ("0", 2, Vector (100, 0, 0), Vector (0, 0, 0));
441  t->AddReferencePoint ("0", 2, Vector (100, 0, 0), Vector (0, 100, 0));
442  t->AddReferencePoint ("0", 3, Vector (100, 100, 0), Vector (0, 0, 0));
443  t->AddReferencePoint ("0", 3, Vector (100, 100, 0), Vector (-100, 0, 0));
444  t->AddReferencePoint ("0", 4, Vector (0, 100, 0), Vector (0, 0, 0));
445  t->AddReferencePoint ("0", 4, Vector (0, 100, 0), Vector (0, -100, 0));
446  t->AddReferencePoint ("0", 5, Vector (0, 0, 0), Vector (0, 0, 0));
447  AddTestCase (t);
448  t = new Ns2MobilityHelperTest ("Bug 1219 testcase", Seconds (16));
449  t->SetTrace ("$node_(0) set X_ 0.0\n"
450  "$node_(0) set Y_ 0.0\n"
451  "$ns_ at 1.0 \"$node_(0) setdest 0 10 1\"\n"
452  "$ns_ at 6.0 \"$node_(0) setdest 0 -10 1\"\n"
453  );
454  // id t position velocity
455  t->AddReferencePoint ("0", 0, Vector (0, 0, 0), Vector (0, 0, 0));
456  t->AddReferencePoint ("0", 1, Vector (0, 0, 0), Vector (0, 1, 0));
457  t->AddReferencePoint ("0", 6, Vector (0, 5, 0), Vector (0, -1, 0));
458  t->AddReferencePoint ("0", 16, Vector (0, -10, 0), Vector (0, 0, 0));
459  AddTestCase (t);
460  t = new Ns2MobilityHelperTest ("Bug 1059 testcase", Seconds (16));
461  t->SetTrace ("$node_(0) set X_ 10.0\r\n"
462  "$node_(0) set Y_ 0.0\r\n"
463  );
464  // id t position velocity
465  t->AddReferencePoint ("0", 0, Vector (10, 0, 0), Vector (0, 0, 0));
466  AddTestCase (t);
467  t = new Ns2MobilityHelperTest ("Bug 1301 testcase", Seconds (16));
468  t->SetTrace ("$node_(0) set X_ 10.0\n"
469  "$node_(0) set Y_ 0.0\n"
470  "$ns_ at 1.0 \"$node_(0) setdest 10 0 1\"\n"
471  );
472  // id t position velocity
473  // Moving to the current position must change nothing. No NaN
474  // speed must be.
475  t->AddReferencePoint ("0", 0, Vector (10, 0, 0), Vector (0, 0, 0));
476  AddTestCase (t);
477 
478 
479  }
481 
482 
483 } // namespace ns3