time_test.c revision 1.1.1.2 1 /* $NetBSD: time_test.c,v 1.1.1.2 2025/01/26 16:12:36 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 t = isc_time_now();
150
151 isc_time_formathttptimestamp(&t, buf, sizeof(buf));
152 result = isc_time_parsehttptimestamp(buf, &x);
153 assert_int_equal(result, ISC_R_SUCCESS);
154 assert_int_equal(isc_time_seconds(&t), isc_time_seconds(&x));
155 }
156
157 /* print UTC in ISO8601 */
158
159 ISC_RUN_TEST_IMPL(isc_time_formatISO8601_test) {
160 isc_time_t t;
161 char buf[64];
162
163 UNUSED(state);
164
165 setenv("TZ", "America/Los_Angeles", 1);
166 t = isc_time_now();
167
168 /* check formatting: yyyy-mm-ddThh:mm:ssZ */
169 memset(buf, 'X', sizeof(buf));
170 isc_time_formatISO8601(&t, buf, sizeof(buf));
171 assert_int_equal(strlen(buf), 20);
172 assert_int_equal(buf[4], '-');
173 assert_int_equal(buf[7], '-');
174 assert_int_equal(buf[10], 'T');
175 assert_int_equal(buf[13], ':');
176 assert_int_equal(buf[16], ':');
177 assert_int_equal(buf[19], 'Z');
178
179 /* check time conversion correctness */
180 memset(buf, 'X', sizeof(buf));
181 isc_time_settoepoch(&t);
182 isc_time_formatISO8601(&t, buf, sizeof(buf));
183 assert_string_equal(buf, "1970-01-01T00:00:00Z");
184
185 memset(buf, 'X', sizeof(buf));
186 isc_time_set(&t, 1450000000, 123000000);
187 isc_time_formatISO8601(&t, buf, sizeof(buf));
188 assert_string_equal(buf, "2015-12-13T09:46:40Z");
189 }
190
191 /* print UTC in ISO8601 with milliseconds */
192
193 ISC_RUN_TEST_IMPL(isc_time_formatISO8601ms_test) {
194 isc_time_t t;
195 char buf[64];
196
197 UNUSED(state);
198
199 setenv("TZ", "America/Los_Angeles", 1);
200 t = isc_time_now();
201
202 /* check formatting: yyyy-mm-ddThh:mm:ss.sssZ */
203 memset(buf, 'X', sizeof(buf));
204 isc_time_formatISO8601ms(&t, buf, sizeof(buf));
205 assert_int_equal(strlen(buf), 24);
206 assert_int_equal(buf[4], '-');
207 assert_int_equal(buf[7], '-');
208 assert_int_equal(buf[10], 'T');
209 assert_int_equal(buf[13], ':');
210 assert_int_equal(buf[16], ':');
211 assert_int_equal(buf[19], '.');
212 assert_int_equal(buf[23], 'Z');
213
214 /* check time conversion correctness */
215 memset(buf, 'X', sizeof(buf));
216 isc_time_settoepoch(&t);
217 isc_time_formatISO8601ms(&t, buf, sizeof(buf));
218 assert_string_equal(buf, "1970-01-01T00:00:00.000Z");
219
220 memset(buf, 'X', sizeof(buf));
221 isc_time_set(&t, 1450000000, 123000000);
222 isc_time_formatISO8601ms(&t, buf, sizeof(buf));
223 assert_string_equal(buf, "2015-12-13T09:46:40.123Z");
224 }
225
226 /* print UTC in ISO8601 with microseconds */
227
228 ISC_RUN_TEST_IMPL(isc_time_formatISO8601us_test) {
229 isc_time_t t;
230 char buf[64];
231
232 UNUSED(state);
233
234 setenv("TZ", "America/Los_Angeles", 1);
235 t = isc_time_now_hires();
236
237 /* check formatting: yyyy-mm-ddThh:mm:ss.ssssssZ */
238 memset(buf, 'X', sizeof(buf));
239 isc_time_formatISO8601us(&t, buf, sizeof(buf));
240 assert_int_equal(strlen(buf), 27);
241 assert_int_equal(buf[4], '-');
242 assert_int_equal(buf[7], '-');
243 assert_int_equal(buf[10], 'T');
244 assert_int_equal(buf[13], ':');
245 assert_int_equal(buf[16], ':');
246 assert_int_equal(buf[19], '.');
247 assert_int_equal(buf[26], 'Z');
248
249 /* check time conversion correctness */
250 memset(buf, 'X', sizeof(buf));
251 isc_time_settoepoch(&t);
252 isc_time_formatISO8601us(&t, buf, sizeof(buf));
253 assert_string_equal(buf, "1970-01-01T00:00:00.000000Z");
254
255 memset(buf, 'X', sizeof(buf));
256 isc_time_set(&t, 1450000000, 123456000);
257 isc_time_formatISO8601us(&t, buf, sizeof(buf));
258 assert_string_equal(buf, "2015-12-13T09:46:40.123456Z");
259 }
260
261 /* print local time in ISO8601 */
262
263 ISC_RUN_TEST_IMPL(isc_time_formatISO8601L_test) {
264 isc_time_t t;
265 char buf[64];
266
267 UNUSED(state);
268
269 setenv("TZ", "America/Los_Angeles", 1);
270 t = isc_time_now();
271
272 /* check formatting: yyyy-mm-ddThh:mm:ss */
273 memset(buf, 'X', sizeof(buf));
274 isc_time_formatISO8601L(&t, buf, sizeof(buf));
275 assert_int_equal(strlen(buf), 19);
276 assert_int_equal(buf[4], '-');
277 assert_int_equal(buf[7], '-');
278 assert_int_equal(buf[10], 'T');
279 assert_int_equal(buf[13], ':');
280 assert_int_equal(buf[16], ':');
281
282 /* check time conversion correctness */
283 memset(buf, 'X', sizeof(buf));
284 isc_time_settoepoch(&t);
285 isc_time_formatISO8601L(&t, buf, sizeof(buf));
286 assert_string_equal(buf, "1969-12-31T16:00:00");
287
288 memset(buf, 'X', sizeof(buf));
289 isc_time_set(&t, 1450000000, 123000000);
290 isc_time_formatISO8601L(&t, buf, sizeof(buf));
291 assert_string_equal(buf, "2015-12-13T01:46:40");
292 }
293
294 /* print local time in ISO8601 with milliseconds */
295
296 ISC_RUN_TEST_IMPL(isc_time_formatISO8601Lms_test) {
297 isc_time_t t;
298 char buf[64];
299
300 UNUSED(state);
301
302 setenv("TZ", "America/Los_Angeles", 1);
303 t = isc_time_now();
304
305 /* check formatting: yyyy-mm-ddThh:mm:ss.sss */
306 memset(buf, 'X', sizeof(buf));
307 isc_time_formatISO8601Lms(&t, buf, sizeof(buf));
308 assert_int_equal(strlen(buf), 23);
309 assert_int_equal(buf[4], '-');
310 assert_int_equal(buf[7], '-');
311 assert_int_equal(buf[10], 'T');
312 assert_int_equal(buf[13], ':');
313 assert_int_equal(buf[16], ':');
314 assert_int_equal(buf[19], '.');
315
316 /* check time conversion correctness */
317 memset(buf, 'X', sizeof(buf));
318 isc_time_settoepoch(&t);
319 isc_time_formatISO8601Lms(&t, buf, sizeof(buf));
320 assert_string_equal(buf, "1969-12-31T16:00:00.000");
321
322 memset(buf, 'X', sizeof(buf));
323 isc_time_set(&t, 1450000000, 123000000);
324 isc_time_formatISO8601Lms(&t, buf, sizeof(buf));
325 assert_string_equal(buf, "2015-12-13T01:46:40.123");
326 }
327
328 /* print local time in ISO8601 with microseconds */
329
330 ISC_RUN_TEST_IMPL(isc_time_formatISO8601Lus_test) {
331 isc_time_t t;
332 char buf[64];
333
334 UNUSED(state);
335
336 setenv("TZ", "America/Los_Angeles", 1);
337 t = isc_time_now_hires();
338
339 /* check formatting: yyyy-mm-ddThh:mm:ss.ssssss */
340 memset(buf, 'X', sizeof(buf));
341 isc_time_formatISO8601Lus(&t, buf, sizeof(buf));
342 assert_int_equal(strlen(buf), 26);
343 assert_int_equal(buf[4], '-');
344 assert_int_equal(buf[7], '-');
345 assert_int_equal(buf[10], 'T');
346 assert_int_equal(buf[13], ':');
347 assert_int_equal(buf[16], ':');
348 assert_int_equal(buf[19], '.');
349
350 /* check time conversion correctness */
351 memset(buf, 'X', sizeof(buf));
352 isc_time_settoepoch(&t);
353 isc_time_formatISO8601Lus(&t, buf, sizeof(buf));
354 assert_string_equal(buf, "1969-12-31T16:00:00.000000");
355
356 memset(buf, 'X', sizeof(buf));
357 isc_time_set(&t, 1450000000, 123456000);
358 isc_time_formatISO8601Lus(&t, buf, sizeof(buf));
359 assert_string_equal(buf, "2015-12-13T01:46:40.123456");
360 }
361
362 /* print UTC time as yyyymmddhhmmsssss */
363
364 ISC_RUN_TEST_IMPL(isc_time_formatshorttimestamp_test) {
365 isc_time_t t;
366 char buf[64];
367
368 UNUSED(state);
369
370 setenv("TZ", "America/Los_Angeles", 1);
371 t = isc_time_now();
372
373 /* check formatting: yyyymmddhhmmsssss */
374 memset(buf, 'X', sizeof(buf));
375 isc_time_formatshorttimestamp(&t, buf, sizeof(buf));
376 assert_int_equal(strlen(buf), 17);
377
378 /* check time conversion correctness */
379 memset(buf, 'X', sizeof(buf));
380 isc_time_settoepoch(&t);
381 isc_time_formatshorttimestamp(&t, buf, sizeof(buf));
382 assert_string_equal(buf, "19700101000000000");
383
384 memset(buf, 'X', sizeof(buf));
385 isc_time_set(&t, 1450000000, 123000000);
386 isc_time_formatshorttimestamp(&t, buf, sizeof(buf));
387 assert_string_equal(buf, "20151213094640123");
388 }
389
390 ISC_TEST_LIST_START
391
392 ISC_TEST_ENTRY(isc_time_add_test)
393 ISC_TEST_ENTRY(isc_time_sub_test)
394 ISC_TEST_ENTRY(isc_time_parsehttptimestamp_test)
395 ISC_TEST_ENTRY(isc_time_formatISO8601_test)
396 ISC_TEST_ENTRY(isc_time_formatISO8601ms_test)
397 ISC_TEST_ENTRY(isc_time_formatISO8601us_test)
398 ISC_TEST_ENTRY(isc_time_formatISO8601L_test)
399 ISC_TEST_ENTRY(isc_time_formatISO8601Lms_test)
400 ISC_TEST_ENTRY(isc_time_formatISO8601Lus_test)
401 ISC_TEST_ENTRY(isc_time_formatshorttimestamp_test)
402
403 ISC_TEST_LIST_END
404
405 ISC_TEST_MAIN
406