A Discrete-Event Network Simulator
API
time-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) 2005,2006 INRIA
4  * Copyright (c) 2007 Emmanuelle Laprise
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  * TimeStep support by Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
21  */
22 
23 #include <array>
24 #include <iomanip>
25 #include <iostream>
26 #include <string>
27 #include <sstream>
28 #include <tuple>
29 
30 #include "ns3/nstime.h"
31 #include "ns3/int64x64.h"
32 #include "ns3/test.h"
33 
34 using namespace ns3;
40 {
41 public:
46 
47 private:
51  virtual void DoSetup (void);
52 
56  virtual void DoRun (void);
57 
61  virtual void DoTimeOperations (void);
62 
66  virtual void DoTeardown (void);
67 
78  template<typename T>
79  void TestMultiplication (Time t, Time expected, T val, const std::string& msg);
80 
84  void TestMultiplicationByIntegerTypes ();
85 
89  void TestMultiplicationByDecimalTypes ();
90 
101  template<typename T>
102  void TestDivision(Time t, Time expected, T val, const std::string& msg);
103 
107  void TestDivisionByIntegerTypes ();
108 
112  void TestDivisionByDecimalTypes ();
113 };
114 
116  : TestCase ("Sanity check of common time operations")
117 {}
118 
119 void
121 {}
122 
124 {
125  // Test Multiplication
126  constexpr long long oneSec = 1000000000; // conversion to default nanoseconds
127 
128  // Time in seconds
129  ns3::Time t1 = Time (125LL * oneSec);
130  ns3::Time t2 = Time (2000LL * oneSec);
131 
132  std::cout << "Testing Time Subtraction \n";
133 
134  NS_TEST_ASSERT_MSG_EQ ( (t2 - t1).GetSeconds (), 1875, "Time Subtraction");
135 
136  // Test Multiplication Operations:
137  std::cout << "Testing Time Multiplication \n";
138 
141 
142  // Test Division Operations:
143  std::cout << "Testing Time Division \n";
144 
147 
148  std::cout << "Testing modulo division \n";
149 
150  t1 = Time (101LL * oneSec);
151  NS_TEST_ASSERT_MSG_EQ ( (t2 % t1).GetSeconds (), 81, "Remainder Operation (2000 % 101 = 81)" );
152  NS_TEST_ASSERT_MSG_EQ ( Div (t2,t1), 19, "Modular Divison");
153  NS_TEST_ASSERT_MSG_EQ ( Rem (t2,t1).GetSeconds (), 81, "Remainder Operation (2000 % 101 = 81)" );
154 
155 }
156 
157 void
159 {
160  NS_TEST_ASSERT_MSG_EQ_TOL (Years (1.0).GetYears (), 1.0, Years (1).GetYears (),
161  "is 1 really 1 ?");
162  NS_TEST_ASSERT_MSG_EQ_TOL (Years (10.0).GetYears (), 10.0, Years (1).GetYears (),
163  "is 10 really 10 ?");
164  NS_TEST_ASSERT_MSG_EQ_TOL (Days (1.0).GetDays (), 1.0, Days (1).GetDays (),
165  "is 1 really 1 ?");
166  NS_TEST_ASSERT_MSG_EQ_TOL (Days (10.0).GetDays (), 10.0, Days (1).GetDays (),
167  "is 10 really 10 ?");
168  NS_TEST_ASSERT_MSG_EQ_TOL (Hours (1.0).GetHours (), 1.0, Hours (1).GetHours (),
169  "is 1 really 1 ?");
170  NS_TEST_ASSERT_MSG_EQ_TOL (Hours (10.0).GetHours (), 10.0, Hours (1).GetHours (),
171  "is 10 really 10 ?");
172  NS_TEST_ASSERT_MSG_EQ_TOL (Minutes (1.0).GetMinutes (), 1.0, Minutes (1).GetMinutes (),
173  "is 1 really 1 ?");
174  NS_TEST_ASSERT_MSG_EQ_TOL (Minutes (10.0).GetMinutes (), 10.0, Minutes (1).GetMinutes (),
175  "is 10 really 10 ?");
176  NS_TEST_ASSERT_MSG_EQ_TOL (Seconds (1.0).GetSeconds (), 1.0, TimeStep (1).GetSeconds (),
177  "is 1 really 1 ?");
178  NS_TEST_ASSERT_MSG_EQ_TOL (Seconds (10.0).GetSeconds (), 10.0, TimeStep (1).GetSeconds (),
179  "is 10 really 10 ?");
180  NS_TEST_ASSERT_MSG_EQ (MilliSeconds (1).GetMilliSeconds (), 1,
181  "is 1ms really 1ms ?");
182  NS_TEST_ASSERT_MSG_EQ (MicroSeconds (1).GetMicroSeconds (), 1,
183  "is 1us really 1us ?");
184 
185  DoTimeOperations ();
186 
187 #if 0
188  Time ns = NanoSeconds (1);
189  ns.GetNanoSeconds ();
190  NS_TEST_ASSERT_MSG_EQ (NanoSeconds (1).GetNanoSeconds (), 1,
191  "is 1ns really 1ns ?");
192  NS_TEST_ASSERT_MSG_EQ (PicoSeconds (1).GetPicoSeconds (), 1,
193  "is 1ps really 1ps ?");
194  NS_TEST_ASSERT_MSG_EQ (FemtoSeconds (1).GetFemtoSeconds (), 1,
195  "is 1fs really 1fs ?");
196 #endif
197 
198  Time ten = NanoSeconds (10);
199  int64_t tenValue = ten.GetInteger ();
200  Time::SetResolution (Time::PS);
201  int64_t tenKValue = ten.GetInteger ();
202  NS_TEST_ASSERT_MSG_EQ (tenValue * 1000, tenKValue,
203  "change resolution to PS");
204 }
205 
206 void
208 {}
209 
210 template<typename T>
211 void
213  const std::string& msg)
214 
215 {
216  using TestEntry = std::tuple<Time, std::string>;
217  std::array<TestEntry, 2> TESTS{
218  std::make_tuple (t * val, "Test Time * value: "),
219  std::make_tuple (val * t, "Test Time * value: ")
220  };
221 
222  for (auto test: TESTS )
223  {
224  std::string errMsg = std::get<1> (test) + msg;
225 
226  NS_TEST_ASSERT_MSG_EQ (std::get<0> (test), expected, errMsg);
227  }
228 }
229 
230 void
232 {
233  int sec = 125;
234  int scale = 100;
235 
236  Time t = Seconds (sec);
237  Time expected = Time (t.GetTimeStep () * scale);
238 
239  TestMultiplication (t, expected, static_cast<char> (scale), "Multiplication by char");
240  TestMultiplication (t, expected, static_cast<unsigned char> (scale),
241  "Multiplication by unsigned char");
242  TestMultiplication (t, expected, static_cast<short> (scale), "Multiplication by short");
243  TestMultiplication (t, expected, static_cast<unsigned short> (scale),
244  "Multiplication by unsigned short");
245  TestMultiplication (t, expected, static_cast<int> (scale), "Multiplication by int");
246  TestMultiplication (t, expected, static_cast<unsigned int> (scale),
247  "Multiplication by unsigned int");
248  TestMultiplication (t, expected, static_cast<long> (scale), "Multiplication by long");
249  TestMultiplication (t, expected, static_cast<unsigned long> (scale),
250  "Multiplication by unsigned long");
251  TestMultiplication (t, expected, static_cast<long long> (scale),
252  "Multiplication by long long");
253  TestMultiplication (t, expected, static_cast<unsigned long long> (scale),
254  "Multiplication by unsigned long long");
255  TestMultiplication (t, expected, static_cast<std::size_t> (scale),
256  "Multiplication by size_t");
257 
258  int64x64_t scale64 = 100;
259  TestMultiplication (t, expected, scale64, "Multiplication by int64x64_t");
260 }
261 
262 void
264 {
265  float sec = 150.0;
266  float scale = 100.2;
267 
268  Time t = Seconds (sec);
269  Time expected = Time (t.GetDouble () * scale);
270 
271  TestMultiplication (t, expected, scale, "Multiplication by float");
272  TestMultiplication (t, expected, static_cast<double> (scale),
273  "Multiplication by double");
274 }
275 
276 template<typename T>
277 void
278 TimeSimpleTestCase::TestDivision (Time t, Time expected, T val, const std::string& msg)
279 {
280  Time result = t / val;
281 
282  NS_TEST_ASSERT_MSG_EQ (result, expected, msg);
283 }
284 
285 void
287 {
288  int sec = 2000;
289  int scale = 100;
290 
291  Time t = Seconds (sec);
292  Time expected = Time (t.GetTimeStep () / scale);
293 
294  TestDivision (t, expected, static_cast<char> (scale), "Division by char");
295  TestDivision (t, expected, static_cast<unsigned char> (scale),
296  "Division by unsigned char");
297  TestDivision (t, expected, static_cast<short> (scale), "Division by short");
298  TestDivision (t, expected, static_cast<unsigned short> (scale),
299  "Division by unsigned short");
300  TestDivision (t, expected, static_cast<int> (scale), "Division by int");
301  TestDivision (t, expected, static_cast<unsigned int> (scale),
302  "Division by unsigned int");
303  TestDivision (t, expected, static_cast<long> (scale), "Division by long");
304  TestDivision (t, expected, static_cast<unsigned long> (scale),
305  "Division by unsigned long");
306  TestDivision (t, expected, static_cast<long long> (scale),
307  "Division by long long");
308  TestDivision (t, expected, static_cast<unsigned long long> (scale),
309  "Division by unsigned long long");
310  TestDivision (t, expected, static_cast<std::size_t> (scale),
311  "Division by size_t");
312 
313  int64x64_t scale64 = 100;
314  TestDivision (t, expected, scale64, "Division by int64x64_t");
315 }
316 
317 void
319 {
320  float sec = 200.0;
321  float scale = 0.2;
322 
323  Time t = Seconds (sec);
324  Time expected = t / int64x64_t (scale);
325 
326  TestDivision (t, expected, scale, "Division by float");
327  TestDivision (t, expected, static_cast<double> (scale),
328  "Division by double");
329 }
330 
331 
337 {
338 public:
343 
344 private:
348  virtual void DoSetup (void);
349 
353  virtual void DoRun (void);
354 
358  virtual void DoTeardown (void);
359 };
360 
362  : TestCase ("Checks times that have plus or minus signs")
363 {}
364 
365 void
367 {}
368 
369 void
371 {
372  Time timePositive ("+1000.0");
373  Time timePositiveWithUnits ("+1000.0ms");
374 
375  Time timeNegative ("-1000.0");
376  Time timeNegativeWithUnits ("-1000.0ms");
377 
378  NS_TEST_ASSERT_MSG_EQ_TOL (timePositive.GetSeconds (),
379  +1000.0,
380  1.0e-8,
381  "Positive time not parsed correctly.");
382 
383  NS_TEST_ASSERT_MSG_EQ_TOL (timePositiveWithUnits.GetSeconds (),
384  +1.0,
385  1.0e-8,
386  "Positive time with units not parsed correctly.");
387 
388  NS_TEST_ASSERT_MSG_EQ_TOL (timeNegative.GetSeconds (),
389  -1000.0,
390  1.0e-8,
391  "Negative time not parsed correctly.");
392 
393  NS_TEST_ASSERT_MSG_EQ_TOL (timeNegativeWithUnits.GetSeconds (),
394  -1.0,
395  1.0e-8,
396  "Negative time with units not parsed correctly.");
397 }
398 
399 
400 void
402 {}
403 
409 {
410 public:
415 
416 private:
420  virtual void DoRun (void);
425  void Check (const std::string & str);
426 
432  void CheckAs (const Time t, const std::string expect);
433 };
434 
436  : TestCase ("Input,output from,to strings")
437 {}
438 
439 void
440 TimeInputOutputTestCase::Check (const std::string & str)
441 {
442  std::stringstream ss (str);
443  Time time;
444  ss >> time;
445  ss << time;
446  bool pass = (str == ss.str ());
447 
448  std::cout << GetParent ()->GetName () << " InputOutput: "
449  << (pass ? "pass " : "FAIL ")
450  << "\"" << str << "\"";
451  if (!pass)
452  {
453  std::cout << ", got " << ss.str ();
454  }
455  std::cout << std::endl;
456  NS_TEST_EXPECT_MSG_EQ (ss.str (), str, "round trip conversion from/to string");
457 }
458 
459 void
460 TimeInputOutputTestCase::CheckAs (const Time t, const std::string expect)
461 {
462  std::stringstream ss;
463  ss << std::fixed << std::setprecision (6) << t.As ();
464  std::string str;
465  ss >> str;
466  bool pass = (str == expect);
467 
468  std::cout << GetParent ()->GetName () << " InputOutput:As: "
469  << (pass ? "pass " : "FAIL ")
470  << "\"" << expect << "\"";
471  if (!pass)
472  {
473  std::cout << ", got " << str;
474  }
475  std::cout << std::endl;
476  NS_TEST_EXPECT_MSG_EQ (str, expect, "Time::As() autoscaling");
477 
478 }
479 
480 void
482 {
483  std::cout << std::endl;
484  std::cout << GetParent ()->GetName () << " InputOutput: " << GetName ()
485  << std::endl;
486 
487  Check ("2ns");
488  Check ("+3.1us");
489  Check ("-4.2ms");
490  Check ("5.3s");
491  Check ("6.4min");
492  Check ("7.5h");
493  Check ("8.6d");
494  Check ("10.8y");
495 
496  Time t (3.141592654e9); // Pi seconds
497 
498  std::cout << GetParent ()->GetName () << " InputOutput: "
499  << "example: raw: " << t
500  << std::endl;
501 
502  std::cout << GetParent ()->GetName () << " InputOutput: "
503  << std::fixed << std::setprecision (9)
504  << "example: in s: " << t.As (Time::S)
505  << std::endl;
506 
507  std::cout << GetParent ()->GetName () << " InputOutput: "
508  << std::setprecision (6)
509  << "example: in ms: " << t.As (Time::MS)
510  << std::endl;
511 
512  std::cout << GetParent ()->GetName () << " InputOutput: "
513  << "example: Get ns: " << t.GetNanoSeconds ()
514  << std::endl;
515 
516  std::cout << GetParent ()->GetName () << " InputOutput: "
517  << "example: auto scale: \n";
518  CheckAs (t * 1e-9, "+3.000000ns");
519  CheckAs (t * 1e-8, "+31.000000ns");
520  CheckAs (t * 1e-7, "+314.000000ns");
521  CheckAs (t * 1e-6, "+3.142000us");
522  CheckAs (t * 1e-5, "+31.416000us");
523  CheckAs (t * 1e-4, "+314.159000us");
524  CheckAs (t * 1e-3, "+3.141593ms");
525  CheckAs (t * 1e-2, "+31.415927ms");
526  CheckAs (t * 1e-1, "+314.159265ms");
527  CheckAs (t * 1e-0, "+3.141593s");
528  CheckAs (t * 1e+1, "+31.415927s");
529  CheckAs (t * 1e+2, "+5.235988min");
530  CheckAs (t * 1e+3, "+52.359878min");
531  CheckAs (t * 1e+4, "+8.726646h");
532  CheckAs (t * 1e+5, "+3.636103d");
533  CheckAs (t * 1e+6, "+36.361026d");
534  CheckAs (t * 1e+7, "+363.610261d");
535  CheckAs (t * 1e+8, "+9.961925y");
536 }
537 
542 static class TimeTestSuite : public TestSuite
543 {
544 public:
546  : TestSuite ("time", UNIT)
547  {
548  AddTestCase (new TimeWithSignTestCase (), TestCase::QUICK);
549  AddTestCase (new TimeInputOutputTestCase (), TestCase::QUICK);
550  // This should be last, since it changes the resolution
551  AddTestCase (new TimeSimpleTestCase (), TestCase::QUICK);
552  }
553 }
virtual void DoRun(void)
DoRun for TimeInputOutputTestCase.
virtual void DoRun(void)
Runs the Simple Time test case.
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:429
TimeInputOutputTestCase()
Constructor for TimeInputOutputTestCase.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
TimeSimpleTestCase()
constructor for TimeSimpleTestCase.
int64_t GetInteger(void) const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:424
virtual void DoTeardown(void)
DoTeardown for TimeWithSignTestCase.
High precision numerical type, implementing Q64.64 fixed precision.
Definition: int64x64-128.h:45
A suite of tests to run.
Definition: test.h:1343
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380
void Check(const std::string &str)
Check roundtrip from/to string.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:283
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:813
encapsulates test code
Definition: test.h:1153
time-tests Time with Sign test case
void TestMultiplicationByIntegerTypes()
Test multiplying a Time instance by various integer types.
Time PicoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1321
virtual void DoRun(void)
DoRun for TimeWithSignTestCase.
Time Years(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1257
virtual void DoSetup(void)
setup function for TimeSimpleTestCase.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
virtual void DoSetup(void)
DoSetup for TimeWithSignTestCase.
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:166
void TestMultiplication(Time t, Time expected, T val, const std::string &msg)
Helper function to handle boilerplate code for multiplication tests.
Time Rem(const Time &lhs, const Time &rhs)
Remainder (modulus) from the quotient of two Times.
Definition: nstime.h:1149
TimeTestSuite g_timeTestSuite
Member variable for time test suite.
double GetDouble(void) const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:420
int64_t Div(const Length &numerator, const Length &denominator, Length *remainder)
This function provides a string parsing method that does not rely on istream, which has been found to...
Definition: length.cc:488
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition: test.h:378
Every class exported by the ns3 library is enclosed in the ns3 namespace.
int64_t GetNanoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:392
TestCase * GetParent() const
Get the parent of this TestCsse.
Definition: test.cc:376
Time Hours(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1273
Input output Test Case for Time.
void CheckAs(const Time t, const std::string expect)
Check autoscaling output using Time::As()
Time Minutes(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1281
void TestDivisionByDecimalTypes()
Test dividing a Time instance by various decimal types.
void TestDivisionByIntegerTypes()
Test dividing a Time instance by various integer types.
std::string GetName(void) const
Definition: test.cc:370
virtual void DoTeardown(void)
Does the tear down for TimeSimpleTestCase.
void TestMultiplicationByDecimalTypes()
Test multiplying a Time instance by various decimal types.
void TestDivision(Time t, Time expected, T val, const std::string &msg)
Helper function to handle boilerplate code for division tests.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
Time Days(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1265
Time FemtoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1329
This test suite implements a Unit Test.
Definition: test.h:1353
TimeWithSignTestCase()
constructor for TimeWithSignTestCase.
Time test Suite.
virtual void DoTimeOperations(void)
Tests the Time Operations.
time simple test case, Checks the basic operations on time
int64_t GetTimeStep(void) const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:416