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