#include <isc/time.h>
#include <isc/util.h>
+#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) {
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),