Home | History | Annotate | Line # | Download | only in isc
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