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 }
Input output Test Case for Time.
TimeInputOutputTestCase()
Constructor for TimeInputOutputTestCase.
virtual void DoRun(void)
DoRun for TimeInputOutputTestCase.
void CheckAs(const Time t, const std::string expect)
Check autoscaling output using Time::As()
void Check(const std::string &str)
Check roundtrip from/to string.
time simple test case, Checks the basic operations on time
void TestMultiplicationByDecimalTypes()
Test multiplying a Time instance by various decimal types.
void TestMultiplicationByIntegerTypes()
Test multiplying a Time instance by various integer types.
virtual void DoRun(void)
Runs the Simple Time test case.
virtual void DoSetup(void)
setup function for TimeSimpleTestCase.
TimeSimpleTestCase()
constructor for TimeSimpleTestCase.
virtual void DoTeardown(void)
Does the tear down for TimeSimpleTestCase.
void TestDivisionByIntegerTypes()
Test dividing a Time instance by various integer types.
void TestDivision(Time t, Time expected, T val, const std::string &msg)
Helper function to handle boilerplate code for division tests.
void TestDivisionByDecimalTypes()
Test dividing a Time instance by various decimal types.
virtual void DoTimeOperations(void)
Tests the Time Operations.
void TestMultiplication(Time t, Time expected, T val, const std::string &msg)
Helper function to handle boilerplate code for multiplication tests.
Time test Suite.
time-tests Time with Sign test case
virtual void DoRun(void)
DoRun for TimeWithSignTestCase.
virtual void DoTeardown(void)
DoTeardown for TimeWithSignTestCase.
virtual void DoSetup(void)
DoSetup for TimeWithSignTestCase.
TimeWithSignTestCase()
constructor for TimeWithSignTestCase.
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
TestCase * GetParent() const
Get the parent of this TestCsse.
Definition: test.cc:376
std::string GetName(void) const
Definition: test.cc:370
A suite of tests to run.
Definition: test.h:1188
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1197
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
double GetDouble(void) const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:419
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
int64_t GetTimeStep(void) const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:415
int64_t GetInteger(void) const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:423
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:418
int64_t GetNanoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:391
High precision numerical type, implementing Q64.64 fixed precision.
Definition: int64x64-128.h:56
TimeTestSuite g_timeTestSuite
Member variable for time test suite.
int64_t Div(const Length &numerator, const Length &denominator, Length *remainder)
Calculate how many times numerator can be split into denominator sized pieces.
Definition: length.cc:474
#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:141
#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:240
#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:323
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1260
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1268
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time Days(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1220
Time Hours(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1228
Time PicoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1276
Time FemtoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1284
Time Minutes(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1236
Time Years(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1212
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:793
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Time Rem(const Time &lhs, const Time &rhs)
Remainder (modulus) from the quotient of two Times.
Definition: nstime.h:1078