implement division by scalar for Time and container ops
[libi2ncommon] / test / test_timefunc.cpp
1 /*
2 The software in this package is distributed under the GNU General
3 Public License version 2 (with a special exception described below).
4
5 A copy of GNU General Public License (GPL) is included in this distribution,
6 in the file COPYING.GPL.
7
8 As a special exception, if other files instantiate templates or use macros
9 or inline functions from this file, or you compile this file and link it
10 with other works to produce a work based on this file, this file
11 does not by itself cause the resulting work to be covered
12 by the GNU General Public License.
13
14 However the source code for this file must still be made available
15 in accordance with section (3) of the GNU General Public License.
16
17 This exception does not invalidate any other reasons why a work based
18 on 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
27 #define BOOST_TEST_DYN_LINK
28 #include <boost/test/unit_test.hpp>
29
30 #include <timefunc.hxx>
31 #include <filefunc.hxx>
32
33 #include <unistd.h>
34 #include <set>
35
36 using namespace std;
37 using namespace I2n;
38 using namespace I2n::Time;
39
40 class TestTimeFuncFixture
41 {
42 protected:
43    typedef std::list< std::string > StringList;
44    std::set<std::string>  used_check_files;
45
46    std::string get_check_file_path(std::string tag)
47    {
48       std::string result;
49       result= "__unittest__" + tag + ".dat";
50       used_check_files.insert(result);
51       return result;
52    } // eo get_check_file_path
53
54    void remove_check_files()
55    {
56       for (std::set<std::string>::iterator it= used_check_files.begin();
57             it != used_check_files.end();
58             ++it)
59       {
60          std::string filepath(*it);
61          if (path_exists(filepath))
62          {
63             unlink(filepath);
64          }
65          //TODO
66       }
67       used_check_files.clear();
68    } // eo remove_check_files
69
70 public:
71     TestTimeFuncFixture()
72     {
73     }
74
75     ~TestTimeFuncFixture()
76     {
77         remove_check_files();
78     }
79 };
80
81 BOOST_FIXTURE_TEST_SUITE(TestTimeFunc, TestTimeFuncFixture)
82
83 BOOST_AUTO_TEST_CASE(AddIntervalsDisjoint)
84 {
85     Intervals intervals;
86
87     intervals.add( Interval( 10, 100 ) );
88     intervals.add( Interval( 600, 620 ) );
89
90     BOOST_CHECK_EQUAL( false, intervals.empty() );
91     BOOST_CHECK_EQUAL( 2u, intervals.size() );
92
93     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
94     BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
95
96     BOOST_CHECK_EQUAL( 600u, intervals.back().lower_bound() );
97     BOOST_CHECK_EQUAL( 620u, intervals.back().upper_bound() );
98 } // eo AddIntervalsDisjoint()
99
100
101
102 BOOST_AUTO_TEST_CASE(AddIntervalsInclude)
103 {
104     Intervals intervals;
105
106     intervals.add( Interval( 10, 100 ) );
107     intervals.add( Interval( 10, 80 ) );
108
109     BOOST_CHECK_EQUAL( false, intervals.empty() );
110     BOOST_CHECK_EQUAL( 1u, intervals.size() );
111
112     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
113     BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
114     BOOST_CHECK_EQUAL( false, intervals.front().changed() );
115 } // eo AddIntervalsInclude()
116
117
118
119 BOOST_AUTO_TEST_CASE(AddIntervalsEmbrace)
120 {
121     Intervals intervals;
122
123     intervals.add( Interval( 10, 100 ) );
124     intervals.add( Interval( 5, 120 ) );
125
126     BOOST_CHECK_EQUAL( false, intervals.empty() );
127     BOOST_CHECK_EQUAL( 1u, intervals.size() );
128
129     BOOST_CHECK_EQUAL( 5u, intervals.front().lower_bound() );
130     BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() );
131     BOOST_CHECK_EQUAL( true, intervals.front().changed() );
132 } // eo AddIntervalsEmbrace()
133
134
135
136 BOOST_AUTO_TEST_CASE(AddIntervalsJoin1)
137 {
138     Intervals intervals;
139
140     intervals.add( Interval( 10, 100 ) );
141     intervals.add( Interval( 60, 120 ) );
142
143     BOOST_CHECK_EQUAL( false, intervals.empty() );
144     BOOST_CHECK_EQUAL( 1u, intervals.size() );
145
146     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
147     BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() );
148     BOOST_CHECK_EQUAL( true, intervals.front().changed() );
149 } // eo AddIntervalsJoin1()
150
151
152
153 BOOST_AUTO_TEST_CASE(AddIntervalsJoin1b)
154 {
155     Intervals intervals;
156
157     intervals.add( Interval( 10, 100 ) );
158     intervals.add( Interval( 100, 120 ) );
159
160     BOOST_CHECK_EQUAL( false, intervals.empty() );
161     BOOST_CHECK_EQUAL( 1u, intervals.size() );
162
163     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
164     BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() );
165     BOOST_CHECK_EQUAL( true, intervals.front().changed() );
166 } // eo AddIntervalsJoin1b()
167
168
169
170 BOOST_AUTO_TEST_CASE(AddIntervalsJoin2)
171 {
172     Intervals intervals;
173
174     intervals.add( Interval( 10, 100 ) );
175     intervals.add( Interval( 200, 250 ) );
176
177     BOOST_CHECK_EQUAL( false, intervals.empty() );
178     BOOST_CHECK_EQUAL( 2u, intervals.size() );
179
180     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
181     BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
182     BOOST_CHECK_EQUAL( 200u, intervals.back().lower_bound() );
183     BOOST_CHECK_EQUAL( 250u, intervals.back().upper_bound() );
184
185     // now add the gap; the intervals should collapse to one covering all:
186     intervals.add( Interval(100, 200) );
187
188     BOOST_CHECK_EQUAL( false, intervals.empty() );
189     BOOST_CHECK_EQUAL( 1u, intervals.size() );
190
191     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
192     BOOST_CHECK_EQUAL( 250u, intervals.front().upper_bound() );
193     BOOST_CHECK_EQUAL( true, intervals.front().changed() );
194 } // eo AddIntervalsJoin2()
195
196
197
198 BOOST_AUTO_TEST_CASE(SubIntervalsDisjoint)
199 {
200     Intervals intervals;
201
202     intervals.add( Interval(10, 100) );
203     intervals.sub( Interval(0, 10) );
204
205     BOOST_CHECK_EQUAL( false, intervals.empty() );
206     BOOST_CHECK_EQUAL( 1u, intervals.size() );
207
208     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
209     BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
210     BOOST_CHECK_EQUAL( false, intervals.front().changed() );
211 } // eo SubIntervalsDisjoint()
212
213
214
215 BOOST_AUTO_TEST_CASE(SubIntervalsExact)
216 {
217     Intervals intervals;
218
219     intervals.add( Interval(10, 100) );
220     intervals.sub( Interval(10, 100) );
221
222     BOOST_CHECK_EQUAL( true, intervals.empty() );
223     BOOST_CHECK_EQUAL( 0u, intervals.size() );
224 } // eo SubIntervalsExact()
225
226
227
228 BOOST_AUTO_TEST_CASE(SubIntervalsSplit1)
229 {
230     Intervals intervals;
231
232     intervals.add( Interval(10, 100) );
233     intervals.sub( Interval(20, 40) );
234
235     BOOST_CHECK_EQUAL( false, intervals.empty() );
236     BOOST_CHECK_EQUAL( 2u, intervals.size() );
237
238     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
239     BOOST_CHECK_EQUAL( 20u, intervals.front().upper_bound() );
240
241     BOOST_CHECK_EQUAL( 40u, intervals.back().lower_bound() );
242     BOOST_CHECK_EQUAL( 100u, intervals.back().upper_bound() );
243     BOOST_CHECK_EQUAL( false, intervals.front().changed() );
244     BOOST_CHECK_EQUAL( true, intervals.back().changed() );
245 } // eo SubIntervalsSplit1()
246
247
248 BOOST_AUTO_TEST_CASE(SubIntervalsCutFront)
249 {
250     Intervals intervals;
251
252     intervals.add( Interval(10, 100) );
253     intervals.sub( Interval(10, 20) );
254
255     BOOST_CHECK_EQUAL( false, intervals.empty() );
256     BOOST_CHECK_EQUAL( 1u, intervals.size() );
257
258     BOOST_CHECK_EQUAL( 20u, intervals.front().lower_bound() );
259     BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
260     BOOST_CHECK_EQUAL( true, intervals.front().changed() );
261 } // eo SubIntervalsCutFront()
262
263
264 BOOST_AUTO_TEST_CASE(SubIntervalsCutBack)
265 {
266     Intervals intervals;
267
268     intervals.add( Interval(10, 100) );
269     intervals.sub( Interval(87, 100) );
270
271     BOOST_CHECK_EQUAL( false, intervals.empty() );
272     BOOST_CHECK_EQUAL( 1u, intervals.size() );
273
274     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
275     BOOST_CHECK_EQUAL( 87u, intervals.front().upper_bound() );
276     BOOST_CHECK_EQUAL( true, intervals.front().changed() );
277 } // eo SubIntervalsCutBack()
278
279
280
281 BOOST_AUTO_TEST_CASE(SubIntervalsCutMore)
282 {
283     Intervals intervals;
284
285     intervals.add( Interval( 10, 100) );
286     intervals.add( Interval(110, 200) );
287     intervals.add( Interval(210, 300) );
288
289     // this should remove the first 2 intervals and cut the third:
290     intervals.sub( Interval(8, 220) );
291
292     BOOST_CHECK_EQUAL( false, intervals.empty() );
293     BOOST_CHECK_EQUAL( 1u, intervals.size() );
294
295     BOOST_CHECK_EQUAL( 220u, intervals.front().lower_bound() );
296     BOOST_CHECK_EQUAL( 300u, intervals.front().upper_bound() );
297     BOOST_CHECK_EQUAL( true, intervals.front().changed() );
298 } // eo SubIntervalsCutMore()
299
300
301 BOOST_AUTO_TEST_CASE(IntervalComparisons)
302 {
303     Intervals intervals1;
304     Intervals intervals2;
305
306     intervals1.add( Interval( 10, 120) );
307
308     intervals2.add( Interval( 10, 110 ) );
309     intervals2.add( Interval( 100, 120 ) );
310
311     BOOST_CHECK_EQUAL( 1u, intervals2.size() );
312
313     BOOST_CHECK( intervals1 == intervals2 );
314     BOOST_CHECK_EQUAL( true, intervals1.contains( intervals2 ));
315     BOOST_CHECK_EQUAL( true, intervals2.contains( intervals1 ));
316
317     intervals2.sub( Interval( 40, 50) );
318
319     BOOST_CHECK( intervals1 != intervals2 );
320     BOOST_CHECK_EQUAL( true, intervals1.contains( intervals2 ));
321     BOOST_CHECK_EQUAL( false, intervals2.contains( intervals1 ));
322 } // eo IntervalComparisons()
323
324
325
326 BOOST_AUTO_TEST_CASE(MonotonicClock)
327 {
328     long sec0, nsec0;
329     long sec1, nsec1;
330
331     bool res = monotonic_clock_gettime(sec0,nsec0);
332     BOOST_CHECK_EQUAL( true, res );
333
334     usleep(250000);
335     res= monotonic_clock_gettime(sec1,nsec1);
336     BOOST_CHECK_EQUAL( true, res);
337
338     long delta_sec = sec1 - sec0;
339     long delta_nsec= nsec1 - nsec0;
340
341     long delta_millisec= ( delta_nsec / 1000000L) + delta_sec * 1000L;
342
343     BOOST_CHECK( delta_millisec >= 250 - /*fuzz*/ 1);
344     BOOST_CHECK( delta_millisec < 300 );
345 } // eo MonotonicClock()
346
347 BOOST_AUTO_TEST_CASE(WeekInvalid)
348 {
349     Week week("99999999");
350     BOOST_CHECK_EQUAL(false, week.is_valid());
351     BOOST_CHECK_EQUAL(string(""), week.get_displaystring());
352 }
353
354 BOOST_AUTO_TEST_CASE(WeekDisplayString1)
355 {
356     Week week("");
357     BOOST_CHECK_EQUAL(true, week.is_valid());
358     BOOST_CHECK_EQUAL(string(""), week.get_displaystring());
359 }
360
361 BOOST_AUTO_TEST_CASE(WeekDisplayString2)
362 {
363     Week week("0123456");
364     BOOST_CHECK_EQUAL(true, week.is_valid());
365     BOOST_CHECK_EQUAL(string("Mon-Sun"), week.get_displaystring());
366 }
367
368 BOOST_AUTO_TEST_CASE(WeekDisplayString3)
369 {
370     Week week("123456");
371     BOOST_CHECK_EQUAL(true, week.is_valid());
372     BOOST_CHECK_EQUAL(string("Mon-Sat"), week.get_displaystring());
373 }
374
375 BOOST_AUTO_TEST_CASE(WeekDisplayString4)
376 {
377     Week week("012345");
378     BOOST_CHECK_EQUAL(true, week.is_valid());
379     BOOST_CHECK_EQUAL(string("Mon-Fri, Sun"), week.get_displaystring());
380 }
381
382 BOOST_AUTO_TEST_CASE(WeekDisplayString5)
383 {
384     Week week("1256");
385     BOOST_CHECK_EQUAL(true, week.is_valid());
386     BOOST_CHECK_EQUAL(string("Mon, Tue, Fri, Sat"), week.get_displaystring());
387 }
388
389 BOOST_AUTO_TEST_CASE(WeekDisplayString6)
390 {
391     Week week("0246");
392     BOOST_CHECK_EQUAL(true, week.is_valid());
393     BOOST_CHECK_EQUAL(string("Tue, Thu, Sat, Sun"), week.get_displaystring());
394 }
395
396 BOOST_AUTO_TEST_CASE(WeekDisplayString7)
397 {
398     Week week("135");
399     BOOST_CHECK_EQUAL(true, week.is_valid());
400     BOOST_CHECK_EQUAL(string("Mon, Wed, Fri"), week.get_displaystring());
401 }
402
403 BOOST_AUTO_TEST_CASE(WeekDisplayString8)
404 {
405     Week week("15");
406     BOOST_CHECK_EQUAL(true, week.is_valid());
407     BOOST_CHECK_EQUAL(string("Mon, Fri"), week.get_displaystring());
408 }
409
410 BOOST_AUTO_TEST_CASE(WeekDisplayString9)
411 {
412     Week week("06");
413     BOOST_CHECK_EQUAL(true, week.is_valid());
414     BOOST_CHECK_EQUAL(string("Sat, Sun"), week.get_displaystring());
415 }
416
417 BOOST_AUTO_TEST_CASE(WeekDisplayString10)
418 {
419     Week week("056");
420     BOOST_CHECK_EQUAL(true, week.is_valid());
421     BOOST_CHECK_EQUAL(string("Fri-Sun"), week.get_displaystring());
422 }
423
424 BOOST_AUTO_TEST_CASE(WeekDisplayString11)
425 {
426     Week week("0");
427     BOOST_CHECK_EQUAL(true, week.is_valid());
428     BOOST_CHECK_EQUAL(string("Sun"), week.get_displaystring());
429 }
430
431 BOOST_AUTO_TEST_CASE(WeekDisplayString12)
432 {
433     Week week("6");
434     BOOST_CHECK_EQUAL(true, week.is_valid());
435     BOOST_CHECK_EQUAL(string("Sat"), week.get_displaystring());
436 }
437
438 BOOST_AUTO_TEST_CASE(WeekDisplayString13)
439 {
440     Week week("123");
441     BOOST_CHECK_EQUAL(true, week.is_valid());
442     BOOST_CHECK_EQUAL(string("Mon-Wed"), week.get_displaystring());
443 }
444
445 BOOST_AUTO_TEST_CASE(FormatFullTime)
446 {
447     time_t seconds = 1318844005;
448
449     BOOST_CHECK_EQUAL("17.10.2011 11:33", format_full_time(seconds));
450 }
451
452 BOOST_AUTO_TEST_CASE(DateToSeconds1)
453 {
454     // no DST
455     BOOST_CHECK_EQUAL(1325372400, date_to_seconds("2012-01-01"));
456 }
457
458 BOOST_AUTO_TEST_CASE(DateToSeconds2)
459 {
460     // DST
461     BOOST_CHECK_EQUAL(1341093600, date_to_seconds("2012-07-01"));
462 }
463
464 BOOST_AUTO_TEST_CASE(FormatISO8601_T)
465 {
466     const time_t moment = 1515492684;
467     BOOST_CHECK_EQUAL("10:11:24",
468                       format_iso8601 (moment, true, false, true, false));
469 }
470
471 BOOST_AUTO_TEST_CASE(FormatISO8601_TZ_local)
472 {
473     const time_t moment = 1515492684;
474     BOOST_CHECK_EQUAL("11:11:24Z+0100",
475                       format_iso8601 (moment, false, false, true, true));
476 }
477
478 BOOST_AUTO_TEST_CASE(FormatISO8601_TZ)
479 {
480     const time_t moment = 1515492684;
481     BOOST_CHECK_EQUAL("10:11:24Z+0000",
482                       format_iso8601 (moment, true, false, true, true));
483 }
484
485 BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_local)
486 {
487     const time_t moment = 1515492684;
488     BOOST_CHECK_EQUAL("2018-01-09T11:11:24Z+0100",
489                       format_iso8601 (moment, false, true, true, true));
490 }
491
492 BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ)
493 {
494     const time_t moment = 1515492684;
495     BOOST_CHECK_EQUAL("2018-01-09T10:11:24Z+0000",
496                       format_iso8601 (moment, true, true, true, true));
497 }
498
499 BOOST_AUTO_TEST_CASE(FormatISO8601_DT)
500 {
501     const time_t moment = 1515492684;
502     BOOST_CHECK_EQUAL("2018-01-09T10:11:24",
503                       format_iso8601 (moment, true, true, true, false));
504 }
505
506 BOOST_AUTO_TEST_CASE(FormatISO8601_D)
507 {
508     const time_t moment = 1515492684;
509     BOOST_CHECK_EQUAL("2018-01-09",
510                       format_iso8601 (moment, true, true, false, false));
511 }
512
513 BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_struct_tm)
514 {
515     struct tm helau;
516     helau.tm_sec    = 11;
517     helau.tm_min    = 11;
518     helau.tm_hour   = 11;
519     helau.tm_mday   = 11;
520     helau.tm_mon    = 10;
521     helau.tm_year   = 2018 - 1900;
522     helau.tm_wday   = 0;
523     helau.tm_yday   = 315;
524     helau.tm_isdst  = 0;
525     helau.tm_gmtoff = 0;
526     helau.tm_zone   = NULL;
527
528     BOOST_CHECK_EQUAL("2018-11-11T11:11:11Z+0000",
529                       format_iso8601 (helau, true, true, true));
530 }
531
532 BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_struct_timespec)
533 {
534     struct timespec ts = { 1541934671, 11 };
535
536     BOOST_CHECK_EQUAL("2018-11-11T11:11:11Z+0000",
537                       format_iso8601 (ts, true, true, true, true));
538 }
539
540 BOOST_AUTO_TEST_SUITE(Clock)
541
542     BOOST_AUTO_TEST_CASE(ctor_simple)
543     {
544         I2n::clock::Time t;
545
546         BOOST_CHECK_EQUAL(t.get_sec  (), 0);
547         BOOST_CHECK_EQUAL(t.get_nsec (), 0);
548     }
549
550     BOOST_AUTO_TEST_CASE(ctor_type)
551     {
552         I2n::clock::Time t (I2n::clock::type::real);
553
554         BOOST_CHECK_EQUAL(t.get_sec  (), 0);
555         BOOST_CHECK_EQUAL(t.get_nsec (), 0);
556     }
557
558     BOOST_AUTO_TEST_CASE(ctor_variant)
559     {
560         I2n::clock::Time t (I2n::clock::type::cpu,
561                             I2n::clock::type::thread);
562
563         BOOST_CHECK_EQUAL(t.get_sec  (), 0);
564         BOOST_CHECK_EQUAL(t.get_nsec (), 0);
565     }
566
567     BOOST_AUTO_TEST_CASE(initializer_now)
568     {
569         boost::optional<I2n::clock::Time> t = I2n::clock::now ();
570
571         BOOST_CHECK(t);
572         BOOST_CHECK_GT(t->get_sec (), 0);
573         BOOST_CHECK_EQUAL(t->err, 0);
574     }
575
576     BOOST_AUTO_TEST_CASE(initializer_zero)
577     {
578         I2n::clock::Time stundenull = I2n::clock::zero ();
579
580         BOOST_CHECK_EQUAL(stundenull.get_sec  (), 0);
581         BOOST_CHECK_EQUAL(stundenull.get_nsec (), 0);
582         BOOST_CHECK_EQUAL(stundenull.err, 0);
583     }
584
585     BOOST_AUTO_TEST_CASE(member_set_now)
586     {
587         I2n::clock::Time t;
588
589         BOOST_CHECK(t.set ());
590
591         BOOST_CHECK_NE(t.get_sec (), 0);
592     }
593
594     BOOST_AUTO_TEST_CASE(member_set_value)
595     {
596         I2n::clock::Time t;
597
598         t.set (42, 42);
599
600         BOOST_CHECK_EQUAL(t.get_sec  (), 42);
601         BOOST_CHECK_EQUAL(t.get_nsec (), 42);
602     }
603
604     BOOST_AUTO_TEST_CASE(member_set_value_type)
605     {
606         I2n::clock::Time t;
607
608         t.set (42, 42, I2n::clock::type::real, I2n::clock::type::exact);
609
610         BOOST_CHECK_EQUAL(t.get_sec  (), 42);
611         BOOST_CHECK_EQUAL(t.get_nsec (), 42);
612     }
613
614     BOOST_AUTO_TEST_CASE(member_add_parts)
615     {
616         I2n::clock::Time t;
617
618         t.set (42, 42);
619         t.add (2187, 2187);
620
621         BOOST_CHECK_EQUAL(t.get_sec  (), 2229);
622         BOOST_CHECK_EQUAL(t.get_nsec (), 2229);
623     }
624
625     BOOST_AUTO_TEST_CASE(member_sub_parts)
626     {
627         I2n::clock::Time t;
628
629         t.set (2, 0L);
630         t.subtract (1, 1L);
631
632         BOOST_CHECK_EQUAL(t.get_sec  (), 0);
633         BOOST_CHECK_EQUAL(t.get_nsec (), 999999999);
634     }
635
636     BOOST_AUTO_TEST_CASE(member_sub_Time)
637     {
638         I2n::clock::Time t1;
639         I2n::clock::Time t2;
640
641         t1.set (42, 42L);
642         t2.set (42,  0L);
643
644         t1.subtract (t2);
645
646         BOOST_CHECK_EQUAL(t1.get_sec  (),  0);
647         BOOST_CHECK_EQUAL(t1.get_nsec (), 42L);
648     }
649
650     BOOST_AUTO_TEST_CASE(member_diff)
651     {
652         static const time_t five = 5 * 365 * 24 * 3600;
653
654         I2n::clock::Time t1 (42, 1337);
655         I2n::clock::Time t2 = t1 + five;;
656         I2n::clock::Time t3 = t1 - five;;
657
658         BOOST_CHECK_EQUAL(t2, I2n::clock::Time ((time_t)42 + five, 1337));
659         BOOST_CHECK_EQUAL(t3, I2n::clock::Time ((time_t)42 - five, 1337));
660         BOOST_CHECK_EQUAL(t1.difference (t3), t3.difference (t1));
661         BOOST_CHECK_EQUAL(t3.difference (t3), t3.difference (t3));
662     }
663
664     BOOST_AUTO_TEST_CASE(op_copyassign)
665     {
666         I2n::clock::Time t1;
667         I2n::clock::Time t2;
668
669         BOOST_CHECK(t1.set ());
670
671         t2 = t1;
672
673         BOOST_CHECK_EQUAL(t1.get_sec  (), t2.get_sec  ());
674         BOOST_CHECK_EQUAL(t1.get_nsec (), t2.get_nsec ());
675     }
676
677     BOOST_AUTO_TEST_CASE(op_equal)
678     {
679         I2n::clock::Time t1;
680         I2n::clock::Time t2;
681
682         BOOST_CHECK(t1.set ());
683         t2 = t1;
684
685         BOOST_CHECK_EQUAL(t1, t2);
686     }
687
688     BOOST_AUTO_TEST_CASE(op_add_Time)
689     {
690         I2n::clock::Time t1;
691         I2n::clock::Time t2;
692         I2n::clock::Time tsum;
693
694         t1.set (2187, 2187);
695         t2.set (1337, 1337);
696         tsum = t1 + t2;
697
698         BOOST_CHECK_EQUAL(tsum.get_sec  (), 3524);
699         BOOST_CHECK_EQUAL(tsum.get_nsec (), 3524);
700     }
701
702     BOOST_AUTO_TEST_CASE(op_add_Time_carry)
703     {
704         I2n::clock::Time t1;
705         I2n::clock::Time t2;
706         I2n::clock::Time tsum;
707
708         t1.set (2187, 2187);
709         t2.set (1300, 37L * 1000 * 1000 * 1000 + 1337);
710
711         tsum = t1 + t2;
712
713         BOOST_CHECK_EQUAL(tsum.get_sec  (), 3524);
714         BOOST_CHECK_EQUAL(tsum.get_nsec (), 3524);
715     }
716
717     BOOST_AUTO_TEST_CASE(op_add_time_t)
718     {
719         I2n::clock::Time t1 (2187, 2187);
720         time_t           t2 = 1337;
721         I2n::clock::Time tsum;
722
723         tsum = t1 + t2;
724
725         BOOST_CHECK_EQUAL(tsum.get_sec  (), 3524);
726         BOOST_CHECK_EQUAL(tsum.get_nsec (), 2187);
727     }
728
729     BOOST_AUTO_TEST_CASE(op_add_time_t_external)
730     {
731         time_t           t1 = 1337;
732         I2n::clock::Time t2 (2187, 2187);
733         I2n::clock::Time tsum;
734
735         tsum = t1 + t2;
736
737         BOOST_CHECK_EQUAL(tsum.get_sec  (), 3524);
738         BOOST_CHECK_EQUAL(tsum.get_nsec (), 2187);
739     }
740
741     BOOST_AUTO_TEST_CASE(op_incr_Time)
742     {
743         I2n::clock::Time t1 (2187, 2187);
744         I2n::clock::Time t2 (1337, 1337);
745
746         t1 += t2;
747
748         BOOST_CHECK_EQUAL(t1.get_sec  (), 3524);
749         BOOST_CHECK_EQUAL(t1.get_nsec (), 3524);
750     }
751
752     BOOST_AUTO_TEST_CASE(op_incr_time_t)
753     {
754         I2n::clock::Time t1 (2187, 2187);
755         time_t           t2 = 1337;
756
757         t1 += t2;
758
759         BOOST_CHECK_EQUAL(t1.get_sec  (), 3524);
760         BOOST_CHECK_EQUAL(t1.get_nsec (), 2187);
761     }
762
763     BOOST_AUTO_TEST_CASE(op_subtract_Time)
764     {
765         I2n::clock::Time t1;
766         I2n::clock::Time t2;
767         I2n::clock::Time tdiff;
768
769         t1.set (2187, 2187);
770         t2.set (1337, 1337);
771         tdiff = t1 - t2;
772
773         BOOST_CHECK_EQUAL(tdiff.get_sec  (), 850);
774         BOOST_CHECK_EQUAL(tdiff.get_nsec (), 850);
775     }
776
777     BOOST_AUTO_TEST_CASE(op_subtract_time_t)
778     {
779         I2n::clock::Time t1 (2187, 2187);
780         time_t           t2 = 1337;
781         I2n::clock::Time tdiff;
782
783         tdiff = t1 - t2;
784
785         BOOST_CHECK_EQUAL(tdiff.get_sec  (), 850);
786         BOOST_CHECK_EQUAL(tdiff.get_nsec (), 2187);
787     }
788
789     BOOST_AUTO_TEST_CASE(op_subtract_time_t_external)
790     {
791         time_t           t1 = 1337;
792         I2n::clock::Time t2 (2187, 2187);
793         I2n::clock::Time tdiff;
794
795         tdiff = t1 - t2;
796
797         BOOST_CHECK_EQUAL(tdiff.get_sec  (), -851);
798         BOOST_CHECK_EQUAL(tdiff.get_nsec (), 999997813);
799     }
800
801     BOOST_AUTO_TEST_CASE(op_decr_Time)
802     {
803         I2n::clock::Time t1 (2187, 2187);
804         I2n::clock::Time t2 (1337, 1337);
805
806         t1 -= t2;
807
808         BOOST_CHECK_EQUAL(t1.get_sec  (), 850);
809         BOOST_CHECK_EQUAL(t1.get_nsec (), 850);
810     }
811
812     BOOST_AUTO_TEST_CASE(op_decr_time_t)
813     {
814         I2n::clock::Time t1 (2187, 2187);
815         time_t           t2 = 1337;
816
817         t1 -= t2;
818
819         BOOST_CHECK_EQUAL(t1.get_sec  (), 850);
820         BOOST_CHECK_EQUAL(t1.get_nsec (), 2187);
821     }
822
823     BOOST_AUTO_TEST_CASE(op_mult_scale)
824     {
825         I2n::clock::Time t1;
826         I2n::clock::Time t2;
827
828         t1.set (1, 1);
829         t2 = t1 * 42;
830
831         BOOST_CHECK_EQUAL(t2.get_sec  (), 42);
832         BOOST_CHECK_EQUAL(t2.get_nsec (), 42);
833     }
834
835     BOOST_AUTO_TEST_CASE(op_mult_mutate)
836     {
837         I2n::clock::Time t1 (  42, 42);
838         I2n::clock::Time t2 (1337,  0);
839
840         t1 *=   2;
841         t2 *= -10;
842
843         BOOST_CHECK_EQUAL(t1.get_sec  (),     84);
844         BOOST_CHECK_EQUAL(t1.get_nsec (),     84);
845         BOOST_CHECK_EQUAL(t2.get_sec  (), -13370);
846     }
847
848     BOOST_AUTO_TEST_CASE(op_mult_scale_carry)
849     {
850         I2n::clock::Time t1;
851         I2n::clock::Time t2;
852
853         t1.set (1, 500 * 1000 * 1000);
854         t2 = t1 * 3;
855
856         BOOST_CHECK_EQUAL(t2.get_sec  (),  4);
857         BOOST_CHECK_EQUAL(t2.get_nsec (),  500 * 1000 * 1000);
858     }
859
860     BOOST_AUTO_TEST_CASE(op_equals)
861     {
862         I2n::clock::Time t1;
863         I2n::clock::Time t2;
864
865         t1.set (50, 50);
866         t2.set (50, 50);
867
868         BOOST_CHECK_EQUAL(t1, t2);
869     }
870
871     BOOST_AUTO_TEST_CASE(compare_equal)
872     {
873         I2n::clock::Time t1;
874         I2n::clock::Time t2;
875
876         t1.set (42, 42);
877         t2.set (42, 42);
878
879         BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), 0);
880     }
881
882     BOOST_AUTO_TEST_CASE(compare_equal_type)
883     {
884         I2n::clock::Time t1 (42, 42, I2n::clock::type::real);
885         I2n::clock::Time t2 (42, 42, I2n::clock::type::cpu);
886         I2n::clock::Time t3 (42,  0, I2n::clock::type::real);
887         I2n::clock::Time t4 (42, 42, I2n::clock::type::real);
888
889         BOOST_CHECK_NE(t1, t2);
890         BOOST_CHECK_NE(t1, t3);
891         BOOST_CHECK_EQUAL(t1, t4);
892     }
893
894     BOOST_AUTO_TEST_CASE(compare_ne_sec)
895     {
896         I2n::clock::Time t1;
897         I2n::clock::Time t2;
898
899         t1.set (  42, 42);
900         t2.set (1337, 42);
901
902         BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), -1);
903         BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1),  1);
904     }
905
906     BOOST_AUTO_TEST_CASE(compare_ne_nsec)
907     {
908         I2n::clock::Time t1;
909         I2n::clock::Time t2;
910
911         t1.set (42,   42);
912         t2.set (42, 1337);
913
914         BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), -1);
915         BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1),  1);
916     }
917
918     BOOST_AUTO_TEST_CASE(compare_ne_both)
919     {
920         I2n::clock::Time t1;
921         I2n::clock::Time t2;
922
923         t1.set (42, 2187);
924         t2.set (23, 1337);
925
926         BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2),  1);
927         BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1), -1);
928     }
929
930     BOOST_AUTO_TEST_CASE(op_ineq_sec)
931     {
932         I2n::clock::Time t1 (1337);
933         I2n::clock::Time t2 (2187);
934
935         BOOST_CHECK_LT(t1, t2);
936         BOOST_CHECK_GT(t2, t1);
937     }
938
939     BOOST_AUTO_TEST_CASE(op_ineq_nsec)
940     {
941         I2n::clock::Time t1 (1337, 23);
942         I2n::clock::Time t2 (1337, 42);
943
944         BOOST_CHECK_LT(t1, t2);
945         BOOST_CHECK_GT(t2, t1);
946     }
947
948     BOOST_AUTO_TEST_CASE(op_ineq_both)
949     {
950         I2n::clock::Time t1 (2187, 23);
951         I2n::clock::Time t2 (1337, 42);
952
953         BOOST_CHECK_LT(t2, t1);
954         BOOST_CHECK_GT(t1, t2);
955     }
956
957     BOOST_AUTO_TEST_CASE(op_eq_time_t)
958     {
959         boost::optional<I2n::clock::Time> t1  = I2n::clock::now ();
960         const time_t                      t2  = time (NULL); /* race here */
961
962         *t1 -= (time_t)42;
963
964         BOOST_CHECK_NE(*t1,  t2);
965         BOOST_CHECK_LT(*t1,  t2);
966         BOOST_CHECK_GT( t2, *t1);
967     }
968
969     BOOST_AUTO_TEST_CASE(FormatISO8601_T)
970     {
971         I2n::clock::Time t (42, 42);
972         boost::optional<std::string> s = t.format_iso8601 (true, false, true, false);
973
974         BOOST_CHECK_EQUAL("00:00:42", *s);
975     }
976
977     BOOST_AUTO_TEST_CASE(FormatISO8601_DT)
978     {
979         I2n::clock::Time t (1541934671, 0);
980         boost::optional<std::string> s = t.format_iso8601 (true, true, true, false);
981
982         BOOST_CHECK_EQUAL("2018-11-11T11:11:11", *s);
983     }
984
985     BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ)
986     {
987         I2n::clock::Time t (1541934671, 0);
988         boost::optional<std::string> s = t.format_iso8601 (true, true, true, true);
989
990         BOOST_CHECK_EQUAL("2018-11-11T11:11:11Z+0000", *s);
991     }
992
993     BOOST_AUTO_TEST_CASE(Format_make_nice_time)
994     {
995         I2n::clock::Time t (111111, 0);
996         boost::optional<std::string> s = t.make_nice_time ();
997
998         BOOST_CHECK_EQUAL("1 day, 06:51:51", *s);
999     }
1000
1001     BOOST_AUTO_TEST_CASE(Format_format_full_time)
1002     {
1003         I2n::clock::Time t (1541934671, 0);
1004         /*
1005          * brr, the old formatters use localtime without a way to opt out of
1006          * it!
1007          */
1008         setenv ("TZ", "UTC", 1);
1009         tzset();
1010         boost::optional<std::string> s = t.format_full_time ();
1011
1012         BOOST_CHECK_EQUAL("11.11.2018 11:11", *s);
1013     }
1014
1015     BOOST_AUTO_TEST_CASE(Format_format_date)
1016     {
1017         I2n::clock::Time t (1541934671, 0);
1018         boost::optional<std::string> s = t.format_date ();
1019
1020         BOOST_CHECK_EQUAL("11.11.2018", *s);
1021     }
1022
1023     BOOST_AUTO_TEST_CASE(FromString_iso8601_full)
1024     {
1025         const std::string in1 ("0001-01-01T00:00:00Z+0000");
1026         const std::string in2 ("2018-11-11T11:11:11Z+0000");
1027
1028         boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1);
1029         boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2);
1030
1031         BOOST_CHECK(t1);
1032         BOOST_CHECK(t2);
1033
1034         BOOST_CHECK_EQUAL(*t1->format_iso8601 (), in1);
1035         BOOST_CHECK_EQUAL(*t2->format_iso8601 (), in2);
1036     }
1037
1038     BOOST_AUTO_TEST_CASE(FromString_iso8601_full_negyear)
1039     {
1040         const std::string in1 ("-0001-01-01T00:00:00Z+0000");
1041         const std::string in2 ("-2018-11-11T11:11:11Z+0000");
1042
1043         boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1);
1044         boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2);
1045
1046         BOOST_CHECK(t1);
1047         BOOST_CHECK(t2);
1048
1049         BOOST_CHECK_EQUAL(*t1->format_iso8601 (), in1);
1050         BOOST_CHECK_EQUAL(*t2->format_iso8601 (), in2);
1051     }
1052
1053     BOOST_AUTO_TEST_CASE(FromString_iso8601_partial)
1054     {
1055         const std::string in1 ("2018-11-11T11:11:11");
1056         const std::string in2 ("2018-11-11");
1057         const std::string in3 ("11:11:11");
1058
1059         boost::optional<I2n::clock::Time> t1 =
1060             I2n::clock::time_of_iso8601 (in1, true, true, false);
1061         boost::optional<I2n::clock::Time> t2 =
1062             I2n::clock::time_of_iso8601 (in2, true, false, false);
1063         boost::optional<I2n::clock::Time> t3 =
1064             I2n::clock::time_of_iso8601 (in3, false, true, false);
1065
1066         BOOST_CHECK(t1);
1067         BOOST_CHECK(t2);
1068         BOOST_CHECK(t3);
1069         /*
1070          * We test for the difference here which is zero if the number is
1071          * correct but causes the difference from the expected value to be
1072          * printed in case the test fails.
1073          */
1074         BOOST_CHECK_EQUAL(*t1->format_iso8601 (true,  true,  true, false), in1);
1075         BOOST_CHECK_EQUAL(*t2->format_iso8601 (true,  true, false, false), in2);
1076         BOOST_CHECK_EQUAL(*t3->format_iso8601 (true, false,  true, false), in3);
1077     }
1078
1079     BOOST_AUTO_TEST_CASE(containers_list)
1080     {
1081         std::list<I2n::clock::Time> ts;
1082
1083         ts.push_back (I2n::clock::zero ());
1084         ts.push_back (I2n::clock::zero ());
1085
1086         BOOST_CHECK_EQUAL(ts.size (), 2);
1087     }
1088
1089     BOOST_AUTO_TEST_CASE(containers_vec)
1090     {
1091         std::vector<I2n::clock::Time> ts;
1092
1093         ts.push_back (I2n::clock::zero ());
1094         ts.push_back (I2n::clock::zero ());
1095
1096         BOOST_CHECK_EQUAL(ts.size (), 2);
1097     }
1098
1099     BOOST_AUTO_TEST_CASE(containers_set)
1100     {
1101         std::set<I2n::clock::Time> ts;
1102
1103         ts.insert (I2n::clock::zero ());
1104         ts.insert (I2n::clock::Time (42, 2187));
1105         ts.insert (I2n::clock::zero ());
1106
1107         BOOST_CHECK_EQUAL(ts.size (), 2);
1108     }
1109
1110     BOOST_AUTO_TEST_CASE(containers_list_mean)
1111     {
1112         std::list<I2n::clock::Time> ts;
1113
1114         ts.push_back (I2n::clock::Time (42, 42));
1115         ts.push_back (I2n::clock::Time (1337, 1337));
1116
1117         BOOST_CHECK_EQUAL(I2n::clock::mean (ts),
1118                           I2n::clock::Time (689, 500000689));
1119     }
1120
1121     BOOST_AUTO_TEST_CASE(containers_list_mean_zero)
1122     {
1123         std::list<I2n::clock::Time> ts;
1124
1125         ts.push_back (I2n::clock::Time (0, 0));
1126         ts.push_back (I2n::clock::Time (0, 0));
1127         ts.push_back (I2n::clock::Time (0, 0));
1128         ts.push_back (I2n::clock::Time (0, 0));
1129
1130         BOOST_CHECK_EQUAL(I2n::clock::mean (ts),
1131                           I2n::clock::zero ());
1132     }
1133
1134     BOOST_AUTO_TEST_CASE(containers_list_mean_empty)
1135     {
1136         std::list<I2n::clock::Time> ts;
1137
1138         BOOST_CHECK_EQUAL(I2n::clock::mean (ts), I2n::clock::Time (0, 0));
1139     }
1140
1141     BOOST_AUTO_TEST_CASE(containers_set_mean)
1142     {
1143         std::set<I2n::clock::Time> ts;
1144
1145         ts.insert (I2n::clock::Time (42));
1146         ts.insert (I2n::clock::Time (1337));
1147         ts.insert (I2n::clock::Time (2187));
1148
1149         BOOST_CHECK_EQUAL(I2n::clock::mean (ts),
1150                           I2n::clock::Time (1188, 666666666));
1151     }
1152
1153     BOOST_AUTO_TEST_CASE(containers_set_median_empty)
1154     {
1155         std::set<I2n::clock::Time> ts;
1156
1157         BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (0, 0));
1158     }
1159
1160     BOOST_AUTO_TEST_CASE(containers_set_median_one)
1161     {
1162         std::set<I2n::clock::Time> ts;
1163
1164         ts.insert (I2n::clock::Time (42, 0));
1165
1166         BOOST_CHECK_EQUAL(I2n::clock::median (ts),
1167                           I2n::clock::Time (42, 0));
1168     }
1169
1170     BOOST_AUTO_TEST_CASE(containers_set_median_multi)
1171     {
1172         std::set<I2n::clock::Time> ts;
1173
1174         ts.insert (I2n::clock::Time (42));
1175         ts.insert (I2n::clock::Time (1337));
1176         ts.insert (I2n::clock::Time (2187));
1177
1178         BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (1337));
1179     }
1180
1181     BOOST_AUTO_TEST_CASE(containers_vec_median_multi)
1182     {
1183         std::vector<I2n::clock::Time> ts;
1184
1185         ts.push_back (I2n::clock::Time (42));
1186         ts.push_back (I2n::clock::Time (1337));
1187         ts.push_back (I2n::clock::Time (2187));
1188
1189         BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (1337));
1190     }
1191
1192     BOOST_AUTO_TEST_CASE(containers_list_median_multi)
1193     {
1194         std::list<I2n::clock::Time> ts;
1195
1196         ts.push_back (I2n::clock::Time (42));
1197         ts.push_back (I2n::clock::Time (1337));
1198         ts.push_back (I2n::clock::Time (2187));
1199         ts.push_back (I2n::clock::Time (0xcafebabe));
1200         ts.push_back (I2n::clock::Time (0xdeadbeef));
1201
1202         BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (2187));
1203     }
1204
1205     BOOST_AUTO_TEST_CASE(containers_list_median_multi_evensize)
1206     {
1207         std::list<I2n::clock::Time> ts;
1208
1209         ts.push_back (I2n::clock::Time (42));
1210         ts.push_back (I2n::clock::Time (1337));
1211         ts.push_back (I2n::clock::Time (2187));
1212         ts.push_back (I2n::clock::Time (0xf00d));
1213         ts.push_back (I2n::clock::Time (0xcafebabe));
1214         ts.push_back (I2n::clock::Time (0xdeadbeef));
1215
1216         BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (0xf00d));
1217     }
1218
1219 BOOST_AUTO_TEST_SUITE_END() /* [Clock] */
1220
1221 BOOST_AUTO_TEST_SUITE_END()