Replace inet_aton() with inet_pton() to parse IPs correctly (#8825)
[libi2ncommon] / test / test_timefunc.cpp
... / ...
CommitLineData
1/*
2The software in this package is distributed under the GNU General
3Public License version 2 (with a special exception described below).
4
5A copy of GNU General Public License (GPL) is included in this distribution,
6in the file COPYING.GPL.
7
8As a special exception, if other files instantiate templates or use macros
9or inline functions from this file, or you compile this file and link it
10with other works to produce a work based on this file, this file
11does not by itself cause the resulting work to be covered
12by the GNU General Public License.
13
14However the source code for this file must still be made available
15in accordance with section (3) of the GNU General Public License.
16
17This exception does not invalidate any other reasons why a work based
18on this file might be covered by the GNU General Public License.
19*/
20/** @file
21 * @brief unit test for time related functions.
22 *
23 * @copyright Copyright © 2001-2008 by Intra2net AG
24 *
25 */
26#include <features.h>
27#if (__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 23)
28/*
29 * Ancient glibc (pre 2015) has a defective implementation of strptime(3)
30 * that doesn’t handle the ‘Z’ modifier of ISO8601 to indicate UTC. It also
31 * parses fractional timezones only partially so e. g. “+11:11” is treated
32 * as “+1100”.
33 */
34# define GLIBC_STRPTIME_LACKS_Z
35#endif
36
37#define BOOST_TEST_DYN_LINK
38#include <time.h>
39#include <boost/test/unit_test.hpp>
40
41#include <timefunc.hxx>
42#include <filefunc.hxx>
43
44#include <unistd.h>
45#include <set>
46#include <iostream>
47#include <sstream>
48
49using namespace std;
50using namespace I2n;
51using namespace I2n::Time;
52
53class TestTimeFuncFixture
54{
55protected:
56 typedef std::list< std::string > StringList;
57 std::set<std::string> used_check_files;
58
59 struct {
60 std::string env; /* save and restore TZ from envp */
61 char *name[2];
62 long zone;
63 int dst;
64 } timezone;
65
66 std::string get_check_file_path(std::string tag)
67 {
68 std::string result;
69 result= "__unittest__" + tag + ".dat";
70 used_check_files.insert(result);
71 return result;
72 } // eo get_check_file_path
73
74 void dump_tz_info (void)
75 {
76 fprintf (stderr, "timezone: %s(%s) %ld, dst: %d\n",
77 tzname[0], tzname[1], ::timezone, daylight);
78 }
79
80 void remove_check_files()
81 {
82 for (std::set<std::string>::iterator it= used_check_files.begin();
83 it != used_check_files.end();
84 ++it)
85 {
86 std::string filepath(*it);
87 if (path_exists(filepath))
88 {
89 unlink(filepath);
90 }
91 //TODO
92 }
93 used_check_files.clear();
94 } // eo remove_check_files
95
96 void set_tz (const std::string &tzname)
97 {
98 errno = 0;
99 if (setenv ("TZ", tzname.c_str (), 1) == -1)
100 {
101 std::cerr
102 << "error setting environment 'TZ': [" << tzname << "]"
103 << std::endl
104 ;
105 return;
106 }
107
108 tzset ();
109 }
110
111 inline void set_utc (void)
112 {
113 this->set_tz ("UTC");
114 }
115
116 void set_dst (const bool dst=true)
117 {
118 daylight = dst ? 1 : 0;
119 tzset ();
120 }
121
122public:
123 TestTimeFuncFixture()
124 {
125 this->timezone.env = std::string (secure_getenv ("TZ") ?: "");
126 this->timezone.name[0] = tzname [0];
127 this->timezone.name[1] = tzname [1];
128 this->timezone.zone = ::timezone;
129 this->timezone.dst = daylight;
130 }
131
132 ~TestTimeFuncFixture()
133 {
134 remove_check_files();
135
136 /* time zone related cleanup */
137 daylight = this->timezone.dst;
138 ::timezone = this->timezone.zone;
139
140 tzname [0] = this->timezone.name[0];
141 tzname [1] = this->timezone.name[1];
142
143 errno = 0;
144 if (setenv ("TZ", this->timezone.env.c_str (), 1) == -1)
145 {
146 std::cerr
147 << "error cleaning up environment 'TZ': [" << this->timezone.env << "]"
148 << std::endl
149 ;
150 }
151
152 tzset();
153 }
154};
155
156BOOST_FIXTURE_TEST_SUITE(TestTimeFunc, TestTimeFuncFixture)
157
158BOOST_AUTO_TEST_CASE(AddIntervalsDisjoint)
159{
160 Intervals intervals;
161
162 intervals.add( Interval( 10, 100 ) );
163 intervals.add( Interval( 600, 620 ) );
164
165 BOOST_CHECK_EQUAL( false, intervals.empty() );
166 BOOST_CHECK_EQUAL( 2u, intervals.size() );
167
168 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
169 BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
170
171 BOOST_CHECK_EQUAL( 600u, intervals.back().lower_bound() );
172 BOOST_CHECK_EQUAL( 620u, intervals.back().upper_bound() );
173} // eo AddIntervalsDisjoint()
174
175
176
177BOOST_AUTO_TEST_CASE(AddIntervalsInclude)
178{
179 Intervals intervals;
180
181 intervals.add( Interval( 10, 100 ) );
182 intervals.add( Interval( 10, 80 ) );
183
184 BOOST_CHECK_EQUAL( false, intervals.empty() );
185 BOOST_CHECK_EQUAL( 1u, intervals.size() );
186
187 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
188 BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
189 BOOST_CHECK_EQUAL( false, intervals.front().changed() );
190} // eo AddIntervalsInclude()
191
192
193
194BOOST_AUTO_TEST_CASE(AddIntervalsEmbrace)
195{
196 Intervals intervals;
197
198 intervals.add( Interval( 10, 100 ) );
199 intervals.add( Interval( 5, 120 ) );
200
201 BOOST_CHECK_EQUAL( false, intervals.empty() );
202 BOOST_CHECK_EQUAL( 1u, intervals.size() );
203
204 BOOST_CHECK_EQUAL( 5u, intervals.front().lower_bound() );
205 BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() );
206 BOOST_CHECK_EQUAL( true, intervals.front().changed() );
207} // eo AddIntervalsEmbrace()
208
209
210
211BOOST_AUTO_TEST_CASE(AddIntervalsJoin1)
212{
213 Intervals intervals;
214
215 intervals.add( Interval( 10, 100 ) );
216 intervals.add( Interval( 60, 120 ) );
217
218 BOOST_CHECK_EQUAL( false, intervals.empty() );
219 BOOST_CHECK_EQUAL( 1u, intervals.size() );
220
221 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
222 BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() );
223 BOOST_CHECK_EQUAL( true, intervals.front().changed() );
224} // eo AddIntervalsJoin1()
225
226
227
228BOOST_AUTO_TEST_CASE(AddIntervalsJoin1b)
229{
230 Intervals intervals;
231
232 intervals.add( Interval( 10, 100 ) );
233 intervals.add( Interval( 100, 120 ) );
234
235 BOOST_CHECK_EQUAL( false, intervals.empty() );
236 BOOST_CHECK_EQUAL( 1u, intervals.size() );
237
238 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
239 BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() );
240 BOOST_CHECK_EQUAL( true, intervals.front().changed() );
241} // eo AddIntervalsJoin1b()
242
243
244
245BOOST_AUTO_TEST_CASE(AddIntervalsJoin2)
246{
247 Intervals intervals;
248
249 intervals.add( Interval( 10, 100 ) );
250 intervals.add( Interval( 200, 250 ) );
251
252 BOOST_CHECK_EQUAL( false, intervals.empty() );
253 BOOST_CHECK_EQUAL( 2u, intervals.size() );
254
255 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
256 BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
257 BOOST_CHECK_EQUAL( 200u, intervals.back().lower_bound() );
258 BOOST_CHECK_EQUAL( 250u, intervals.back().upper_bound() );
259
260 // now add the gap; the intervals should collapse to one covering all:
261 intervals.add( Interval(100, 200) );
262
263 BOOST_CHECK_EQUAL( false, intervals.empty() );
264 BOOST_CHECK_EQUAL( 1u, intervals.size() );
265
266 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
267 BOOST_CHECK_EQUAL( 250u, intervals.front().upper_bound() );
268 BOOST_CHECK_EQUAL( true, intervals.front().changed() );
269} // eo AddIntervalsJoin2()
270
271
272
273BOOST_AUTO_TEST_CASE(SubIntervalsDisjoint)
274{
275 Intervals intervals;
276
277 intervals.add( Interval(10, 100) );
278 intervals.sub( Interval(0, 10) );
279
280 BOOST_CHECK_EQUAL( false, intervals.empty() );
281 BOOST_CHECK_EQUAL( 1u, intervals.size() );
282
283 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
284 BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
285 BOOST_CHECK_EQUAL( false, intervals.front().changed() );
286} // eo SubIntervalsDisjoint()
287
288
289
290BOOST_AUTO_TEST_CASE(SubIntervalsExact)
291{
292 Intervals intervals;
293
294 intervals.add( Interval(10, 100) );
295 intervals.sub( Interval(10, 100) );
296
297 BOOST_CHECK_EQUAL( true, intervals.empty() );
298 BOOST_CHECK_EQUAL( 0u, intervals.size() );
299} // eo SubIntervalsExact()
300
301
302
303BOOST_AUTO_TEST_CASE(SubIntervalsSplit1)
304{
305 Intervals intervals;
306
307 intervals.add( Interval(10, 100) );
308 intervals.sub( Interval(20, 40) );
309
310 BOOST_CHECK_EQUAL( false, intervals.empty() );
311 BOOST_CHECK_EQUAL( 2u, intervals.size() );
312
313 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
314 BOOST_CHECK_EQUAL( 20u, intervals.front().upper_bound() );
315
316 BOOST_CHECK_EQUAL( 40u, intervals.back().lower_bound() );
317 BOOST_CHECK_EQUAL( 100u, intervals.back().upper_bound() );
318 BOOST_CHECK_EQUAL( false, intervals.front().changed() );
319 BOOST_CHECK_EQUAL( true, intervals.back().changed() );
320} // eo SubIntervalsSplit1()
321
322
323BOOST_AUTO_TEST_CASE(SubIntervalsCutFront)
324{
325 Intervals intervals;
326
327 intervals.add( Interval(10, 100) );
328 intervals.sub( Interval(10, 20) );
329
330 BOOST_CHECK_EQUAL( false, intervals.empty() );
331 BOOST_CHECK_EQUAL( 1u, intervals.size() );
332
333 BOOST_CHECK_EQUAL( 20u, intervals.front().lower_bound() );
334 BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
335 BOOST_CHECK_EQUAL( true, intervals.front().changed() );
336} // eo SubIntervalsCutFront()
337
338
339BOOST_AUTO_TEST_CASE(SubIntervalsCutBack)
340{
341 Intervals intervals;
342
343 intervals.add( Interval(10, 100) );
344 intervals.sub( Interval(87, 100) );
345
346 BOOST_CHECK_EQUAL( false, intervals.empty() );
347 BOOST_CHECK_EQUAL( 1u, intervals.size() );
348
349 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
350 BOOST_CHECK_EQUAL( 87u, intervals.front().upper_bound() );
351 BOOST_CHECK_EQUAL( true, intervals.front().changed() );
352} // eo SubIntervalsCutBack()
353
354
355
356BOOST_AUTO_TEST_CASE(SubIntervalsCutMore)
357{
358 Intervals intervals;
359
360 intervals.add( Interval( 10, 100) );
361 intervals.add( Interval(110, 200) );
362 intervals.add( Interval(210, 300) );
363
364 // this should remove the first 2 intervals and cut the third:
365 intervals.sub( Interval(8, 220) );
366
367 BOOST_CHECK_EQUAL( false, intervals.empty() );
368 BOOST_CHECK_EQUAL( 1u, intervals.size() );
369
370 BOOST_CHECK_EQUAL( 220u, intervals.front().lower_bound() );
371 BOOST_CHECK_EQUAL( 300u, intervals.front().upper_bound() );
372 BOOST_CHECK_EQUAL( true, intervals.front().changed() );
373} // eo SubIntervalsCutMore()
374
375
376BOOST_AUTO_TEST_CASE(IntervalComparisons)
377{
378 Intervals intervals1;
379 Intervals intervals2;
380
381 intervals1.add( Interval( 10, 120) );
382
383 intervals2.add( Interval( 10, 110 ) );
384 intervals2.add( Interval( 100, 120 ) );
385
386 BOOST_CHECK_EQUAL( 1u, intervals2.size() );
387
388 BOOST_CHECK( intervals1 == intervals2 );
389 BOOST_CHECK_EQUAL( true, intervals1.contains( intervals2 ));
390 BOOST_CHECK_EQUAL( true, intervals2.contains( intervals1 ));
391
392 intervals2.sub( Interval( 40, 50) );
393
394 BOOST_CHECK( intervals1 != intervals2 );
395 BOOST_CHECK_EQUAL( true, intervals1.contains( intervals2 ));
396 BOOST_CHECK_EQUAL( false, intervals2.contains( intervals1 ));
397} // eo IntervalComparisons()
398
399
400
401BOOST_AUTO_TEST_CASE(MonotonicClock)
402{
403 long sec0, nsec0;
404 long sec1, nsec1;
405
406 bool res = monotonic_clock_gettime(sec0,nsec0);
407 BOOST_CHECK_EQUAL( true, res );
408
409 usleep(250000);
410 res= monotonic_clock_gettime(sec1,nsec1);
411 BOOST_CHECK_EQUAL( true, res);
412
413 long delta_sec = sec1 - sec0;
414 long delta_nsec= nsec1 - nsec0;
415
416 long delta_millisec= ( delta_nsec / 1000000L) + delta_sec * 1000L;
417
418 BOOST_CHECK( delta_millisec >= 250 - /*fuzz*/ 1);
419 BOOST_CHECK( delta_millisec < 300 );
420} // eo MonotonicClock()
421
422BOOST_AUTO_TEST_CASE(WeekInvalid)
423{
424 Week week("99999999");
425 BOOST_CHECK_EQUAL(false, week.is_valid());
426 BOOST_CHECK_EQUAL(string(""), week.get_displaystring());
427}
428
429BOOST_AUTO_TEST_CASE(WeekDisplayString1)
430{
431 Week week("");
432 BOOST_CHECK_EQUAL(true, week.is_valid());
433 BOOST_CHECK_EQUAL(string(""), week.get_displaystring());
434}
435
436BOOST_AUTO_TEST_CASE(WeekDisplayString2)
437{
438 Week week("0123456");
439 BOOST_CHECK_EQUAL(true, week.is_valid());
440 BOOST_CHECK_EQUAL(string("Mon-Sun"), week.get_displaystring());
441}
442
443BOOST_AUTO_TEST_CASE(WeekDisplayString3)
444{
445 Week week("123456");
446 BOOST_CHECK_EQUAL(true, week.is_valid());
447 BOOST_CHECK_EQUAL(string("Mon-Sat"), week.get_displaystring());
448}
449
450BOOST_AUTO_TEST_CASE(WeekDisplayString4)
451{
452 Week week("012345");
453 BOOST_CHECK_EQUAL(true, week.is_valid());
454 BOOST_CHECK_EQUAL(string("Mon-Fri, Sun"), week.get_displaystring());
455}
456
457BOOST_AUTO_TEST_CASE(WeekDisplayString5)
458{
459 Week week("1256");
460 BOOST_CHECK_EQUAL(true, week.is_valid());
461 BOOST_CHECK_EQUAL(string("Mon, Tue, Fri, Sat"), week.get_displaystring());
462}
463
464BOOST_AUTO_TEST_CASE(WeekDisplayString6)
465{
466 Week week("0246");
467 BOOST_CHECK_EQUAL(true, week.is_valid());
468 BOOST_CHECK_EQUAL(string("Tue, Thu, Sat, Sun"), week.get_displaystring());
469}
470
471BOOST_AUTO_TEST_CASE(WeekDisplayString7)
472{
473 Week week("135");
474 BOOST_CHECK_EQUAL(true, week.is_valid());
475 BOOST_CHECK_EQUAL(string("Mon, Wed, Fri"), week.get_displaystring());
476}
477
478BOOST_AUTO_TEST_CASE(WeekDisplayString8)
479{
480 Week week("15");
481 BOOST_CHECK_EQUAL(true, week.is_valid());
482 BOOST_CHECK_EQUAL(string("Mon, Fri"), week.get_displaystring());
483}
484
485BOOST_AUTO_TEST_CASE(WeekDisplayString9)
486{
487 Week week("06");
488 BOOST_CHECK_EQUAL(true, week.is_valid());
489 BOOST_CHECK_EQUAL(string("Sat, Sun"), week.get_displaystring());
490}
491
492BOOST_AUTO_TEST_CASE(WeekDisplayString10)
493{
494 Week week("056");
495 BOOST_CHECK_EQUAL(true, week.is_valid());
496 BOOST_CHECK_EQUAL(string("Fri-Sun"), week.get_displaystring());
497}
498
499BOOST_AUTO_TEST_CASE(WeekDisplayString11)
500{
501 Week week("0");
502 BOOST_CHECK_EQUAL(true, week.is_valid());
503 BOOST_CHECK_EQUAL(string("Sun"), week.get_displaystring());
504}
505
506BOOST_AUTO_TEST_CASE(WeekDisplayString12)
507{
508 Week week("6");
509 BOOST_CHECK_EQUAL(true, week.is_valid());
510 BOOST_CHECK_EQUAL(string("Sat"), week.get_displaystring());
511}
512
513BOOST_AUTO_TEST_CASE(WeekDisplayString13)
514{
515 Week week("123");
516 BOOST_CHECK_EQUAL(true, week.is_valid());
517 BOOST_CHECK_EQUAL(string("Mon-Wed"), week.get_displaystring());
518}
519
520BOOST_AUTO_TEST_CASE(FormatFullTime)
521{
522 this->set_tz ("CET");
523 time_t seconds = 1318844005;
524
525 BOOST_CHECK_EQUAL("17.10.2011 11:33", format_full_time(seconds));
526}
527
528BOOST_AUTO_TEST_CASE(DateToSeconds1)
529{
530 this->set_tz ("CET");
531 // no DST
532 BOOST_CHECK_EQUAL(1325372400, date_to_seconds("2012-01-01"));
533}
534
535BOOST_AUTO_TEST_CASE(DateToSeconds2)
536{
537 this->set_tz ("CET");
538 // DST
539 BOOST_CHECK_EQUAL(1341093600, date_to_seconds("2012-07-01"));
540}
541
542BOOST_AUTO_TEST_CASE(FormatISO8601_T)
543{
544 const time_t moment = 1515492684;
545 BOOST_CHECK_EQUAL("10:11:24",
546 format_iso8601 (moment, true, false, true, false));
547}
548
549BOOST_AUTO_TEST_CASE(FormatISO8601_TZ_local)
550{
551 this->set_tz ("CET");
552 const time_t moment = 1515492684;
553 BOOST_CHECK_EQUAL("11:11:24+0100",
554 format_iso8601 (moment, false, false, true, true));
555}
556
557BOOST_AUTO_TEST_CASE(FormatISO8601_TZ)
558{
559 const time_t moment = 1515492684;
560 BOOST_CHECK_EQUAL("10:11:24+0000",
561 format_iso8601 (moment, true, false, true, true));
562}
563
564BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_local)
565{
566 this->set_tz ("CET");
567 const time_t moment = 1515492684;
568 BOOST_CHECK_EQUAL("2018-01-09T11:11:24+0100",
569 format_iso8601 (moment, false, true, true, true));
570}
571
572BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ)
573{
574 const time_t moment = 1515492684;
575 BOOST_CHECK_EQUAL("2018-01-09T10:11:24+0000",
576 format_iso8601 (moment, true, true, true, true));
577}
578
579BOOST_AUTO_TEST_CASE(FormatISO8601_DT)
580{
581 const time_t moment = 1515492684;
582 BOOST_CHECK_EQUAL("2018-01-09T10:11:24",
583 format_iso8601 (moment, true, true, true, false));
584}
585
586BOOST_AUTO_TEST_CASE(FormatISO8601_D)
587{
588 const time_t moment = 1515492684;
589 BOOST_CHECK_EQUAL("2018-01-09",
590 format_iso8601 (moment, true, true, false, false));
591}
592
593BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_struct_tm)
594{
595 struct tm helau;
596 helau.tm_sec = 11;
597 helau.tm_min = 11;
598 helau.tm_hour = 11;
599 helau.tm_mday = 11;
600 helau.tm_mon = 10;
601 helau.tm_year = 2018 - 1900;
602 helau.tm_wday = 0;
603 helau.tm_yday = 315;
604 helau.tm_isdst = 0;
605 helau.tm_gmtoff = 0;
606 helau.tm_zone = NULL;
607
608 BOOST_CHECK_EQUAL("2018-11-11T11:11:11+0000",
609 format_iso8601 (helau, true, true, true));
610}
611
612BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_struct_timespec)
613{
614 struct timespec ts = { 1541934671, 11 };
615
616 BOOST_CHECK_EQUAL("2018-11-11T11:11:11+0000",
617 format_iso8601 (ts, true, true, true, true));
618}
619
620BOOST_AUTO_TEST_SUITE(Clock)
621
622 BOOST_AUTO_TEST_CASE(ctor_simple)
623 {
624 I2n::clock::Time t;
625
626 BOOST_CHECK_EQUAL(t.get_sec (), 0);
627 BOOST_CHECK_EQUAL(t.get_nsec (), 0);
628 }
629
630 BOOST_AUTO_TEST_CASE(ctor_type)
631 {
632 I2n::clock::Time t1 (I2n::clock::type::real);
633 I2n::clock::Time t2 (I2n::clock::type::mono);
634 I2n::clock::Time t3 (I2n::clock::type::boot);
635 I2n::clock::Time t4 (I2n::clock::type::cpu);
636
637 BOOST_CHECK_EQUAL(t1.get_sec (), 0);
638 BOOST_CHECK_EQUAL(t1.get_nsec (), 0);
639
640 BOOST_CHECK_EQUAL(t2.get_sec (), 0);
641 BOOST_CHECK_EQUAL(t2.get_nsec (), 0);
642
643 BOOST_CHECK_EQUAL(t3.get_sec (), 0);
644 BOOST_CHECK_EQUAL(t3.get_nsec (), 0);
645
646 BOOST_CHECK_EQUAL(t4.get_sec (), 0);
647 BOOST_CHECK_EQUAL(t4.get_nsec (), 0);
648 }
649
650 BOOST_AUTO_TEST_CASE(ctor_variant)
651 {
652 I2n::clock::Time tmc (I2n::clock::type::mono);
653 I2n::clock::Time tmr (I2n::clock::type::mono, I2n::clock::type::raw);
654 I2n::clock::Time tme (I2n::clock::type::mono, I2n::clock::type::exact);
655
656 I2n::clock::Time trc (I2n::clock::type::real);
657 I2n::clock::Time tre (I2n::clock::type::real, I2n::clock::type::exact);
658
659 I2n::clock::Time tb (I2n::clock::type::boot);
660
661 I2n::clock::Time tcp (I2n::clock::type::cpu);
662 I2n::clock::Time tct (I2n::clock::type::cpu, I2n::clock::type::thread);
663
664 BOOST_CHECK_EQUAL(tmc.get_sec (), 0); /* MONO */
665 BOOST_CHECK_EQUAL(tmc.get_nsec (), 0);
666
667 BOOST_CHECK_EQUAL(tmr.get_sec (), 0);
668 BOOST_CHECK_EQUAL(tmr.get_nsec (), 0);
669
670 BOOST_CHECK_EQUAL(tme.get_sec (), 0);
671 BOOST_CHECK_EQUAL(tme.get_nsec (), 0);
672
673 BOOST_CHECK_EQUAL(trc.get_sec (), 0); /* REAL */
674 BOOST_CHECK_EQUAL(trc.get_nsec (), 0);
675
676 BOOST_CHECK_EQUAL(tre.get_sec (), 0);
677 BOOST_CHECK_EQUAL(tre.get_nsec (), 0);
678
679 BOOST_CHECK_EQUAL(tb.get_sec (), 0); /* BOOT */
680 BOOST_CHECK_EQUAL(tb.get_nsec (), 0);
681
682 BOOST_CHECK_EQUAL(tcp.get_sec (), 0); /* CPU */
683 BOOST_CHECK_EQUAL(tcp.get_nsec (), 0);
684
685 BOOST_CHECK_EQUAL(tct.get_sec (), 0);
686 BOOST_CHECK_EQUAL(tct.get_nsec (), 0);
687 }
688
689 BOOST_AUTO_TEST_CASE(initializer_now)
690 {
691 boost::optional<I2n::clock::Time> t = I2n::clock::now ();
692
693 BOOST_CHECK(t);
694 BOOST_CHECK_GT(t->get_sec (), 0);
695 BOOST_CHECK_EQUAL(t->err, 0);
696 }
697
698 BOOST_AUTO_TEST_CASE(initializer_zero)
699 {
700 I2n::clock::Time stundenull = I2n::clock::zero ();
701
702 BOOST_CHECK_EQUAL(stundenull.get_sec (), 0);
703 BOOST_CHECK_EQUAL(stundenull.get_nsec (), 0);
704 BOOST_CHECK_EQUAL(stundenull.err, 0);
705 }
706
707 BOOST_AUTO_TEST_CASE(member_set_now)
708 {
709 I2n::clock::Time t;
710
711 BOOST_CHECK(t.set ());
712
713 BOOST_CHECK_NE(t.get_sec (), 0);
714 }
715
716 BOOST_AUTO_TEST_CASE(member_set_value)
717 {
718 I2n::clock::Time t;
719
720 t.set (42, 42);
721
722 BOOST_CHECK_EQUAL(t.get_sec (), 42);
723 BOOST_CHECK_EQUAL(t.get_nsec (), 42);
724 }
725
726 BOOST_AUTO_TEST_CASE(member_set_value_type)
727 {
728 I2n::clock::Time t;
729
730 t.set (42, 42, I2n::clock::type::real, I2n::clock::type::exact);
731
732 BOOST_CHECK_EQUAL(t.get_sec (), 42);
733 BOOST_CHECK_EQUAL(t.get_nsec (), 42);
734 }
735
736 BOOST_AUTO_TEST_CASE(member_add_parts)
737 {
738 I2n::clock::Time t;
739
740 t.set (42, 42);
741 t.add (2187, 2187);
742
743 BOOST_CHECK_EQUAL(t.get_sec (), 2229);
744 BOOST_CHECK_EQUAL(t.get_nsec (), 2229);
745 }
746
747 BOOST_AUTO_TEST_CASE(member_sub_parts)
748 {
749 I2n::clock::Time t;
750
751 t.set (2, 0L);
752 t.subtract (1, 1L);
753
754 BOOST_CHECK_EQUAL(t.get_sec (), 0);
755 BOOST_CHECK_EQUAL(t.get_nsec (), 999999999);
756 }
757
758 BOOST_AUTO_TEST_CASE(member_sub_Time)
759 {
760 I2n::clock::Time t1;
761 I2n::clock::Time t2;
762
763 t1.set (42, 42L);
764 t2.set (42, 0L);
765
766 t1.subtract (t2);
767
768 BOOST_CHECK_EQUAL(t1.get_sec (), 0);
769 BOOST_CHECK_EQUAL(t1.get_nsec (), 42L);
770 }
771
772 BOOST_AUTO_TEST_CASE(member_diff)
773 {
774 static const time_t five = 5 * 365 * 24 * 3600;
775
776 I2n::clock::Time t1 (42, 1337);
777 I2n::clock::Time t2 = t1 + five;;
778 I2n::clock::Time t3 = t1 - five;;
779
780 BOOST_CHECK_EQUAL(t2, I2n::clock::Time ((time_t)42 + five, 1337));
781 BOOST_CHECK_EQUAL(t3, I2n::clock::Time ((time_t)42 - five, 1337));
782 BOOST_CHECK_EQUAL(t1.difference (t3), t3.difference (t1));
783 BOOST_CHECK_EQUAL(t3.difference (t3), t3.difference (t3));
784 }
785
786 BOOST_AUTO_TEST_CASE(op_copyassign)
787 {
788 I2n::clock::Time t1;
789 I2n::clock::Time t2;
790
791 BOOST_CHECK(t1.set ());
792
793 t2 = t1;
794
795 BOOST_CHECK_EQUAL(t1.get_sec (), t2.get_sec ());
796 BOOST_CHECK_EQUAL(t1.get_nsec (), t2.get_nsec ());
797 }
798
799 BOOST_AUTO_TEST_CASE(op_equal)
800 {
801 I2n::clock::Time t1;
802 I2n::clock::Time t2;
803
804 BOOST_CHECK(t1.set ());
805 t2 = t1;
806
807 BOOST_CHECK_EQUAL(t1, t2);
808 }
809
810 BOOST_AUTO_TEST_CASE(op_add_Time)
811 {
812 I2n::clock::Time t1;
813 I2n::clock::Time t2;
814 I2n::clock::Time tsum;
815
816 t1.set (2187, 2187);
817 t2.set (1337, 1337);
818 tsum = t1 + t2;
819
820 BOOST_CHECK_EQUAL(tsum.get_sec (), 3524);
821 BOOST_CHECK_EQUAL(tsum.get_nsec (), 3524);
822 }
823
824 BOOST_AUTO_TEST_CASE(op_add_Time_carry)
825 {
826 I2n::clock::Time t1;
827 I2n::clock::Time t2;
828 I2n::clock::Time tsum;
829
830 t1.set (2187, 2187);
831# if LONG_BIT == 32
832 t2.set (1300, 2L * 1000 * 1000 * 1000 + 1337);
833# else
834 t2.set (1300, 37L * 1000 * 1000 * 1000 + 1337);
835# endif
836
837 tsum = t1 + t2;
838
839# if LONG_BIT == 32
840 BOOST_CHECK_EQUAL(tsum.get_sec (), 3489);
841 BOOST_CHECK_EQUAL(tsum.get_nsec (), 3524);
842# else
843 BOOST_CHECK_EQUAL(tsum.get_sec (), 3524);
844 BOOST_CHECK_EQUAL(tsum.get_nsec (), 3524);
845# endif
846 }
847
848 BOOST_AUTO_TEST_CASE(op_add_time_t)
849 {
850 I2n::clock::Time t1 (2187, 2187);
851 time_t t2 = 1337;
852 I2n::clock::Time tsum;
853
854 tsum = t1 + t2;
855
856 BOOST_CHECK_EQUAL(tsum.get_sec (), 3524);
857 BOOST_CHECK_EQUAL(tsum.get_nsec (), 2187);
858 }
859
860 BOOST_AUTO_TEST_CASE(op_add_time_t_external)
861 {
862 time_t t1 = 1337;
863 I2n::clock::Time t2 (2187, 2187);
864 I2n::clock::Time tsum;
865
866 tsum = t1 + t2;
867
868 BOOST_CHECK_EQUAL(tsum.get_sec (), 3524);
869 BOOST_CHECK_EQUAL(tsum.get_nsec (), 2187);
870 }
871
872 BOOST_AUTO_TEST_CASE(op_incr_Time)
873 {
874 I2n::clock::Time t1 (2187, 2187);
875 I2n::clock::Time t2 (1337, 1337);
876
877 t1 += t2;
878
879 BOOST_CHECK_EQUAL(t1.get_sec (), 3524);
880 BOOST_CHECK_EQUAL(t1.get_nsec (), 3524);
881 }
882
883 BOOST_AUTO_TEST_CASE(op_incr_time_t)
884 {
885 I2n::clock::Time t1 (2187, 2187);
886 time_t t2 = 1337;
887
888 t1 += t2;
889
890 BOOST_CHECK_EQUAL(t1.get_sec (), 3524);
891 BOOST_CHECK_EQUAL(t1.get_nsec (), 2187);
892 }
893
894 BOOST_AUTO_TEST_CASE(op_subtract_Time)
895 {
896 I2n::clock::Time t1;
897 I2n::clock::Time t2;
898 I2n::clock::Time tdiff;
899
900 t1.set (2187, 2187);
901 t2.set (1337, 1337);
902 tdiff = t1 - t2;
903
904 BOOST_CHECK_EQUAL(tdiff.get_sec (), 850);
905 BOOST_CHECK_EQUAL(tdiff.get_nsec (), 850);
906 }
907
908 BOOST_AUTO_TEST_CASE(op_subtract_time_t)
909 {
910 I2n::clock::Time t1 (2187, 2187);
911 time_t t2 = 1337;
912 I2n::clock::Time tdiff;
913
914 tdiff = t1 - t2;
915
916 BOOST_CHECK_EQUAL(tdiff.get_sec (), 850);
917 BOOST_CHECK_EQUAL(tdiff.get_nsec (), 2187);
918 }
919
920 BOOST_AUTO_TEST_CASE(op_subtract_time_t_external)
921 {
922 time_t t1 = 1337;
923 I2n::clock::Time t2 (2187, 2187);
924 I2n::clock::Time tdiff;
925
926 tdiff = t1 - t2;
927
928 BOOST_CHECK_EQUAL(tdiff.get_sec (), -851);
929 BOOST_CHECK_EQUAL(tdiff.get_nsec (), 999997813);
930 }
931
932 BOOST_AUTO_TEST_CASE(op_decr_Time)
933 {
934 I2n::clock::Time t1 (2187, 2187);
935 I2n::clock::Time t2 (1337, 1337);
936
937 t1 -= t2;
938
939 BOOST_CHECK_EQUAL(t1.get_sec (), 850);
940 BOOST_CHECK_EQUAL(t1.get_nsec (), 850);
941 }
942
943 BOOST_AUTO_TEST_CASE(op_decr_time_t)
944 {
945 I2n::clock::Time t1 (2187, 2187);
946 time_t t2 = 1337;
947
948 t1 -= t2;
949
950 BOOST_CHECK_EQUAL(t1.get_sec (), 850);
951 BOOST_CHECK_EQUAL(t1.get_nsec (), 2187);
952 }
953
954 BOOST_AUTO_TEST_CASE(op_mult_scale)
955 {
956 I2n::clock::Time t1;
957 I2n::clock::Time t2;
958
959 t1.set (1, 1);
960 t2 = t1 * 42;
961
962 BOOST_CHECK_EQUAL(t2.get_sec (), 42);
963 BOOST_CHECK_EQUAL(t2.get_nsec (), 42);
964 }
965
966 BOOST_AUTO_TEST_CASE(op_mult_mutate)
967 {
968 I2n::clock::Time t1 ( 42, 42);
969 I2n::clock::Time t2 (1337, 0);
970
971 t1 *= 2;
972 t2 *= -10;
973
974 BOOST_CHECK_EQUAL(t1.get_sec (), 84);
975 BOOST_CHECK_EQUAL(t1.get_nsec (), 84);
976 BOOST_CHECK_EQUAL(t2.get_sec (), -13370);
977 }
978
979 BOOST_AUTO_TEST_CASE(op_mult_scale_carry)
980 {
981 I2n::clock::Time t1;
982 I2n::clock::Time t2;
983
984 t1.set (1, 500 * 1000 * 1000);
985 t2 = t1 * 3;
986
987 BOOST_CHECK_EQUAL(t2.get_sec (), 4);
988 BOOST_CHECK_EQUAL(t2.get_nsec (), 500 * 1000 * 1000);
989 }
990
991 BOOST_AUTO_TEST_CASE(op_equals)
992 {
993 I2n::clock::Time t1;
994 I2n::clock::Time t2;
995
996 t1.set (50, 50);
997 t2.set (50, 50);
998
999 BOOST_CHECK_EQUAL(t1, t2);
1000 }
1001
1002 BOOST_AUTO_TEST_CASE(compare_equal)
1003 {
1004 I2n::clock::Time t1;
1005 I2n::clock::Time t2;
1006
1007 t1.set (42, 42);
1008 t2.set (42, 42);
1009
1010 BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), 0);
1011 }
1012
1013 BOOST_AUTO_TEST_CASE(compare_equal_type)
1014 {
1015 I2n::clock::Time t1 (42, 42, I2n::clock::type::real);
1016 I2n::clock::Time t2 (42, 42, I2n::clock::type::cpu);
1017 I2n::clock::Time t3 (42, 0, I2n::clock::type::real);
1018 I2n::clock::Time t4 (42, 42, I2n::clock::type::real);
1019
1020 BOOST_CHECK_NE(t1, t2);
1021 BOOST_CHECK_NE(t1, t3);
1022 BOOST_CHECK_EQUAL(t1, t4);
1023 }
1024
1025 BOOST_AUTO_TEST_CASE(compare_ne_sec)
1026 {
1027 I2n::clock::Time t1;
1028 I2n::clock::Time t2;
1029
1030 t1.set ( 42, 42);
1031 t2.set (1337, 42);
1032
1033 BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), -1);
1034 BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1), 1);
1035 }
1036
1037 BOOST_AUTO_TEST_CASE(compare_ne_nsec)
1038 {
1039 I2n::clock::Time t1;
1040 I2n::clock::Time t2;
1041
1042 t1.set (42, 42);
1043 t2.set (42, 1337);
1044
1045 BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), -1);
1046 BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1), 1);
1047 }
1048
1049 BOOST_AUTO_TEST_CASE(compare_ne_both)
1050 {
1051 I2n::clock::Time t1;
1052 I2n::clock::Time t2;
1053
1054 t1.set (42, 2187);
1055 t2.set (23, 1337);
1056
1057 BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), 1);
1058 BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1), -1);
1059 }
1060
1061 BOOST_AUTO_TEST_CASE(op_ineq_sec)
1062 {
1063 I2n::clock::Time t1 (1337);
1064 I2n::clock::Time t2 (2187);
1065
1066 BOOST_CHECK_LT(t1, t2);
1067 BOOST_CHECK_GT(t2, t1);
1068 }
1069
1070 BOOST_AUTO_TEST_CASE(op_ineq_nsec)
1071 {
1072 I2n::clock::Time t1 (1337, 23);
1073 I2n::clock::Time t2 (1337, 42);
1074
1075 BOOST_CHECK_LT(t1, t2);
1076 BOOST_CHECK_GT(t2, t1);
1077 }
1078
1079 BOOST_AUTO_TEST_CASE(op_ineq_both)
1080 {
1081 I2n::clock::Time t1 (2187, 23);
1082 I2n::clock::Time t2 (1337, 42);
1083
1084 BOOST_CHECK_LT(t2, t1);
1085 BOOST_CHECK_GT(t1, t2);
1086 }
1087
1088 BOOST_AUTO_TEST_CASE(op_eq_time_t)
1089 {
1090 boost::optional<I2n::clock::Time> t1 = I2n::clock::now ();
1091 const time_t t2 = time (NULL); /* race here */
1092
1093 *t1 -= (time_t)42;
1094
1095 BOOST_CHECK_NE(*t1, t2);
1096 BOOST_CHECK_LT(*t1, t2);
1097 BOOST_CHECK_GT( t2, *t1);
1098 }
1099
1100 BOOST_AUTO_TEST_CASE(Format_sec_msec)
1101 {
1102 I2n::clock::Time t1 (42, 42);
1103 I2n::clock::Time t2 ( 4, 242424242);
1104 I2n::clock::Time t3 ( 0, 133713371);
1105 I2n::clock::Time t4 ( 0, 0);
1106
1107 std::string s1 = t1.format_sec_msec ();
1108 std::string s2 = t2.format_sec_msec ();
1109 std::string s3 = t3.format_sec_msec ();
1110 std::string s4 = t4.format_sec_msec ();
1111
1112 BOOST_CHECK_EQUAL("42s 0ms" , s1);
1113 BOOST_CHECK_EQUAL( "4s 242ms", s2);
1114 BOOST_CHECK_EQUAL( "0s 133ms", s3);
1115 BOOST_CHECK_EQUAL( "0s 0ms" , s4);
1116 }
1117
1118 BOOST_AUTO_TEST_CASE(Format_min_sec_msec)
1119 {
1120 I2n::clock::Time t1 (42*60 + 42, 42);
1121 I2n::clock::Time t2 ( 4*60 + 42, 242424242);
1122 I2n::clock::Time t3 ( 0*60 + 42, 133713371);
1123 I2n::clock::Time t4 ( 0 + 0, 0);
1124
1125 std::string s1 = *t1.format_min_sec_msec ();
1126 std::string s2 = *t2.format_min_sec_msec ();
1127 std::string s3 = *t3.format_min_sec_msec ();
1128 std::string s4 = *t4.format_min_sec_msec ();
1129
1130 BOOST_CHECK_EQUAL("42m42.000s", s1);
1131 BOOST_CHECK_EQUAL( "4m42.242s", s2);
1132 BOOST_CHECK_EQUAL( "0m42.133s", s3);
1133 BOOST_CHECK_EQUAL( "0m0.000s", s4);
1134 }
1135
1136 BOOST_AUTO_TEST_CASE(FormatISO8601_T)
1137 {
1138 I2n::clock::Time t (42, 42);
1139 boost::optional<std::string> s = t.format_iso8601 (true, false, true, false);
1140
1141 BOOST_CHECK_EQUAL("00:00:42", *s);
1142 }
1143
1144 BOOST_AUTO_TEST_CASE(FormatISO8601_DT)
1145 {
1146 I2n::clock::Time t (1541934671, 0);
1147 boost::optional<std::string> s = t.format_iso8601 (true, true, true, false);
1148
1149 BOOST_CHECK_EQUAL("2018-11-11T11:11:11", *s);
1150 }
1151
1152 BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ)
1153 {
1154 I2n::clock::Time t (1541934671, 0);
1155 boost::optional<std::string> s = t.format_iso8601 (true, true, true, true);
1156
1157 BOOST_CHECK_EQUAL("2018-11-11T11:11:11+0000", *s);
1158 }
1159
1160 BOOST_AUTO_TEST_CASE(Format_make_nice_time)
1161 {
1162 I2n::clock::Time t (111111, 0);
1163 boost::optional<std::string> s = t.make_nice_time ();
1164
1165 BOOST_CHECK_EQUAL("1 day, 06:51:51", *s);
1166 }
1167
1168 BOOST_AUTO_TEST_CASE(Format_format_full_time)
1169 {
1170 I2n::clock::Time t (1541934671, 0);
1171 /*
1172 * brr, the old formatters use localtime without a way to opt out of
1173 * it!
1174 */
1175 this->set_utc ();
1176 boost::optional<std::string> s = t.format_full_time ();
1177
1178 BOOST_CHECK_EQUAL("11.11.2018 11:11", *s);
1179 }
1180
1181 BOOST_AUTO_TEST_CASE(Format_format_date)
1182 {
1183 I2n::clock::Time t (1541934671, 0);
1184 boost::optional<std::string> s = t.format_date ();
1185
1186 BOOST_CHECK_EQUAL("11.11.2018", *s);
1187 }
1188
1189 BOOST_AUTO_TEST_CASE(FromString_iso8601_full)
1190 {
1191 const std::string in1 ("0001-01-01T00:00:00+0000");
1192 const std::string in2 ("2018-11-11T11:11:11+0000");
1193
1194 this->set_utc ();
1195
1196 boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1);
1197 boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2);
1198
1199# if LONG_BIT == 32
1200 BOOST_CHECK(!t1);
1201# else
1202 BOOST_CHECK(t1);
1203 BOOST_CHECK_EQUAL(*t1->format_iso8601 (), in1);
1204# endif
1205
1206 BOOST_CHECK(t2);
1207 BOOST_CHECK_EQUAL(*t2->format_iso8601 (), in2);
1208 }
1209
1210 BOOST_AUTO_TEST_CASE(FromString_iso8601_full_negyear)
1211 {
1212 const std::string in1 ("-0001-01-01T00:00:00+0000");
1213 const std::string in2 ("-2018-11-11T11:11:11+0000");
1214
1215 this->set_utc ();
1216
1217 boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1);
1218 boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2);
1219
1220# if LONG_BIT == 32
1221 BOOST_CHECK(!t1);
1222 BOOST_CHECK(!t2);
1223# else
1224 BOOST_CHECK(t1);
1225 BOOST_CHECK(t2);
1226 BOOST_CHECK_EQUAL(*t1->format_iso8601 (), in1);
1227 BOOST_CHECK_EQUAL(*t2->format_iso8601 (), in2);
1228# endif
1229 }
1230
1231# ifndef GLIBC_STRPTIME_LACKS_Z
1232 BOOST_AUTO_TEST_CASE(FromString_iso8601_Z)
1233 {
1234 const std::string in1 ("2019-04-25T13:41:47+0000");
1235 const std::string in2 ("2019-04-25T13:41:47Z");
1236
1237 this->set_utc ();
1238 boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1, true, true, true);
1239 boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2, true, true, true);
1240
1241 BOOST_CHECK(t1);
1242 BOOST_CHECK(t2);
1243
1244 BOOST_CHECK_EQUAL(*t1, *t2);
1245 BOOST_CHECK_EQUAL(*t1->format_iso8601 (), *t2->format_iso8601 ());
1246 BOOST_CHECK_EQUAL(*t2->format_iso8601 (), in1);
1247 }
1248# endif
1249
1250 BOOST_AUTO_TEST_CASE(FromString_iso8601_partial)
1251 {
1252 const std::string in1 ("2018-11-11T11:11:11");
1253 const std::string in2 ("2018-11-11");
1254
1255 this->set_utc ();
1256
1257 boost::optional<I2n::clock::Time> t1 =
1258 I2n::clock::time_of_iso8601 (in1, true, true, false);
1259 boost::optional<I2n::clock::Time> t2 =
1260 I2n::clock::time_of_iso8601 (in2, true, false, false);
1261
1262 BOOST_CHECK(t1);
1263 BOOST_CHECK(t2);
1264 /*
1265 * We test for the difference here which is zero if the number is
1266 * correct but causes the difference from the expected value to be
1267 * printed in case the test fails.
1268 */
1269 BOOST_CHECK_EQUAL(*t1->format_iso8601 (true, true, true, false), in1);
1270 BOOST_CHECK_EQUAL(*t2->format_iso8601 (true, true, false, false), in2);
1271 }
1272
1273 BOOST_AUTO_TEST_CASE(FromString_iso8601_offset)
1274 {
1275 const std::string in1 ("2019-04-25T13:41:47Z");
1276 const std::string in2 ("2019-04-25T13:41:47+0200"); /* = UTC(in1 + 2h) */
1277 const std::string in3 ("2019-04-25T15:41:47+0000"); /* = UTC(in2) */
1278
1279 this->set_utc ();
1280 boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1, true, true, true);
1281 boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2, true, true, true);
1282 boost::optional<I2n::clock::Time> t3 = I2n::clock::time_of_iso8601 (in3, true, true, true);
1283
1284# ifdef GLIBC_STRPTIME_LACKS_Z
1285 BOOST_CHECK(!t1);
1286# else
1287 BOOST_CHECK(t1);
1288# endif
1289 BOOST_CHECK(t2);
1290 BOOST_CHECK(t3);
1291
1292# ifndef GLIBC_STRPTIME_LACKS_Z
1293 BOOST_CHECK_EQUAL(*t1->format_iso8601 (), "2019-04-25T13:41:47+0000");
1294 BOOST_CHECK_EQUAL(t1->get_sec (), 1556199707);
1295# endif
1296 BOOST_CHECK_EQUAL(*t2->format_iso8601 (), "2019-04-25T15:41:47+0000");
1297# ifndef GLIBC_STRPTIME_LACKS_Z
1298 BOOST_CHECK_EQUAL(t2->get_sec (), t1->get_sec () + 2 * 60 * 60);
1299# endif
1300 BOOST_CHECK_EQUAL(*t2, *t3);
1301 BOOST_CHECK_EQUAL(*t3->format_iso8601 (), "2019-04-25T15:41:47+0000");
1302 }
1303
1304 BOOST_AUTO_TEST_CASE(FromString_iso8601_dst)
1305 {
1306 const std::string in1 ("2019-03-30T12:42:42"); /* “winter time” */
1307 const std::string in2 ("2019-03-31T12:42:42"); /* “summer time” */
1308
1309 this->set_utc ();
1310 boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1, true, true, false);
1311 boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2, true, true, false);
1312
1313 BOOST_CHECK(t1);
1314 BOOST_CHECK(t2);
1315 BOOST_CHECK_EQUAL(t1->get_sec (), 1553949762);
1316 BOOST_CHECK_EQUAL(t2->get_sec (), 1554036162);
1317 BOOST_CHECK_EQUAL(*t1->format_iso8601 (), in1 + "+0000");
1318 BOOST_CHECK_EQUAL(*t2->format_iso8601 (), in2 + "+0000");
1319
1320 this->set_tz ("CET");
1321 BOOST_CHECK_EQUAL(*t1->format_iso8601 (false, true, true, true), "2019-03-30T13:42:42+0100");
1322 BOOST_CHECK_EQUAL(*t2->format_iso8601 (false, true, true, true), "2019-03-31T14:42:42+0200");
1323 }
1324
1325 BOOST_AUTO_TEST_CASE(FromString_iso8601_tzdiff)
1326 {
1327 const std::string in ("2019-04-26T13:45:02+0000");
1328
1329 this->set_tz ("UTC");
1330 boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in, true, true, false);
1331
1332 this->set_tz ("CET");
1333 boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in, true, true, false);
1334
1335 BOOST_CHECK_EQUAL(*t1->format_iso8601 (true, true, true, true), in);
1336 BOOST_CHECK_EQUAL(*t2->format_iso8601 (true, true, true, true), "2019-04-26T13:45:02+0000");
1337 }
1338
1339 BOOST_AUTO_TEST_CASE(FromString_iso8601_32bit_time_t_err)
1340 {
1341 const std::string timeless ("11:11:11");
1342 boost::optional<I2n::clock::Time> untimely = boost::none;
1343
1344 this->set_utc ();
1345
1346 untimely = I2n::clock::time_of_iso8601 (timeless, false, true, false);
1347
1348# if LONG_BIT == 32
1349 BOOST_CHECK(!untimely);
1350# else
1351 BOOST_CHECK(untimely);
1352 BOOST_CHECK_EQUAL(*untimely->format_iso8601 (true, false, true, false),
1353 timeless);
1354# endif
1355 }
1356
1357 BOOST_AUTO_TEST_CASE(Ctor_32bit_time_t_err)
1358 {
1359 boost::optional<std::string> threw = boost::none;
1360
1361 struct tm tm;
1362 memset (&tm, 0, sizeof (tm));
1363
1364 tm.tm_sec = 11;
1365 tm.tm_min = 11;
1366 tm.tm_hour = 11;
1367 tm.tm_mday = 11;
1368 tm.tm_mon = 10;
1369 tm.tm_year = -789;
1370 tm.tm_gmtoff = 0;
1371
1372 try {
1373 I2n::clock::Time untimely (tm);
1374 } catch (I2n::clock::conversion_error &exn) {
1375 threw = std::string (exn);
1376 }
1377
1378
1379# if LONG_BIT == 32
1380 BOOST_CHECK_EQUAL(*threw,
1381 "errno=0 [mktime: from struct tm {Sun Nov 11 11:11:11 1111}]");
1382# else
1383 BOOST_CHECK(!threw);
1384# endif
1385 }
1386
1387 BOOST_AUTO_TEST_CASE(containers_list)
1388 {
1389 std::list<I2n::clock::Time> ts;
1390
1391 ts.push_back (I2n::clock::zero ());
1392 ts.push_back (I2n::clock::zero ());
1393
1394 BOOST_CHECK_EQUAL(ts.size (), 2);
1395 }
1396
1397 BOOST_AUTO_TEST_CASE(containers_vec)
1398 {
1399 std::vector<I2n::clock::Time> ts;
1400
1401 ts.push_back (I2n::clock::zero ());
1402 ts.push_back (I2n::clock::zero ());
1403
1404 BOOST_CHECK_EQUAL(ts.size (), 2);
1405 }
1406
1407 BOOST_AUTO_TEST_CASE(containers_set)
1408 {
1409 std::set<I2n::clock::Time> ts;
1410
1411 ts.insert (I2n::clock::zero ());
1412 ts.insert (I2n::clock::Time (42, 2187));
1413 ts.insert (I2n::clock::zero ());
1414
1415 BOOST_CHECK_EQUAL(ts.size (), 2);
1416 }
1417
1418 BOOST_AUTO_TEST_CASE(containers_list_mean)
1419 {
1420 std::list<I2n::clock::Time> ts;
1421
1422 ts.push_back (I2n::clock::Time (42, 42));
1423 ts.push_back (I2n::clock::Time (1337, 1337));
1424
1425 BOOST_CHECK_EQUAL(I2n::clock::mean (ts),
1426 I2n::clock::Time (689, 500000689));
1427 }
1428
1429 BOOST_AUTO_TEST_CASE(containers_list_mean_zero)
1430 {
1431 std::list<I2n::clock::Time> ts;
1432
1433 ts.push_back (I2n::clock::Time (0, 0));
1434 ts.push_back (I2n::clock::Time (0, 0));
1435 ts.push_back (I2n::clock::Time (0, 0));
1436 ts.push_back (I2n::clock::Time (0, 0));
1437
1438 BOOST_CHECK_EQUAL(I2n::clock::mean (ts),
1439 I2n::clock::zero ());
1440 }
1441
1442 BOOST_AUTO_TEST_CASE(containers_list_mean_empty)
1443 {
1444 std::list<I2n::clock::Time> ts;
1445
1446 BOOST_CHECK_EQUAL(I2n::clock::mean (ts), I2n::clock::Time (0, 0));
1447 }
1448
1449 BOOST_AUTO_TEST_CASE(containers_set_mean)
1450 {
1451 std::set<I2n::clock::Time> ts;
1452
1453 ts.insert (I2n::clock::Time (42));
1454 ts.insert (I2n::clock::Time (1337));
1455 ts.insert (I2n::clock::Time (2187));
1456
1457 BOOST_CHECK_EQUAL(I2n::clock::mean (ts),
1458 I2n::clock::Time (1188, 666666666));
1459 }
1460
1461 BOOST_AUTO_TEST_CASE(containers_set_median_empty)
1462 {
1463 std::set<I2n::clock::Time> ts;
1464
1465 BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (0, 0));
1466 }
1467
1468 BOOST_AUTO_TEST_CASE(containers_set_median_one)
1469 {
1470 std::set<I2n::clock::Time> ts;
1471
1472 ts.insert (I2n::clock::Time (42, 0));
1473
1474 BOOST_CHECK_EQUAL(I2n::clock::median (ts),
1475 I2n::clock::Time (42, 0));
1476 }
1477
1478 BOOST_AUTO_TEST_CASE(containers_set_median_multi)
1479 {
1480 std::set<I2n::clock::Time> ts;
1481
1482 ts.insert (I2n::clock::Time (42));
1483 ts.insert (I2n::clock::Time (1337));
1484 ts.insert (I2n::clock::Time (2187));
1485
1486 BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (1337));
1487 }
1488
1489 BOOST_AUTO_TEST_CASE(containers_vec_median_multi)
1490 {
1491 std::vector<I2n::clock::Time> ts;
1492
1493 ts.push_back (I2n::clock::Time (42));
1494 ts.push_back (I2n::clock::Time (1337));
1495 ts.push_back (I2n::clock::Time (2187));
1496
1497 BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (1337));
1498 }
1499
1500 BOOST_AUTO_TEST_CASE(containers_list_median_multi)
1501 {
1502 std::list<I2n::clock::Time> ts;
1503
1504 ts.push_back (I2n::clock::Time (42));
1505 ts.push_back (I2n::clock::Time (1337));
1506 ts.push_back (I2n::clock::Time (2187));
1507 ts.push_back (I2n::clock::Time (0xdead));
1508 ts.push_back (I2n::clock::Time (0xbeef));
1509
1510 BOOST_CHECK_EQUAL(I2n::clock::median (ts),
1511 I2n::clock::Time (2187));
1512 }
1513
1514 BOOST_AUTO_TEST_CASE(containers_list_median_multi_evensize)
1515 {
1516 std::list<I2n::clock::Time> ts;
1517
1518 ts.push_back (I2n::clock::Time (42));
1519 ts.push_back (I2n::clock::Time (1337));
1520 ts.push_back (I2n::clock::Time (2187));
1521 ts.push_back (I2n::clock::Time (0xf00d));
1522 ts.push_back (I2n::clock::Time (0xfeed));
1523 ts.push_back (I2n::clock::Time (0xdeadf0e));
1524
1525 BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (0xf00d));
1526 }
1527
1528 BOOST_AUTO_TEST_CASE(operator_shift_left)
1529 {
1530 std::ostringstream os1;
1531 std::ostringstream os2;
1532 std::ostringstream os3;
1533 std::ostringstream os4;
1534
1535 os1 << I2n::clock::Time ( 42, 42);
1536 os2 << I2n::clock::Time (-42, 42);
1537 os3 << I2n::clock::Time ( 42, -42);
1538 os4 << I2n::clock::Time (-42, -42);
1539
1540 BOOST_CHECK_EQUAL(os1.str (), "42s, 42ns");
1541 BOOST_CHECK_EQUAL(os2.str (), "-42s, 42ns");
1542 BOOST_CHECK_EQUAL(os3.str (), "41s, 999999958ns");
1543 BOOST_CHECK_EQUAL(os4.str (), "-43s, 999999958ns");
1544 }
1545
1546BOOST_AUTO_TEST_SUITE_END() /* [Clock] */
1547
1548BOOST_AUTO_TEST_SUITE_END()