time_test.c revision 1.1 1 /* $NetBSD: time_test.c,v 1.1 2024/02/21 21:54:54 christos Exp $ */
2
3 /*
4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 *
6 * SPDX-License-Identifier: MPL-2.0
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11 *
12 * See the COPYRIGHT file distributed with this work for additional
13 * information regarding copyright ownership.
14 */
15
16 #include <inttypes.h>
17 #include <sched.h> /* IWYU pragma: keep */
18 #include <setjmp.h>
19 #include <stdarg.h>
20 #include <stddef.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #define UNIT_TESTING
26 #include <cmocka.h>
27
28 #include <isc/result.h>
29 #include <isc/time.h>
30 #include <isc/util.h>
31
32 #include "time.c"
33
34 #include <tests/isc.h>
35
36 #define MAX_NS (NS_PER_SEC - 1)
37
38 struct time_vectors {
39 isc_time_t a;
40 isc_interval_t b;
41 isc_time_t r;
42 isc_result_t result;
43 };
44
45 const struct time_vectors vectors_add[8] = {
46 { { 0, 0 }, { 0, 0 }, { 0, 0 }, ISC_R_SUCCESS },
47 { { 0, MAX_NS }, { 0, MAX_NS }, { 1, MAX_NS - 1 }, ISC_R_SUCCESS },
48 { { 0, NS_PER_SEC / 2 },
49 { 0, NS_PER_SEC / 2 },
50 { 1, 0 },
51 ISC_R_SUCCESS },
52 { { UINT_MAX, MAX_NS }, { 0, 0 }, { UINT_MAX, MAX_NS }, ISC_R_SUCCESS },
53 { { UINT_MAX, 0 }, { 0, MAX_NS }, { UINT_MAX, MAX_NS }, ISC_R_SUCCESS },
54 { { UINT_MAX, 0 }, { 1, 0 }, { 0, 0 }, ISC_R_RANGE },
55 { { UINT_MAX, MAX_NS }, { 0, 1 }, { 0, 0 }, ISC_R_RANGE },
56 { { UINT_MAX / 2 + 1, NS_PER_SEC / 2 },
57 { UINT_MAX / 2, NS_PER_SEC / 2 },
58 { 0, 0 },
59 ISC_R_RANGE },
60 };
61
62 const struct time_vectors vectors_sub[7] = {
63 { { 0, 0 }, { 0, 0 }, { 0, 0 }, ISC_R_SUCCESS },
64 { { 1, 0 }, { 0, MAX_NS }, { 0, 1 }, ISC_R_SUCCESS },
65 { { 1, NS_PER_SEC / 2 },
66 { 0, MAX_NS },
67 { 0, NS_PER_SEC / 2 + 1 },
68 ISC_R_SUCCESS },
69 { { UINT_MAX, MAX_NS }, { UINT_MAX, 0 }, { 0, MAX_NS }, ISC_R_SUCCESS },
70 { { 0, 0 }, { 1, 0 }, { 0, 0 }, ISC_R_RANGE },
71 { { 0, 0 }, { 0, MAX_NS }, { 0, 0 }, ISC_R_RANGE },
72 };
73
74 ISC_RUN_TEST_IMPL(isc_time_add_test) {
75 UNUSED(state);
76
77 for (size_t i = 0; i < ARRAY_SIZE(vectors_add); i++) {
78 isc_time_t r = { UINT_MAX, UINT_MAX };
79 isc_result_t result = isc_time_add(&(vectors_add[i].a),
80 &(vectors_add[i].b), &r);
81 assert_int_equal(result, vectors_add[i].result);
82 if (result != ISC_R_SUCCESS) {
83 continue;
84 }
85
86 assert_int_equal(r.seconds, vectors_add[i].r.seconds);
87 assert_int_equal(r.nanoseconds, vectors_add[i].r.nanoseconds);
88 }
89
90 expect_assert_failure((void)isc_time_add(&(isc_time_t){ 0, MAX_NS + 1 },
91 &(isc_interval_t){ 0, 0 },
92 &(isc_time_t){ 0, 0 }));
93 expect_assert_failure((void)isc_time_add(
94 &(isc_time_t){ 0, 0 }, &(isc_interval_t){ 0, MAX_NS + 1 },
95 &(isc_time_t){ 0, 0 }));
96
97 expect_assert_failure((void)isc_time_add((isc_time_t *)NULL,
98 &(isc_interval_t){ 0, 0 },
99 &(isc_time_t){ 0, 0 }));
100 expect_assert_failure((void)isc_time_add(&(isc_time_t){ 0, 0 },
101 (isc_interval_t *)NULL,
102 &(isc_time_t){ 0, 0 }));
103 expect_assert_failure((void)isc_time_add(
104 &(isc_time_t){ 0, 0 }, &(isc_interval_t){ 0, 0 }, NULL));
105 }
106
107 ISC_RUN_TEST_IMPL(isc_time_sub_test) {
108 UNUSED(state);
109
110 for (size_t i = 0; i < ARRAY_SIZE(vectors_sub); i++) {
111 isc_time_t r = { UINT_MAX, UINT_MAX };
112 isc_result_t result = isc_time_subtract(
113 &(vectors_sub[i].a), &(vectors_sub[i].b), &r);
114 assert_int_equal(result, vectors_sub[i].result);
115 if (result != ISC_R_SUCCESS) {
116 continue;
117 }
118 assert_int_equal(r.seconds, vectors_sub[i].r.seconds);
119 assert_int_equal(r.nanoseconds, vectors_sub[i].r.nanoseconds);
120 }
121
122 expect_assert_failure((void)isc_time_subtract(
123 &(isc_time_t){ 0, MAX_NS + 1 }, &(isc_interval_t){ 0, 0 },
124 &(isc_time_t){ 0, 0 }));
125 expect_assert_failure((void)isc_time_subtract(
126 &(isc_time_t){ 0, 0 }, &(isc_interval_t){ 0, MAX_NS + 1 },
127 &(isc_time_t){ 0, 0 }));
128
129 expect_assert_failure((void)isc_time_subtract((isc_time_t *)NULL,
130 &(isc_interval_t){ 0, 0 },
131 &(isc_time_t){ 0, 0 }));
132 expect_assert_failure((void)isc_time_subtract(&(isc_time_t){ 0, 0 },
133 (isc_interval_t *)NULL,
134 &(isc_time_t){ 0, 0 }));
135 expect_assert_failure((void)isc_time_subtract(
136 &(isc_time_t){ 0, 0 }, &(isc_interval_t){ 0, 0 }, NULL));
137 }
138
139 /* parse http time stamp */
140
141 ISC_RUN_TEST_IMPL(isc_time_parsehttptimestamp_test) {
142 isc_result_t result;
143 isc_time_t t, x;
144 char buf[ISC_FORMATHTTPTIMESTAMP_SIZE];
145
146 UNUSED(state);
147
148 setenv("TZ", "America/Los_Angeles", 1);
149 result = isc_time_now(&t);
150 assert_int_equal(result, ISC_R_SUCCESS);
151
152 isc_time_formathttptimestamp(&t, buf, sizeof(buf));
153 result = isc_time_parsehttptimestamp(buf, &x);
154 assert_int_equal(result, ISC_R_SUCCESS);
155 assert_int_equal(isc_time_seconds(&t), isc_time_seconds(&x));
156 }
157
158 /* print UTC in ISO8601 */
159
160 ISC_RUN_TEST_IMPL(isc_time_formatISO8601_test) {
161 isc_result_t result;
162 isc_time_t t;
163 char buf[64];
164
165 UNUSED(state);
166
167 setenv("TZ", "America/Los_Angeles", 1);
168 result = isc_time_now(&t);
169 assert_int_equal(result, ISC_R_SUCCESS);
170
171 /* check formatting: yyyy-mm-ddThh:mm:ssZ */
172 memset(buf, 'X', sizeof(buf));
173 isc_time_formatISO8601(&t, buf, sizeof(buf));
174 assert_int_equal(strlen(buf), 20);
175 assert_int_equal(buf[4], '-');
176 assert_int_equal(buf[7], '-');
177 assert_int_equal(buf[10], 'T');
178 assert_int_equal(buf[13], ':');
179 assert_int_equal(buf[16], ':');
180 assert_int_equal(buf[19], 'Z');
181
182 /* check time conversion correctness */
183 memset(buf, 'X', sizeof(buf));
184 isc_time_settoepoch(&t);
185 isc_time_formatISO8601(&t, buf, sizeof(buf));
186 assert_string_equal(buf, "1970-01-01T00:00:00Z");
187
188 memset(buf, 'X', sizeof(buf));
189 isc_time_set(&t, 1450000000, 123000000);
190 isc_time_formatISO8601(&t, buf, sizeof(buf));
191 assert_string_equal(buf, "2015-12-13T09:46:40Z");
192 }
193
194 /* print UTC in ISO8601 with milliseconds */
195
196 ISC_RUN_TEST_IMPL(isc_time_formatISO8601ms_test) {
197 isc_result_t result;
198 isc_time_t t;
199 char buf[64];
200
201 UNUSED(state);
202
203 setenv("TZ", "America/Los_Angeles", 1);
204 result = isc_time_now(&t);
205 assert_int_equal(result, ISC_R_SUCCESS);
206
207 /* check formatting: yyyy-mm-ddThh:mm:ss.sssZ */
208 memset(buf, 'X', sizeof(buf));
209 isc_time_formatISO8601ms(&t, buf, sizeof(buf));
210 assert_int_equal(strlen(buf), 24);
211 assert_int_equal(buf[4], '-');
212 assert_int_equal(buf[7], '-');
213 assert_int_equal(buf[10], 'T');
214 assert_int_equal(buf[13], ':');
215 assert_int_equal(buf[16], ':');
216 assert_int_equal(buf[19], '.');
217 assert_int_equal(buf[23], 'Z');
218
219 /* check time conversion correctness */
220 memset(buf, 'X', sizeof(buf));
221 isc_time_settoepoch(&t);
222 isc_time_formatISO8601ms(&t, buf, sizeof(buf));
223 assert_string_equal(buf, "1970-01-01T00:00:00.000Z");
224
225 memset(buf, 'X', sizeof(buf));
226 isc_time_set(&t, 1450000000, 123000000);
227 isc_time_formatISO8601ms(&t, buf, sizeof(buf));
228 assert_string_equal(buf, "2015-12-13T09:46:40.123Z");
229 }
230
231 /* print UTC in ISO8601 with microseconds */
232
233 ISC_RUN_TEST_IMPL(isc_time_formatISO8601us_test) {
234 isc_result_t result;
235 isc_time_t t;
236 char buf[64];
237
238 UNUSED(state);
239
240 setenv("TZ", "America/Los_Angeles", 1);
241 result = isc_time_now_hires(&t);
242 assert_int_equal(result, ISC_R_SUCCESS);
243
244 /* check formatting: yyyy-mm-ddThh:mm:ss.ssssssZ */
245 memset(buf, 'X', sizeof(buf));
246 isc_time_formatISO8601us(&t, buf, sizeof(buf));
247 assert_int_equal(strlen(buf), 27);
248 assert_int_equal(buf[4], '-');
249 assert_int_equal(buf[7], '-');
250 assert_int_equal(buf[10], 'T');
251 assert_int_equal(buf[13], ':');
252 assert_int_equal(buf[16], ':');
253 assert_int_equal(buf[19], '.');
254 assert_int_equal(buf[26], 'Z');
255
256 /* check time conversion correctness */
257 memset(buf, 'X', sizeof(buf));
258 isc_time_settoepoch(&t);
259 isc_time_formatISO8601us(&t, buf, sizeof(buf));
260 assert_string_equal(buf, "1970-01-01T00:00:00.000000Z");
261
262 memset(buf, 'X', sizeof(buf));
263 isc_time_set(&t, 1450000000, 123456000);
264 isc_time_formatISO8601us(&t, buf, sizeof(buf));
265 assert_string_equal(buf, "2015-12-13T09:46:40.123456Z");
266 }
267
268 /* print local time in ISO8601 */
269
270 ISC_RUN_TEST_IMPL(isc_time_formatISO8601L_test) {
271 isc_result_t result;
272 isc_time_t t;
273 char buf[64];
274
275 UNUSED(state);
276
277 setenv("TZ", "America/Los_Angeles", 1);
278 result = isc_time_now(&t);
279 assert_int_equal(result, ISC_R_SUCCESS);
280
281 /* check formatting: yyyy-mm-ddThh:mm:ss */
282 memset(buf, 'X', sizeof(buf));
283 isc_time_formatISO8601L(&t, buf, sizeof(buf));
284 assert_int_equal(strlen(buf), 19);
285 assert_int_equal(buf[4], '-');
286 assert_int_equal(buf[7], '-');
287 assert_int_equal(buf[10], 'T');
288 assert_int_equal(buf[13], ':');
289 assert_int_equal(buf[16], ':');
290
291 /* check time conversion correctness */
292 memset(buf, 'X', sizeof(buf));
293 isc_time_settoepoch(&t);
294 isc_time_formatISO8601L(&t, buf, sizeof(buf));
295 assert_string_equal(buf, "1969-12-31T16:00:00");
296
297 memset(buf, 'X', sizeof(buf));
298 isc_time_set(&t, 1450000000, 123000000);
299 isc_time_formatISO8601L(&t, buf, sizeof(buf));
300 assert_string_equal(buf, "2015-12-13T01:46:40");
301 }
302
303 /* print local time in ISO8601 with milliseconds */
304
305 ISC_RUN_TEST_IMPL(isc_time_formatISO8601Lms_test) {
306 isc_result_t result;
307 isc_time_t t;
308 char buf[64];
309
310 UNUSED(state);
311
312 setenv("TZ", "America/Los_Angeles", 1);
313 result = isc_time_now(&t);
314 assert_int_equal(result, ISC_R_SUCCESS);
315
316 /* check formatting: yyyy-mm-ddThh:mm:ss.sss */
317 memset(buf, 'X', sizeof(buf));
318 isc_time_formatISO8601Lms(&t, buf, sizeof(buf));
319 assert_int_equal(strlen(buf), 23);
320 assert_int_equal(buf[4], '-');
321 assert_int_equal(buf[7], '-');
322 assert_int_equal(buf[10], 'T');
323 assert_int_equal(buf[13], ':');
324 assert_int_equal(buf[16], ':');
325 assert_int_equal(buf[19], '.');
326
327 /* check time conversion correctness */
328 memset(buf, 'X', sizeof(buf));
329 isc_time_settoepoch(&t);
330 isc_time_formatISO8601Lms(&t, buf, sizeof(buf));
331 assert_string_equal(buf, "1969-12-31T16:00:00.000");
332
333 memset(buf, 'X', sizeof(buf));
334 isc_time_set(&t, 1450000000, 123000000);
335 isc_time_formatISO8601Lms(&t, buf, sizeof(buf));
336 assert_string_equal(buf, "2015-12-13T01:46:40.123");
337 }
338
339 /* print local time in ISO8601 with microseconds */
340
341 ISC_RUN_TEST_IMPL(isc_time_formatISO8601Lus_test) {
342 isc_result_t result;
343 isc_time_t t;
344 char buf[64];
345
346 UNUSED(state);
347
348 setenv("TZ", "America/Los_Angeles", 1);
349 result = isc_time_now_hires(&t);
350 assert_int_equal(result, ISC_R_SUCCESS);
351
352 /* check formatting: yyyy-mm-ddThh:mm:ss.ssssss */
353 memset(buf, 'X', sizeof(buf));
354 isc_time_formatISO8601Lus(&t, buf, sizeof(buf));
355 assert_int_equal(strlen(buf), 26);
356 assert_int_equal(buf[4], '-');
357 assert_int_equal(buf[7], '-');
358 assert_int_equal(buf[10], 'T');
359 assert_int_equal(buf[13], ':');
360 assert_int_equal(buf[16], ':');
361 assert_int_equal(buf[19], '.');
362
363 /* check time conversion correctness */
364 memset(buf, 'X', sizeof(buf));
365 isc_time_settoepoch(&t);
366 isc_time_formatISO8601Lus(&t, buf, sizeof(buf));
367 assert_string_equal(buf, "1969-12-31T16:00:00.000000");
368
369 memset(buf, 'X', sizeof(buf));
370 isc_time_set(&t, 1450000000, 123456000);
371 isc_time_formatISO8601Lus(&t, buf, sizeof(buf));
372 assert_string_equal(buf, "2015-12-13T01:46:40.123456");
373 }
374
375 /* print UTC time as yyyymmddhhmmsssss */
376
377 ISC_RUN_TEST_IMPL(isc_time_formatshorttimestamp_test) {
378 isc_result_t result;
379 isc_time_t t;
380 char buf[64];
381
382 UNUSED(state);
383
384 setenv("TZ", "America/Los_Angeles", 1);
385 result = isc_time_now(&t);
386 assert_int_equal(result, ISC_R_SUCCESS);
387
388 /* check formatting: yyyymmddhhmmsssss */
389 memset(buf, 'X', sizeof(buf));
390 isc_time_formatshorttimestamp(&t, buf, sizeof(buf));
391 assert_int_equal(strlen(buf), 17);
392
393 /* check time conversion correctness */
394 memset(buf, 'X', sizeof(buf));
395 isc_time_settoepoch(&t);
396 isc_time_formatshorttimestamp(&t, buf, sizeof(buf));
397 assert_string_equal(buf, "19700101000000000");
398
399 memset(buf, 'X', sizeof(buf));
400 isc_time_set(&t, 1450000000, 123000000);
401 isc_time_formatshorttimestamp(&t, buf, sizeof(buf));
402 assert_string_equal(buf, "20151213094640123");
403 }
404
405 ISC_TEST_LIST_START
406
407 ISC_TEST_ENTRY(isc_time_add_test)
408 ISC_TEST_ENTRY(isc_time_sub_test)
409 ISC_TEST_ENTRY(isc_time_parsehttptimestamp_test)
410 ISC_TEST_ENTRY(isc_time_formatISO8601_test)
411 ISC_TEST_ENTRY(isc_time_formatISO8601ms_test)
412 ISC_TEST_ENTRY(isc_time_formatISO8601us_test)
413 ISC_TEST_ENTRY(isc_time_formatISO8601L_test)
414 ISC_TEST_ENTRY(isc_time_formatISO8601Lms_test)
415 ISC_TEST_ENTRY(isc_time_formatISO8601Lus_test)
416 ISC_TEST_ENTRY(isc_time_formatshorttimestamp_test)
417
418 ISC_TEST_LIST_END
419
420 ISC_TEST_MAIN
421