From 04511736a041ff4578eeb196b116f1c0aab88ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Wed, 20 Oct 2021 12:06:09 +0200 Subject: [PATCH] Add isc_time_add and isc_time_subtract unit test The isc_time_add() and isc_time_subtract() didn't have a unit test, add the unit test with couple of edge case vectors to check whether overflow and underflow is correctly handled. --- lib/isc/tests/time_test.c | 107 ++++++++++++++++++++++++++++++++++++++ lib/isc/time.c | 4 ++ 2 files changed, 111 insertions(+) diff --git a/lib/isc/tests/time_test.c b/lib/isc/tests/time_test.c index 52e0653422..22ceb90426 100644 --- a/lib/isc/tests/time_test.c +++ b/lib/isc/tests/time_test.c @@ -26,6 +26,111 @@ #include #include +#include "../time.c" + +#define NS_PER_S 1000000000 /*%< Nanoseconds per second. */ +#define MAX_NS (NS_PER_S - 1) + +struct time_vectors { + isc_time_t a; + isc_interval_t b; + isc_time_t r; + isc_result_t result; +}; + +const struct time_vectors vectors_add[8] = { + { { 0, 0 }, { 0, 0 }, { 0, 0 }, ISC_R_SUCCESS }, + { { 0, MAX_NS }, { 0, MAX_NS }, { 1, MAX_NS - 1 }, ISC_R_SUCCESS }, + { { 0, NS_PER_S / 2 }, { 0, NS_PER_S / 2 }, { 1, 0 }, ISC_R_SUCCESS }, + { { UINT_MAX, MAX_NS }, { 0, 0 }, { UINT_MAX, MAX_NS }, ISC_R_SUCCESS }, + { { UINT_MAX, 0 }, { 0, MAX_NS }, { UINT_MAX, MAX_NS }, ISC_R_SUCCESS }, + { { UINT_MAX, 0 }, { 1, 0 }, { 0, 0 }, ISC_R_RANGE }, + { { UINT_MAX, MAX_NS }, { 0, 1 }, { 0, 0 }, ISC_R_RANGE }, + { { UINT_MAX / 2 + 1, NS_PER_S / 2 }, + { UINT_MAX / 2, NS_PER_S / 2 }, + { 0, 0 }, + ISC_R_RANGE }, +}; + +const struct time_vectors vectors_sub[7] = { + { { 0, 0 }, { 0, 0 }, { 0, 0 }, ISC_R_SUCCESS }, + { { 1, 0 }, { 0, MAX_NS }, { 0, 1 }, ISC_R_SUCCESS }, + { { 1, NS_PER_S / 2 }, + { 0, MAX_NS }, + { 0, NS_PER_S / 2 + 1 }, + ISC_R_SUCCESS }, + { { UINT_MAX, MAX_NS }, { UINT_MAX, 0 }, { 0, MAX_NS }, ISC_R_SUCCESS }, + { { 0, 0 }, { 1, 0 }, { 0, 0 }, ISC_R_RANGE }, + { { 0, 0 }, { 0, MAX_NS }, { 0, 0 }, ISC_R_RANGE }, +}; + +static void +isc_time_add_test(void **state) { + UNUSED(state); + + for (size_t i = 0; i < ARRAY_SIZE(vectors_add); i++) { + isc_time_t r = { UINT_MAX, UINT_MAX }; + isc_result_t result = isc_time_add(&(vectors_add[i].a), + &(vectors_add[i].b), &r); + assert_int_equal(result, vectors_add[i].result); + if (result != ISC_R_SUCCESS) { + continue; + } + + assert_int_equal(r.seconds, vectors_add[i].r.seconds); + assert_int_equal(r.nanoseconds, vectors_add[i].r.nanoseconds); + } + + expect_assert_failure((void)isc_time_add(&(isc_time_t){ 0, MAX_NS + 1 }, + &(isc_interval_t){ 0, 0 }, + &(isc_time_t){ 0, 0 })); + expect_assert_failure((void)isc_time_add( + &(isc_time_t){ 0, 0 }, &(isc_interval_t){ 0, MAX_NS + 1 }, + &(isc_time_t){ 0, 0 })); + + expect_assert_failure((void)isc_time_add((isc_time_t *)NULL, + &(isc_interval_t){ 0, 0 }, + &(isc_time_t){ 0, 0 })); + expect_assert_failure((void)isc_time_add(&(isc_time_t){ 0, 0 }, + (isc_interval_t *)NULL, + &(isc_time_t){ 0, 0 })); + expect_assert_failure((void)isc_time_add( + &(isc_time_t){ 0, 0 }, &(isc_interval_t){ 0, 0 }, NULL)); +} + +static void +isc_time_sub_test(void **state) { + UNUSED(state); + + for (size_t i = 0; i < ARRAY_SIZE(vectors_sub); i++) { + isc_time_t r = { UINT_MAX, UINT_MAX }; + isc_result_t result = isc_time_subtract( + &(vectors_sub[i].a), &(vectors_sub[i].b), &r); + assert_int_equal(result, vectors_sub[i].result); + if (result != ISC_R_SUCCESS) { + continue; + } + assert_int_equal(r.seconds, vectors_sub[i].r.seconds); + assert_int_equal(r.nanoseconds, vectors_sub[i].r.nanoseconds); + } + + expect_assert_failure((void)isc_time_subtract( + &(isc_time_t){ 0, MAX_NS + 1 }, &(isc_interval_t){ 0, 0 }, + &(isc_time_t){ 0, 0 })); + expect_assert_failure((void)isc_time_subtract( + &(isc_time_t){ 0, 0 }, &(isc_interval_t){ 0, MAX_NS + 1 }, + &(isc_time_t){ 0, 0 })); + + expect_assert_failure((void)isc_time_subtract((isc_time_t *)NULL, + &(isc_interval_t){ 0, 0 }, + &(isc_time_t){ 0, 0 })); + expect_assert_failure((void)isc_time_subtract(&(isc_time_t){ 0, 0 }, + (isc_interval_t *)NULL, + &(isc_time_t){ 0, 0 })); + expect_assert_failure((void)isc_time_subtract( + &(isc_time_t){ 0, 0 }, &(isc_interval_t){ 0, 0 }, NULL)); +} + /* parse http time stamp */ static void isc_time_parsehttptimestamp_test(void **state) { @@ -295,6 +400,8 @@ isc_time_formatshorttimestamp_test(void **state) { int main(void) { const struct CMUnitTest tests[] = { + cmocka_unit_test(isc_time_add_test), + cmocka_unit_test(isc_time_sub_test), cmocka_unit_test(isc_time_parsehttptimestamp_test), cmocka_unit_test(isc_time_formatISO8601_test), cmocka_unit_test(isc_time_formatISO8601ms_test), diff --git a/lib/isc/time.c b/lib/isc/time.c index 77ac0da28f..83da8df0ee 100644 --- a/lib/isc/time.c +++ b/lib/isc/time.c @@ -53,8 +53,10 @@ *** Intervals ***/ +#if !defined(UNIT_TESTING) static const isc_interval_t zero_interval = { 0, 0 }; const isc_interval_t *const isc_interval_zero = &zero_interval; +#endif void isc_interval_set(isc_interval_t *i, unsigned int seconds, @@ -90,8 +92,10 @@ isc_interval_ms(const isc_interval_t *i) { *** Absolute Times ***/ +#if !defined(UNIT_TESTING) static const isc_time_t epoch = { 0, 0 }; const isc_time_t *const isc_time_epoch = &epoch; +#endif void isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {