xref: /freebsd/contrib/kyua/utils/datetime_test.cpp (revision 7ef62cebc2f965b0f640263e179276928885e33d)
1 // Copyright 2010 The Kyua Authors.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 //   notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 //   notice, this list of conditions and the following disclaimer in the
12 //   documentation and/or other materials provided with the distribution.
13 // * Neither the name of Google Inc. nor the names of its contributors
14 //   may be used to endorse or promote products derived from this software
15 //   without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #include "utils/datetime.hpp"
30 
31 extern "C" {
32 #include <time.h>
33 #include <unistd.h>
34 }
35 
36 #include <sstream>
37 #include <stdexcept>
38 
39 #include <atf-c++.hpp>
40 
41 namespace datetime = utils::datetime;
42 
43 
44 ATF_TEST_CASE_WITHOUT_HEAD(delta__defaults);
45 ATF_TEST_CASE_BODY(delta__defaults)
46 {
47     const datetime::delta delta;
48     ATF_REQUIRE_EQ(0, delta.seconds);
49     ATF_REQUIRE_EQ(0, delta.useconds);
50 }
51 
52 
53 ATF_TEST_CASE_WITHOUT_HEAD(delta__overrides);
54 ATF_TEST_CASE_BODY(delta__overrides)
55 {
56     const datetime::delta delta(1, 2);
57     ATF_REQUIRE_EQ(1, delta.seconds);
58     ATF_REQUIRE_EQ(2, delta.useconds);
59 
60     ATF_REQUIRE_THROW_RE(
61         std::runtime_error, "Negative.*not supported.*-4999997us",
62         datetime::delta(-5, 3));
63 }
64 
65 
66 ATF_TEST_CASE_WITHOUT_HEAD(delta__from_microseconds);
67 ATF_TEST_CASE_BODY(delta__from_microseconds)
68 {
69     {
70         const datetime::delta delta = datetime::delta::from_microseconds(0);
71         ATF_REQUIRE_EQ(0, delta.seconds);
72         ATF_REQUIRE_EQ(0, delta.useconds);
73     }
74     {
75         const datetime::delta delta = datetime::delta::from_microseconds(
76             999999);
77         ATF_REQUIRE_EQ(0, delta.seconds);
78         ATF_REQUIRE_EQ(999999, delta.useconds);
79     }
80     {
81         const datetime::delta delta = datetime::delta::from_microseconds(
82             1000000);
83         ATF_REQUIRE_EQ(1, delta.seconds);
84         ATF_REQUIRE_EQ(0, delta.useconds);
85     }
86     {
87         const datetime::delta delta = datetime::delta::from_microseconds(
88             10576293);
89         ATF_REQUIRE_EQ(10, delta.seconds);
90         ATF_REQUIRE_EQ(576293, delta.useconds);
91     }
92     {
93         const datetime::delta delta = datetime::delta::from_microseconds(
94             123456789123456LL);
95         ATF_REQUIRE_EQ(123456789, delta.seconds);
96         ATF_REQUIRE_EQ(123456, delta.useconds);
97     }
98 
99     ATF_REQUIRE_THROW_RE(
100         std::runtime_error, "Negative.*not supported.*-12345us",
101         datetime::delta::from_microseconds(-12345));
102 }
103 
104 
105 ATF_TEST_CASE_WITHOUT_HEAD(delta__to_microseconds);
106 ATF_TEST_CASE_BODY(delta__to_microseconds)
107 {
108     ATF_REQUIRE_EQ(0, datetime::delta(0, 0).to_microseconds());
109     ATF_REQUIRE_EQ(999999, datetime::delta(0, 999999).to_microseconds());
110     ATF_REQUIRE_EQ(1000000, datetime::delta(1, 0).to_microseconds());
111     ATF_REQUIRE_EQ(10576293, datetime::delta(10, 576293).to_microseconds());
112     ATF_REQUIRE_EQ(11576293, datetime::delta(10, 1576293).to_microseconds());
113 }
114 
115 
116 ATF_TEST_CASE_WITHOUT_HEAD(delta__equals);
117 ATF_TEST_CASE_BODY(delta__equals)
118 {
119     ATF_REQUIRE(datetime::delta() == datetime::delta());
120     ATF_REQUIRE(datetime::delta() == datetime::delta(0, 0));
121     ATF_REQUIRE(datetime::delta(1, 2) == datetime::delta(1, 2));
122 
123     ATF_REQUIRE(!(datetime::delta() == datetime::delta(0, 1)));
124     ATF_REQUIRE(!(datetime::delta() == datetime::delta(1, 0)));
125     ATF_REQUIRE(!(datetime::delta(1, 2) == datetime::delta(2, 1)));
126 }
127 
128 
129 ATF_TEST_CASE_WITHOUT_HEAD(delta__differs);
130 ATF_TEST_CASE_BODY(delta__differs)
131 {
132     ATF_REQUIRE(!(datetime::delta() != datetime::delta()));
133     ATF_REQUIRE(!(datetime::delta() != datetime::delta(0, 0)));
134     ATF_REQUIRE(!(datetime::delta(1, 2) != datetime::delta(1, 2)));
135 
136     ATF_REQUIRE(datetime::delta() != datetime::delta(0, 1));
137     ATF_REQUIRE(datetime::delta() != datetime::delta(1, 0));
138     ATF_REQUIRE(datetime::delta(1, 2) != datetime::delta(2, 1));
139 }
140 
141 
142 ATF_TEST_CASE_WITHOUT_HEAD(delta__sorting);
143 ATF_TEST_CASE_BODY(delta__sorting)
144 {
145     ATF_REQUIRE(!(datetime::delta() <  datetime::delta()));
146     ATF_REQUIRE(  datetime::delta() <= datetime::delta());
147     ATF_REQUIRE(!(datetime::delta() >  datetime::delta()));
148     ATF_REQUIRE(  datetime::delta() >= datetime::delta());
149 
150     ATF_REQUIRE(!(datetime::delta(9, 8) <  datetime::delta(9, 8)));
151     ATF_REQUIRE(  datetime::delta(9, 8) <= datetime::delta(9, 8));
152     ATF_REQUIRE(!(datetime::delta(9, 8) >  datetime::delta(9, 8)));
153     ATF_REQUIRE(  datetime::delta(9, 8) >= datetime::delta(9, 8));
154 
155     ATF_REQUIRE(  datetime::delta(2, 5) <  datetime::delta(4, 8));
156     ATF_REQUIRE(  datetime::delta(2, 5) <= datetime::delta(4, 8));
157     ATF_REQUIRE(!(datetime::delta(2, 5) >  datetime::delta(4, 8)));
158     ATF_REQUIRE(!(datetime::delta(2, 5) >= datetime::delta(4, 8)));
159 
160     ATF_REQUIRE(  datetime::delta(2, 5) <  datetime::delta(2, 8));
161     ATF_REQUIRE(  datetime::delta(2, 5) <= datetime::delta(2, 8));
162     ATF_REQUIRE(!(datetime::delta(2, 5) >  datetime::delta(2, 8)));
163     ATF_REQUIRE(!(datetime::delta(2, 5) >= datetime::delta(2, 8)));
164 
165     ATF_REQUIRE(!(datetime::delta(4, 8) <  datetime::delta(2, 5)));
166     ATF_REQUIRE(!(datetime::delta(4, 8) <= datetime::delta(2, 5)));
167     ATF_REQUIRE(  datetime::delta(4, 8) >  datetime::delta(2, 5));
168     ATF_REQUIRE(  datetime::delta(4, 8) >= datetime::delta(2, 5));
169 
170     ATF_REQUIRE(!(datetime::delta(2, 8) <  datetime::delta(2, 5)));
171     ATF_REQUIRE(!(datetime::delta(2, 8) <= datetime::delta(2, 5)));
172     ATF_REQUIRE(  datetime::delta(2, 8) >  datetime::delta(2, 5));
173     ATF_REQUIRE(  datetime::delta(2, 8) >= datetime::delta(2, 5));
174 }
175 
176 
177 ATF_TEST_CASE_WITHOUT_HEAD(delta__addition);
178 ATF_TEST_CASE_BODY(delta__addition)
179 {
180     using datetime::delta;
181 
182     ATF_REQUIRE_EQ(delta(), delta() + delta());
183     ATF_REQUIRE_EQ(delta(0, 10), delta() + delta(0, 10));
184     ATF_REQUIRE_EQ(delta(10, 0), delta(10, 0) + delta());
185 
186     ATF_REQUIRE_EQ(delta(1, 234567), delta(0, 1234567) + delta());
187     ATF_REQUIRE_EQ(delta(12, 34), delta(10, 20) + delta(2, 14));
188 }
189 
190 
191 ATF_TEST_CASE_WITHOUT_HEAD(delta__addition_and_set);
192 ATF_TEST_CASE_BODY(delta__addition_and_set)
193 {
194     using datetime::delta;
195 
196     {
197         delta d;
198         d += delta(3, 5);
199         ATF_REQUIRE_EQ(delta(3, 5), d);
200     }
201     {
202         delta d(1, 2);
203         d += delta(3, 5);
204         ATF_REQUIRE_EQ(delta(4, 7), d);
205     }
206     {
207         delta d(1, 2);
208         ATF_REQUIRE_EQ(delta(4, 7), (d += delta(3, 5)));
209     }
210 }
211 
212 
213 ATF_TEST_CASE_WITHOUT_HEAD(delta__scale);
214 ATF_TEST_CASE_BODY(delta__scale)
215 {
216     using datetime::delta;
217 
218     ATF_REQUIRE_EQ(delta(), delta() * 0);
219     ATF_REQUIRE_EQ(delta(), delta() * 5);
220 
221     ATF_REQUIRE_EQ(delta(0, 30), delta(0, 10) * 3);
222     ATF_REQUIRE_EQ(delta(17, 500000), delta(3, 500000) * 5);
223 }
224 
225 
226 ATF_TEST_CASE_WITHOUT_HEAD(delta__scale_and_set);
227 ATF_TEST_CASE_BODY(delta__scale_and_set)
228 {
229     using datetime::delta;
230 
231     {
232         delta d(3, 5);
233         d *= 2;
234         ATF_REQUIRE_EQ(delta(6, 10), d);
235     }
236     {
237         delta d(8, 0);
238         d *= 8;
239         ATF_REQUIRE_EQ(delta(64, 0), d);
240     }
241     {
242         delta d(3, 5);
243         ATF_REQUIRE_EQ(delta(9, 15), (d *= 3));
244     }
245 }
246 
247 
248 ATF_TEST_CASE_WITHOUT_HEAD(delta__output);
249 ATF_TEST_CASE_BODY(delta__output)
250 {
251     {
252         std::ostringstream str;
253         str << datetime::delta(15, 8791);
254         ATF_REQUIRE_EQ("15008791us", str.str());
255     }
256     {
257         std::ostringstream str;
258         str << datetime::delta(12345678, 0);
259         ATF_REQUIRE_EQ("12345678000000us", str.str());
260     }
261 }
262 
263 
264 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__copy);
265 ATF_TEST_CASE_BODY(timestamp__copy)
266 {
267     const datetime::timestamp ts1 = datetime::timestamp::from_values(
268         2011, 2, 16, 19, 15, 30, 0);
269     {
270         const datetime::timestamp ts2 = ts1;
271         const datetime::timestamp ts3 = datetime::timestamp::from_values(
272             2012, 2, 16, 19, 15, 30, 0);
273         ATF_REQUIRE_EQ("2011", ts1.strftime("%Y"));
274         ATF_REQUIRE_EQ("2011", ts2.strftime("%Y"));
275         ATF_REQUIRE_EQ("2012", ts3.strftime("%Y"));
276     }
277     ATF_REQUIRE_EQ("2011", ts1.strftime("%Y"));
278 }
279 
280 
281 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__from_microseconds);
282 ATF_TEST_CASE_BODY(timestamp__from_microseconds)
283 {
284     const datetime::timestamp ts = datetime::timestamp::from_microseconds(
285         1328829351987654LL);
286     ATF_REQUIRE_EQ("2012-02-09 23:15:51", ts.strftime("%Y-%m-%d %H:%M:%S"));
287     ATF_REQUIRE_EQ(1328829351987654LL, ts.to_microseconds());
288     ATF_REQUIRE_EQ(1328829351, ts.to_seconds());
289 }
290 
291 
292 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__now__mock);
293 ATF_TEST_CASE_BODY(timestamp__now__mock)
294 {
295     datetime::set_mock_now(2011, 2, 21, 18, 5, 10, 0);
296     ATF_REQUIRE_EQ("2011-02-21 18:05:10",
297                    datetime::timestamp::now().strftime("%Y-%m-%d %H:%M:%S"));
298 
299     datetime::set_mock_now(datetime::timestamp::from_values(
300                                2012, 3, 22, 19, 6, 11, 54321));
301     ATF_REQUIRE_EQ("2012-03-22 19:06:11",
302                    datetime::timestamp::now().strftime("%Y-%m-%d %H:%M:%S"));
303     ATF_REQUIRE_EQ("2012-03-22 19:06:11",
304                    datetime::timestamp::now().strftime("%Y-%m-%d %H:%M:%S"));
305 }
306 
307 
308 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__now__real);
309 ATF_TEST_CASE_BODY(timestamp__now__real)
310 {
311     // This test is might fail if we happen to run at the crossing of one
312     // day to the other and the two measures we pick of the current time
313     // differ.  This is so unlikely that I haven't bothered to do this in any
314     // other way.
315 
316     const time_t just_before = ::time(NULL);
317     const datetime::timestamp now = datetime::timestamp::now();
318 
319     ::tm data;
320     char buf[1024];
321     ATF_REQUIRE(::gmtime_r(&just_before, &data) != 0);
322     ATF_REQUIRE(::strftime(buf, sizeof(buf), "%Y-%m-%d", &data) != 0);
323     ATF_REQUIRE_EQ(buf, now.strftime("%Y-%m-%d"));
324 
325     ATF_REQUIRE(now.strftime("%Z") == "GMT" || now.strftime("%Z") == "UTC");
326 }
327 
328 
329 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__now__granularity);
330 ATF_TEST_CASE_BODY(timestamp__now__granularity)
331 {
332     const datetime::timestamp first = datetime::timestamp::now();
333     ::usleep(1);
334     const datetime::timestamp second = datetime::timestamp::now();
335     ATF_REQUIRE(first.to_microseconds() != second.to_microseconds());
336 }
337 
338 
339 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__strftime);
340 ATF_TEST_CASE_BODY(timestamp__strftime)
341 {
342     const datetime::timestamp ts1 = datetime::timestamp::from_values(
343         2010, 12, 10, 8, 45, 50, 0);
344     ATF_REQUIRE_EQ("2010-12-10", ts1.strftime("%Y-%m-%d"));
345     ATF_REQUIRE_EQ("08:45:50", ts1.strftime("%H:%M:%S"));
346 
347     const datetime::timestamp ts2 = datetime::timestamp::from_values(
348         2011, 2, 16, 19, 15, 30, 0);
349     ATF_REQUIRE_EQ("2011-02-16T19:15:30", ts2.strftime("%Y-%m-%dT%H:%M:%S"));
350 }
351 
352 
353 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__to_iso8601_in_utc);
354 ATF_TEST_CASE_BODY(timestamp__to_iso8601_in_utc)
355 {
356     const datetime::timestamp ts1 = datetime::timestamp::from_values(
357         2010, 12, 10, 8, 45, 50, 0);
358     ATF_REQUIRE_EQ("2010-12-10T08:45:50.000000Z", ts1.to_iso8601_in_utc());
359 
360     const datetime::timestamp ts2= datetime::timestamp::from_values(
361         2016, 7, 11, 17, 51, 28, 123456);
362     ATF_REQUIRE_EQ("2016-07-11T17:51:28.123456Z", ts2.to_iso8601_in_utc());
363 }
364 
365 
366 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__to_microseconds);
367 ATF_TEST_CASE_BODY(timestamp__to_microseconds)
368 {
369     const datetime::timestamp ts1 = datetime::timestamp::from_values(
370         2010, 12, 10, 8, 45, 50, 123456);
371     ATF_REQUIRE_EQ(1291970750123456LL, ts1.to_microseconds());
372 }
373 
374 
375 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__to_seconds);
376 ATF_TEST_CASE_BODY(timestamp__to_seconds)
377 {
378     const datetime::timestamp ts1 = datetime::timestamp::from_values(
379         2010, 12, 10, 8, 45, 50, 123456);
380     ATF_REQUIRE_EQ(1291970750, ts1.to_seconds());
381 }
382 
383 
384 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__leap_second);
385 ATF_TEST_CASE_BODY(timestamp__leap_second)
386 {
387     // This is actually a test for from_values(), which is the function that
388     // includes assertions to validate the input parameters.
389     const datetime::timestamp ts1 = datetime::timestamp::from_values(
390         2012, 6, 30, 23, 59, 60, 543);
391     ATF_REQUIRE_EQ(1341100800, ts1.to_seconds());
392 }
393 
394 
395 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__equals);
396 ATF_TEST_CASE_BODY(timestamp__equals)
397 {
398     ATF_REQUIRE(datetime::timestamp::from_microseconds(1291970750123456LL) ==
399                 datetime::timestamp::from_microseconds(1291970750123456LL));
400 }
401 
402 
403 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__differs);
404 ATF_TEST_CASE_BODY(timestamp__differs)
405 {
406     ATF_REQUIRE(datetime::timestamp::from_microseconds(1291970750123456LL) !=
407                 datetime::timestamp::from_microseconds(1291970750123455LL));
408 }
409 
410 
411 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__sorting);
412 ATF_TEST_CASE_BODY(timestamp__sorting)
413 {
414     {
415         const datetime::timestamp ts1 = datetime::timestamp::from_microseconds(
416             1291970750123455LL);
417         const datetime::timestamp ts2 = datetime::timestamp::from_microseconds(
418             1291970750123455LL);
419 
420         ATF_REQUIRE(!(ts1 < ts2));
421         ATF_REQUIRE(  ts1 <= ts2);
422         ATF_REQUIRE(!(ts1 > ts2));
423         ATF_REQUIRE(  ts1 >= ts2);
424     }
425     {
426         const datetime::timestamp ts1 = datetime::timestamp::from_microseconds(
427             1291970750123455LL);
428         const datetime::timestamp ts2 = datetime::timestamp::from_microseconds(
429             1291970759123455LL);
430 
431         ATF_REQUIRE( ts1 < ts2);
432         ATF_REQUIRE( ts1 <= ts2);
433         ATF_REQUIRE(!(ts1 > ts2));
434         ATF_REQUIRE(!(ts1 >= ts2));
435     }
436     {
437         const datetime::timestamp ts1 = datetime::timestamp::from_microseconds(
438             1291970759123455LL);
439         const datetime::timestamp ts2 = datetime::timestamp::from_microseconds(
440             1291970750123455LL);
441 
442         ATF_REQUIRE(!(ts1 < ts2));
443         ATF_REQUIRE(!(ts1 <= ts2));
444         ATF_REQUIRE(  ts1 > ts2);
445         ATF_REQUIRE(  ts1 >= ts2);
446     }
447 }
448 
449 
450 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__add_delta);
451 ATF_TEST_CASE_BODY(timestamp__add_delta)
452 {
453     using datetime::delta;
454     using datetime::timestamp;
455 
456     ATF_REQUIRE_EQ(timestamp::from_values(2014, 12, 11, 21, 43, 30, 1234),
457                    timestamp::from_values(2014, 12, 11, 21, 43, 0, 0) +
458                    delta(30, 1234));
459     ATF_REQUIRE_EQ(timestamp::from_values(2014, 12, 11, 22, 43, 7, 100),
460                    timestamp::from_values(2014, 12, 11, 21, 43, 0, 0) +
461                    delta(3602, 5000100));
462 }
463 
464 
465 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__add_delta_and_set);
466 ATF_TEST_CASE_BODY(timestamp__add_delta_and_set)
467 {
468     using datetime::delta;
469     using datetime::timestamp;
470 
471     {
472         timestamp ts = timestamp::from_values(2014, 12, 11, 21, 43, 0, 0);
473         ts += delta(30, 1234);
474         ATF_REQUIRE_EQ(timestamp::from_values(2014, 12, 11, 21, 43, 30, 1234),
475                        ts);
476     }
477     {
478         timestamp ts = timestamp::from_values(2014, 12, 11, 21, 43, 0, 0);
479         ATF_REQUIRE_EQ(timestamp::from_values(2014, 12, 11, 22, 43, 7, 100),
480                        ts += delta(3602, 5000100));
481     }
482 }
483 
484 
485 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__subtract_delta);
486 ATF_TEST_CASE_BODY(timestamp__subtract_delta)
487 {
488     using datetime::delta;
489     using datetime::timestamp;
490 
491     ATF_REQUIRE_EQ(timestamp::from_values(2014, 12, 11, 21, 43, 10, 4321),
492                    timestamp::from_values(2014, 12, 11, 21, 43, 40, 5555) -
493                    delta(30, 1234));
494     ATF_REQUIRE_EQ(timestamp::from_values(2014, 12, 11, 20, 43, 1, 300),
495                    timestamp::from_values(2014, 12, 11, 21, 43, 8, 400) -
496                    delta(3602, 5000100));
497 }
498 
499 
500 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__subtract_delta_and_set);
501 ATF_TEST_CASE_BODY(timestamp__subtract_delta_and_set)
502 {
503     using datetime::delta;
504     using datetime::timestamp;
505 
506     {
507         timestamp ts = timestamp::from_values(2014, 12, 11, 21, 43, 40, 5555);
508         ts -= delta(30, 1234);
509         ATF_REQUIRE_EQ(timestamp::from_values(2014, 12, 11, 21, 43, 10, 4321),
510                        ts);
511     }
512     {
513         timestamp ts = timestamp::from_values(2014, 12, 11, 21, 43, 8, 400);
514         ATF_REQUIRE_EQ(timestamp::from_values(2014, 12, 11, 20, 43, 1, 300),
515                        ts -= delta(3602, 5000100));
516     }
517 }
518 
519 
520 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__subtraction);
521 ATF_TEST_CASE_BODY(timestamp__subtraction)
522 {
523     const datetime::timestamp ts1 = datetime::timestamp::from_microseconds(
524         1291970750123456LL);
525     const datetime::timestamp ts2 = datetime::timestamp::from_microseconds(
526         1291970750123468LL);
527     const datetime::timestamp ts3 = datetime::timestamp::from_microseconds(
528         1291970850123456LL);
529 
530     ATF_REQUIRE_EQ(datetime::delta(0, 0), ts1 - ts1);
531     ATF_REQUIRE_EQ(datetime::delta(0, 12), ts2 - ts1);
532     ATF_REQUIRE_EQ(datetime::delta(100, 0), ts3 - ts1);
533     ATF_REQUIRE_EQ(datetime::delta(99, 999988), ts3 - ts2);
534 
535     ATF_REQUIRE_THROW_RE(
536         std::runtime_error,
537         "Cannot subtract 1291970850123456us from 1291970750123468us "
538         ".*negative datetime::delta.*not supported",
539         ts2 - ts3);
540 }
541 
542 
543 ATF_TEST_CASE_WITHOUT_HEAD(timestamp__output);
544 ATF_TEST_CASE_BODY(timestamp__output)
545 {
546     {
547         std::ostringstream str;
548         str << datetime::timestamp::from_microseconds(1291970750123456LL);
549         ATF_REQUIRE_EQ("1291970750123456us", str.str());
550     }
551     {
552         std::ostringstream str;
553         str << datetime::timestamp::from_microseconds(1028309798759812LL);
554         ATF_REQUIRE_EQ("1028309798759812us", str.str());
555     }
556 }
557 
558 
559 ATF_INIT_TEST_CASES(tcs)
560 {
561     ATF_ADD_TEST_CASE(tcs, delta__defaults);
562     ATF_ADD_TEST_CASE(tcs, delta__overrides);
563     ATF_ADD_TEST_CASE(tcs, delta__from_microseconds);
564     ATF_ADD_TEST_CASE(tcs, delta__to_microseconds);
565     ATF_ADD_TEST_CASE(tcs, delta__equals);
566     ATF_ADD_TEST_CASE(tcs, delta__differs);
567     ATF_ADD_TEST_CASE(tcs, delta__sorting);
568     ATF_ADD_TEST_CASE(tcs, delta__addition);
569     ATF_ADD_TEST_CASE(tcs, delta__addition_and_set);
570     ATF_ADD_TEST_CASE(tcs, delta__scale);
571     ATF_ADD_TEST_CASE(tcs, delta__scale_and_set);
572     ATF_ADD_TEST_CASE(tcs, delta__output);
573 
574     ATF_ADD_TEST_CASE(tcs, timestamp__copy);
575     ATF_ADD_TEST_CASE(tcs, timestamp__from_microseconds);
576     ATF_ADD_TEST_CASE(tcs, timestamp__now__mock);
577     ATF_ADD_TEST_CASE(tcs, timestamp__now__real);
578     ATF_ADD_TEST_CASE(tcs, timestamp__now__granularity);
579     ATF_ADD_TEST_CASE(tcs, timestamp__strftime);
580     ATF_ADD_TEST_CASE(tcs, timestamp__to_iso8601_in_utc);
581     ATF_ADD_TEST_CASE(tcs, timestamp__to_microseconds);
582     ATF_ADD_TEST_CASE(tcs, timestamp__to_seconds);
583     ATF_ADD_TEST_CASE(tcs, timestamp__leap_second);
584     ATF_ADD_TEST_CASE(tcs, timestamp__equals);
585     ATF_ADD_TEST_CASE(tcs, timestamp__differs);
586     ATF_ADD_TEST_CASE(tcs, timestamp__sorting);
587     ATF_ADD_TEST_CASE(tcs, timestamp__add_delta);
588     ATF_ADD_TEST_CASE(tcs, timestamp__add_delta_and_set);
589     ATF_ADD_TEST_CASE(tcs, timestamp__subtract_delta);
590     ATF_ADD_TEST_CASE(tcs, timestamp__subtract_delta_and_set);
591     ATF_ADD_TEST_CASE(tcs, timestamp__subtraction);
592     ATF_ADD_TEST_CASE(tcs, timestamp__output);
593 }
594