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