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
34using namespace ns3;
40{
41public:
46
47private:
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
85
90
101 template<typename T>
102 void TestDivision(Time t, Time expected, T val, const std::string& msg);
103
108
113};
114
116 : TestCase ("Sanity check of common time operations")
117{}
118
119void
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
157void
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
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
206void
208{}
209
210template<typename T>
211void
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
230void
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
262void
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
276template<typename T>
277void
278TimeSimpleTestCase::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
285void
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
317void
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{
338public:
343
344private:
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
365void
367{}
368
369void
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
400void
402{}
403
409{
410public:
415
416private:
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
439void
440TimeInputOutputTestCase::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
459void
460TimeInputOutputTestCase::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
480void
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
542static class TimeTestSuite : public TestSuite
543{
544public:
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:432
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.
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:483
#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