A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
time-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006 INRIA
3 * Copyright (c) 2007 Emmanuelle Laprise
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19 * TimeStep support by Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
20 */
21
22#include "ns3/int64x64.h"
23#include "ns3/nstime.h"
24#include "ns3/test.h"
25
26#include <array>
27#include <iomanip>
28#include <iostream>
29#include <sstream>
30#include <string>
31#include <tuple>
32
33using namespace ns3;
34
35/**
36 * \ingroup core-tests
37 * \brief time simple test case, Checks the basic operations on time
38 */
40{
41 public:
42 /**
43 * \brief constructor for TimeSimpleTestCase.
44 */
46
47 private:
48 /**
49 * \brief setup function for TimeSimpleTestCase.
50 */
51 void DoSetup() override;
52
53 /**
54 * \brief Runs the Simple Time test case.
55 */
56 void DoRun() override;
57
58 /**
59 * \brief Tests the Time Operations.
60 */
61 virtual void DoTimeOperations();
62
63 /**
64 * \brief Does the tear down for TimeSimpleTestCase.
65 */
66 void DoTeardown() override;
67
68 /**
69 * Helper function to handle boilerplate code for multiplication tests
70 *
71 * \tparam T type of multiplication value
72 *
73 * \param t Time value to multiply
74 * \param expected Expected result of the multiplication
75 * \param val Value to multiply by
76 * \param msg Error message to print if test fails
77 */
78 template <typename T>
79 void TestMultiplication(Time t, Time expected, T val, const std::string& msg);
80
81 /**
82 * Test multiplying a Time instance by various integer types
83 */
85
86 /**
87 * Test multiplying a Time instance by various decimal types
88 */
90
91 /**
92 * Helper function to handle boilerplate code for division tests
93 *
94 * \tparam T type of division value
95 *
96 * \param t Time value to divide
97 * \param expected Expected result of the division
98 * \param val Value to divide by
99 * \param msg Error message to print if test fails
100 */
101 template <typename T>
102 void TestDivision(Time t, Time expected, T val, const std::string& msg);
103
104 /**
105 * Test dividing a Time instance by various integer types
106 */
108
109 /**
110 * Test dividing a Time instance by various decimal types
111 */
113};
114
116 : TestCase("Sanity check of common time operations")
117{
118}
119
120void
122{
123}
124
125void
127{
128 // Test Multiplication
129 constexpr long long oneSec = 1000000000; // conversion to default nanoseconds
130
131 // Time in seconds
132 ns3::Time t1 = Time(125LL * oneSec);
133 ns3::Time t2 = Time(2000LL * oneSec);
134
135 std::cout << "Testing Time Subtraction \n";
136
137 NS_TEST_ASSERT_MSG_EQ((t2 - t1).GetSeconds(), 1875, "Time Subtraction");
138
139 // Test Multiplication Operations:
140 std::cout << "Testing Time Multiplication \n";
141
144
145 // Test Division Operations:
146 std::cout << "Testing Time Division \n";
147
150
151 std::cout << "Testing modulo division \n";
152
153 t1 = Time(101LL * oneSec);
154 NS_TEST_ASSERT_MSG_EQ((t2 % t1).GetSeconds(), 81, "Remainder Operation (2000 % 101 = 81)");
155 NS_TEST_ASSERT_MSG_EQ(Div(t2, t1), 19, "Modular Division");
156 NS_TEST_ASSERT_MSG_EQ(Rem(t2, t1).GetSeconds(), 81, "Remainder Operation (2000 % 101 = 81)");
157}
158
159void
161{
162 NS_TEST_ASSERT_MSG_EQ_TOL(Years(1.0).GetYears(), 1.0, Years(1).GetYears(), "is 1 really 1 ?");
163 NS_TEST_ASSERT_MSG_EQ_TOL(Years(10.0).GetYears(),
164 10.0,
165 Years(1).GetYears(),
166 "is 10 really 10 ?");
167 NS_TEST_ASSERT_MSG_EQ_TOL(Days(1.0).GetDays(), 1.0, Days(1).GetDays(), "is 1 really 1 ?");
168 NS_TEST_ASSERT_MSG_EQ_TOL(Days(10.0).GetDays(), 10.0, Days(1).GetDays(), "is 10 really 10 ?");
169 NS_TEST_ASSERT_MSG_EQ_TOL(Hours(1.0).GetHours(), 1.0, Hours(1).GetHours(), "is 1 really 1 ?");
170 NS_TEST_ASSERT_MSG_EQ_TOL(Hours(10.0).GetHours(),
171 10.0,
172 Hours(1).GetHours(),
173 "is 10 really 10 ?");
174 NS_TEST_ASSERT_MSG_EQ_TOL(Minutes(1.0).GetMinutes(),
175 1.0,
176 Minutes(1).GetMinutes(),
177 "is 1 really 1 ?");
178 NS_TEST_ASSERT_MSG_EQ_TOL(Minutes(10.0).GetMinutes(),
179 10.0,
180 Minutes(1).GetMinutes(),
181 "is 10 really 10 ?");
182 NS_TEST_ASSERT_MSG_EQ_TOL(Seconds(1.0).GetSeconds(),
183 1.0,
184 TimeStep(1).GetSeconds(),
185 "is 1 really 1 ?");
186 NS_TEST_ASSERT_MSG_EQ_TOL(Seconds(10.0).GetSeconds(),
187 10.0,
188 TimeStep(1).GetSeconds(),
189 "is 10 really 10 ?");
190 NS_TEST_ASSERT_MSG_EQ(MilliSeconds(1).GetMilliSeconds(), 1, "is 1ms really 1ms ?");
191 NS_TEST_ASSERT_MSG_EQ(MicroSeconds(1).GetMicroSeconds(), 1, "is 1us really 1us ?");
192
194
195#if 0
196 Time ns = NanoSeconds (1);
197 ns.GetNanoSeconds ();
198 NS_TEST_ASSERT_MSG_EQ (NanoSeconds (1).GetNanoSeconds (), 1,
199 "is 1ns really 1ns ?");
200 NS_TEST_ASSERT_MSG_EQ (PicoSeconds (1).GetPicoSeconds (), 1,
201 "is 1ps really 1ps ?");
202 NS_TEST_ASSERT_MSG_EQ (FemtoSeconds (1).GetFemtoSeconds (), 1,
203 "is 1fs really 1fs ?");
204#endif
205
206 Time ten = NanoSeconds(10);
207 int64_t tenValue = ten.GetInteger();
209 int64_t tenKValue = ten.GetInteger();
210 NS_TEST_ASSERT_MSG_EQ(tenValue * 1000, tenKValue, "change resolution to PS");
211}
212
213void
215{
216}
217
218template <typename T>
219void
220TimeSimpleTestCase::TestMultiplication(Time t, Time expected, T val, const std::string& msg)
221
222{
223 using TestEntry = std::tuple<Time, std::string>;
224 std::array<TestEntry, 2> TESTS{std::make_tuple(t * val, "Test Time * value: "),
225 std::make_tuple(val * t, "Test Time * value: ")};
226
227 for (auto test : TESTS)
228 {
229 std::string errMsg = std::get<1>(test) + msg;
230
231 NS_TEST_ASSERT_MSG_EQ(std::get<0>(test), expected, errMsg);
232 }
233}
234
235void
237{
238 int sec = 125;
239 int scale = 100;
240
241 Time t = Seconds(sec);
242 Time expected = Time(t.GetTimeStep() * scale);
243
244 TestMultiplication(t, expected, static_cast<char>(scale), "Multiplication by char");
246 expected,
247 static_cast<unsigned char>(scale),
248 "Multiplication by unsigned char");
249 TestMultiplication(t, expected, static_cast<short>(scale), "Multiplication by short");
251 expected,
252 static_cast<unsigned short>(scale),
253 "Multiplication by unsigned short");
254 TestMultiplication(t, expected, static_cast<int>(scale), "Multiplication by int");
256 expected,
257 static_cast<unsigned int>(scale),
258 "Multiplication by unsigned int");
259 TestMultiplication(t, expected, static_cast<long>(scale), "Multiplication by long");
261 expected,
262 static_cast<unsigned long>(scale),
263 "Multiplication by unsigned long");
264 TestMultiplication(t, expected, static_cast<long long>(scale), "Multiplication by long long");
266 expected,
267 static_cast<unsigned long long>(scale),
268 "Multiplication by unsigned long long");
269 TestMultiplication(t, expected, static_cast<std::size_t>(scale), "Multiplication by size_t");
270
271 int64x64_t scale64 = 100;
272 TestMultiplication(t, expected, scale64, "Multiplication by int64x64_t");
273}
274
275void
277{
278 float sec = 150.0;
279 float scale = 100.2;
280
281 Time t = Seconds(sec);
282 Time expected = Time(t.GetDouble() * scale);
283
284 TestMultiplication(t, expected, scale, "Multiplication by float");
285 TestMultiplication(t, expected, static_cast<double>(scale), "Multiplication by double");
286}
287
288template <typename T>
289void
290TimeSimpleTestCase::TestDivision(Time t, Time expected, T val, const std::string& msg)
291{
292 Time result = t / val;
293
294 NS_TEST_ASSERT_MSG_EQ(result, expected, msg);
295}
296
297void
299{
300 int sec = 2000;
301 int scale = 100;
302
303 Time t = Seconds(sec);
304 Time expected = Time(t.GetTimeStep() / scale);
305
306 TestDivision(t, expected, static_cast<char>(scale), "Division by char");
307 TestDivision(t, expected, static_cast<unsigned char>(scale), "Division by unsigned char");
308 TestDivision(t, expected, static_cast<short>(scale), "Division by short");
309 TestDivision(t, expected, static_cast<unsigned short>(scale), "Division by unsigned short");
310 TestDivision(t, expected, static_cast<int>(scale), "Division by int");
311 TestDivision(t, expected, static_cast<unsigned int>(scale), "Division by unsigned int");
312 TestDivision(t, expected, static_cast<long>(scale), "Division by long");
313 TestDivision(t, expected, static_cast<unsigned long>(scale), "Division by unsigned long");
314 TestDivision(t, expected, static_cast<long long>(scale), "Division by long long");
315 TestDivision(t,
316 expected,
317 static_cast<unsigned long long>(scale),
318 "Division by unsigned long long");
319 TestDivision(t, expected, static_cast<std::size_t>(scale), "Division by size_t");
320
321 int64x64_t scale64 = 100;
322 TestDivision(t, expected, scale64, "Division by int64x64_t");
323}
324
325void
327{
328 float sec = 200.0;
329 float scale = 0.2;
330
331 Time t = Seconds(sec);
332 Time expected = t / int64x64_t(scale);
333
334 TestDivision(t, expected, scale, "Division by float");
335 TestDivision(t, expected, static_cast<double>(scale), "Division by double");
336}
337
338/**
339 * \ingroup core-tests
340 * \brief time-tests Time with Sign test case
341 */
343{
344 public:
345 /**
346 * \brief constructor for TimeWithSignTestCase.
347 */
349
350 private:
351 /**
352 * \brief DoSetup for TimeWithSignTestCase.
353 */
354 void DoSetup() override;
355
356 /**
357 * \brief DoRun for TimeWithSignTestCase.
358 */
359 void DoRun() override;
360
361 /**
362 * \brief DoTeardown for TimeWithSignTestCase.
363 */
364 void DoTeardown() override;
365};
366
368 : TestCase("Checks times that have plus or minus signs")
369{
370}
371
372void
374{
375}
376
377void
379{
380 Time timePositive("+1000.0");
381 Time timePositiveWithUnits("+1000.0ms");
382
383 Time timeNegative("-1000.0");
384 Time timeNegativeWithUnits("-1000.0ms");
385
387 +1000.0,
388 1.0e-8,
389 "Positive time not parsed correctly.");
390
391 NS_TEST_ASSERT_MSG_EQ_TOL(timePositiveWithUnits.GetSeconds(),
392 +1.0,
393 1.0e-8,
394 "Positive time with units not parsed correctly.");
395
397 -1000.0,
398 1.0e-8,
399 "Negative time not parsed correctly.");
400
401 NS_TEST_ASSERT_MSG_EQ_TOL(timeNegativeWithUnits.GetSeconds(),
402 -1.0,
403 1.0e-8,
404 "Negative time with units not parsed correctly.");
405}
406
407void
409{
410}
411
412/**
413 * \ingroup core-tests
414 * \brief Input output Test Case for Time
415 */
417{
418 public:
419 /**
420 * \brief Constructor for TimeInputOutputTestCase.
421 */
423
424 private:
425 /**
426 * \brief DoRun for TimeInputOutputTestCase.
427 */
428 void DoRun() override;
429 /**
430 * \brief Check roundtrip from/to string.
431 * \param str Time input check.
432 */
433 void Check(const std::string& str);
434
435 /**
436 * \brief Check autoscaling output using Time::As()
437 * \param t Time instance.
438 * \param expect Expected string output with Time::As() autoscaling.
439 */
440 void CheckAs(const Time t, const std::string expect);
441};
442
444 : TestCase("Input,output from,to strings")
445{
446}
447
448void
449TimeInputOutputTestCase::Check(const std::string& str)
450{
451 std::stringstream ss(str);
452 Time time;
453 ss >> time;
454 ss << time;
455 bool pass = (str == ss.str());
456
457 std::cout << GetParent()->GetName() << " InputOutput: " << (pass ? "pass " : "FAIL ") << "\""
458 << str << "\"";
459 if (!pass)
460 {
461 std::cout << ", got " << ss.str();
462 }
463 std::cout << std::endl;
464 NS_TEST_EXPECT_MSG_EQ(ss.str(), str, "round trip conversion from/to string");
465}
466
467void
468TimeInputOutputTestCase::CheckAs(const Time t, const std::string expect)
469{
470 std::stringstream ss;
471 ss << std::fixed << std::setprecision(6) << t.As();
472 std::string str;
473 ss >> str;
474 bool pass = (str == expect);
475
476 std::cout << GetParent()->GetName() << " InputOutput:As: " << (pass ? "pass " : "FAIL ") << "\""
477 << expect << "\"";
478 if (!pass)
479 {
480 std::cout << ", got " << str;
481 }
482 std::cout << std::endl;
483 NS_TEST_EXPECT_MSG_EQ(str, expect, "Time::As() autoscaling");
484}
485
486void
488{
489 std::cout << std::endl;
490 std::cout << GetParent()->GetName() << " InputOutput: " << GetName() << std::endl;
491
492 Check("2ns");
493 Check("+3.1us");
494 Check("-4.2ms");
495 Check("5.3s");
496 Check("6.4min");
497 Check("7.5h");
498 Check("8.6d");
499 Check("10.8y");
500
501 Time t(3.141592654e9); // Pi seconds
502
503 std::cout << GetParent()->GetName() << " InputOutput: "
504 << "example: raw: " << t << std::endl;
505
506 std::cout << GetParent()->GetName() << " InputOutput: " << std::fixed << std::setprecision(9)
507 << "example: in s: " << t.As(Time::S) << std::endl;
508
509 std::cout << GetParent()->GetName() << " InputOutput: " << std::setprecision(6)
510 << "example: in ms: " << t.As(Time::MS) << std::endl;
511
512 std::cout << GetParent()->GetName() << " InputOutput: "
513 << "example: Get ns: " << t.GetNanoSeconds() << std::endl;
514
515 std::cout << GetParent()->GetName() << " InputOutput: "
516 << "example: auto scale: \n";
517 CheckAs(t * 1e-9, "+3.000000ns");
518 CheckAs(t * 1e-8, "+31.000000ns");
519 CheckAs(t * 1e-7, "+314.000000ns");
520 CheckAs(t * 1e-6, "+3.142000us");
521 CheckAs(t * 1e-5, "+31.416000us");
522 CheckAs(t * 1e-4, "+314.159000us");
523 CheckAs(t * 1e-3, "+3.141593ms");
524 CheckAs(t * 1e-2, "+31.415927ms");
525 CheckAs(t * 1e-1, "+314.159265ms");
526 CheckAs(t * 1e-0, "+3.141593s");
527 CheckAs(t * 1e+1, "+31.415927s");
528 CheckAs(t * 1e+2, "+5.235988min");
529 CheckAs(t * 1e+3, "+52.359878min");
530 CheckAs(t * 1e+4, "+8.726646h");
531 CheckAs(t * 1e+5, "+3.636103d");
532 CheckAs(t * 1e+6, "+36.361026d");
533 CheckAs(t * 1e+7, "+363.610261d");
534 CheckAs(t * 1e+8, "+9.961925y");
535}
536
537/**
538 * \ingroup core-tests
539 * \brief Time test Suite. Runs the appropriate test cases for time
540 */
541static class TimeTestSuite : public TestSuite
542{
543 public:
545 : TestSuite("time", Type::UNIT)
546 {
547 AddTestCase(new TimeWithSignTestCase(), TestCase::Duration::QUICK);
548 AddTestCase(new TimeInputOutputTestCase(), TestCase::Duration::QUICK);
549 // This should be last, since it changes the resolution
550 AddTestCase(new TimeSimpleTestCase(), TestCase::Duration::QUICK);
551 }
552}
553/** \brief Member variable for time test suite */
Input output Test Case for Time.
TimeInputOutputTestCase()
Constructor for TimeInputOutputTestCase.
void DoRun() override
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 DoTeardown() override
Does the tear down for TimeSimpleTestCase.
virtual void DoTimeOperations()
Tests the Time Operations.
void DoSetup() override
setup function for TimeSimpleTestCase.
void TestMultiplicationByDecimalTypes()
Test multiplying a Time instance by various decimal types.
void TestMultiplicationByIntegerTypes()
Test multiplying a Time instance by various integer types.
TimeSimpleTestCase()
constructor for TimeSimpleTestCase.
void DoRun() override
Runs the Simple Time test case.
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.
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
void DoTeardown() override
DoTeardown for TimeWithSignTestCase.
void DoSetup() override
DoSetup for TimeWithSignTestCase.
void DoRun() override
DoRun for TimeWithSignTestCase.
TimeWithSignTestCase()
constructor for TimeWithSignTestCase.
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
TestCase * GetParent() const
Get the parent of this TestCase.
Definition: test.cc:380
std::string GetName() const
Definition: test.cc:373
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
static constexpr auto UNIT
Definition: test.h:1286
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetNanoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:418
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
int64_t GetInteger() const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:455
@ PS
picosecond
Definition: nstime.h:120
@ MS
millisecond
Definition: nstime.h:117
@ S
second
Definition: nstime.h:116
static void SetResolution(Unit resolution)
Definition: time.cc:213
double GetDouble() const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:450
int64_t GetTimeStep() const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:445
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:482
#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:145
#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:252
#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:338
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1362
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time Days(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1290
Time Hours(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1302
Time PicoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1374
Time FemtoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1386
Time Minutes(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1314
Time Years(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1278
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
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:1133
-ns3 Test suite for the ns3 wrapper script