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