2018-02-27 14:29:49 -08:00
|
|
|
/*
|
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
|
|
|
*
|
2021-06-03 08:37:05 +02:00
|
|
|
* SPDX-License-Identifier: MPL-2.0
|
|
|
|
*
|
2018-02-27 14:29:49 -08:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
2020-09-14 16:20:40 -07:00
|
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
2018-02-27 14:29:49 -08:00
|
|
|
*
|
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
|
|
* information regarding copyright ownership.
|
|
|
|
*/
|
|
|
|
|
2020-03-17 11:18:36 -07:00
|
|
|
#include <inttypes.h>
|
2020-02-12 13:59:18 +01:00
|
|
|
#include <sched.h> /* IWYU pragma: keep */
|
|
|
|
#include <setjmp.h>
|
2018-10-24 08:48:41 -07:00
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2018-02-27 14:29:49 -08:00
|
|
|
#include <unistd.h>
|
|
|
|
|
2018-10-24 08:48:41 -07:00
|
|
|
#define UNIT_TESTING
|
|
|
|
#include <cmocka.h>
|
|
|
|
|
2019-07-04 14:21:15 +02:00
|
|
|
#include <isc/atomic.h>
|
2018-10-24 08:48:41 -07:00
|
|
|
#include <isc/commandline.h>
|
2020-02-12 13:59:18 +01:00
|
|
|
#include <isc/condition.h>
|
2022-07-26 13:03:40 +02:00
|
|
|
#include <isc/job.h>
|
|
|
|
#include <isc/loop.h>
|
2018-02-27 14:29:49 -08:00
|
|
|
#include <isc/mem.h>
|
2022-07-26 13:03:40 +02:00
|
|
|
#include <isc/os.h>
|
2018-02-27 14:29:49 -08:00
|
|
|
#include <isc/time.h>
|
|
|
|
#include <isc/timer.h>
|
|
|
|
#include <isc/util.h>
|
2022-05-03 11:37:31 +02:00
|
|
|
#include <isc/uv.h>
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2022-05-03 11:37:31 +02:00
|
|
|
#include "timer.c"
|
Give the unit tests a big overhaul
The unit tests contain a lot of duplicated code and here's an attempt
to reduce code duplication.
This commit does several things:
1. Remove #ifdef HAVE_CMOCKA - we already solve this with automake
conditionals.
2. Create a set of ISC_TEST_* and ISC_*_TEST_ macros to wrap the test
implementations, test lists, and the main test routine, so we don't
have to repeat this all over again. The macros were modeled after
libuv test suite but adapted to cmocka as the test driver.
A simple example of a unit test would be:
ISC_RUN_TEST_IMPL(test1) { assert_true(true); }
ISC_TEST_LIST_START
ISC_TEST_ENTRY(test1)
ISC_TEST_LIST_END
ISC_TEST_MAIN (Discussion: Should this be ISC_TEST_RUN ?)
For more complicated examples including group setup and teardown
functions, and per-test setup and teardown functions.
3. The macros prefix the test functions and cmocka entries, so the name
of the test can now match the tested function name, and we don't have
to append `_test` because `run_test_` is automatically prepended to
the main test function, and `setup_test_` and `teardown_test_` is
prepended to setup and teardown function.
4. Update all the unit tests to use the new syntax and fix a few bits
here and there.
5. In the future, we can separate the test declarations and test
implementations which are going to greatly help with uncluttering the
bigger unit tests like doh_test and netmgr_test, because the test
implementations are not declared static (see `ISC_RUN_TEST_DECLARE`
and `ISC_RUN_TEST_IMPL` for more details.
NOTE: This heavily relies on preprocessor macros, but the result greatly
outweighs all the negatives of using the macros. There's less
duplicated code, the tests are more uniform and the implementation can
be more flexible.
2022-05-02 10:56:42 +02:00
|
|
|
|
2022-05-03 11:37:31 +02:00
|
|
|
#include <tests/isc.h>
|
2019-11-09 14:01:25 +01:00
|
|
|
|
2018-11-16 08:19:06 +00:00
|
|
|
/* Set to true (or use -v option) for verbose output */
|
2018-10-24 08:48:41 -07:00
|
|
|
static bool verbose = false;
|
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
#define FUDGE_SECONDS 0 /* in absence of clock_getres() */
|
2020-02-12 13:59:18 +01:00
|
|
|
#define FUDGE_NANOSECONDS 500000000 /* in absence of clock_getres() */
|
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
static isc_timer_t *timer = NULL;
|
|
|
|
static isc_time_t endtime;
|
|
|
|
static isc_mutex_t lasttime_mx;
|
|
|
|
static isc_time_t lasttime;
|
|
|
|
static int seconds;
|
|
|
|
static int nanoseconds;
|
|
|
|
static atomic_int_fast32_t eventcnt;
|
2019-11-12 12:15:10 +01:00
|
|
|
static atomic_uint_fast32_t errcnt;
|
2020-02-13 14:44:37 -08:00
|
|
|
static int nevents;
|
2018-10-24 08:48:41 -07:00
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
typedef struct setup_test_arg {
|
|
|
|
isc_timertype_t timertype;
|
|
|
|
isc_interval_t *interval;
|
|
|
|
isc_job_cb action;
|
|
|
|
} setup_test_arg_t;
|
2019-11-12 12:15:10 +01:00
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
static void
|
|
|
|
setup_test_run(void *data) {
|
|
|
|
isc_timertype_t timertype = ((setup_test_arg_t *)data)->timertype;
|
|
|
|
isc_interval_t *interval = ((setup_test_arg_t *)data)->interval;
|
|
|
|
isc_job_cb action = ((setup_test_arg_t *)data)->action;
|
|
|
|
isc_result_t result;
|
2018-10-24 08:48:41 -07:00
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
isc_mutex_lock(&lasttime_mx);
|
|
|
|
result = isc_time_now(&lasttime);
|
|
|
|
UNLOCK(&lasttime_mx);
|
|
|
|
assert_int_equal(result, ISC_R_SUCCESS);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
isc_timer_create(mainloop, action, (void *)timertype, &timer);
|
|
|
|
isc_timer_start(timer, timertype, interval);
|
2018-02-27 14:29:49 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2022-03-11 23:08:17 +01:00
|
|
|
setup_test(isc_timertype_t timertype, isc_interval_t *interval,
|
2022-07-26 13:03:40 +02:00
|
|
|
isc_job_cb action) {
|
|
|
|
setup_test_arg_t arg = { .timertype = timertype,
|
|
|
|
.interval = interval,
|
|
|
|
.action = action };
|
|
|
|
|
2018-02-27 14:29:49 -08:00
|
|
|
isc_time_settoepoch(&endtime);
|
2019-07-04 14:21:15 +02:00
|
|
|
atomic_init(&eventcnt, 0);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2019-12-04 10:41:40 +01:00
|
|
|
isc_mutex_init(&lasttime_mx);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2021-06-03 19:31:34 +10:00
|
|
|
atomic_store(&errcnt, ISC_R_SUCCESS);
|
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
isc_loop_setup(mainloop, setup_test_run, &arg);
|
|
|
|
isc_loopmgr_run(loopmgr);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2019-11-12 12:15:10 +01:00
|
|
|
assert_int_equal(atomic_load(&errcnt), ISC_R_SUCCESS);
|
|
|
|
|
2022-08-24 16:41:55 +10:00
|
|
|
isc_mutex_destroy(&lasttime_mx);
|
2018-02-27 14:29:49 -08:00
|
|
|
}
|
|
|
|
|
2019-11-12 12:15:10 +01:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
set_global_error(isc_result_t result) {
|
2020-02-12 13:59:18 +01:00
|
|
|
(void)atomic_compare_exchange_strong(
|
|
|
|
&errcnt, &(uint_fast32_t){ ISC_R_SUCCESS }, result);
|
2019-11-12 12:15:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2021-06-03 11:55:31 +10:00
|
|
|
subthread_assert_true(bool expected, const char *file, unsigned int line) {
|
2019-11-12 12:15:10 +01:00
|
|
|
if (!expected) {
|
2021-06-03 11:55:31 +10:00
|
|
|
printf("# %s:%u subthread_assert_true\n", file, line);
|
2019-11-12 12:15:10 +01:00
|
|
|
set_global_error(ISC_R_UNEXPECTED);
|
|
|
|
}
|
|
|
|
}
|
2021-06-03 11:55:31 +10:00
|
|
|
#define subthread_assert_true(expected) \
|
|
|
|
subthread_assert_true(expected, __FILE__, __LINE__)
|
2019-11-12 12:15:10 +01:00
|
|
|
|
|
|
|
static void
|
2021-06-03 11:55:31 +10:00
|
|
|
subthread_assert_result_equal(isc_result_t result, isc_result_t expected,
|
|
|
|
const char *file, unsigned int line) {
|
2019-11-12 12:15:10 +01:00
|
|
|
if (result != expected) {
|
2021-06-03 11:55:31 +10:00
|
|
|
printf("# %s:%u subthread_assert_result_equal(%u != %u)\n",
|
Give the unit tests a big overhaul
The unit tests contain a lot of duplicated code and here's an attempt
to reduce code duplication.
This commit does several things:
1. Remove #ifdef HAVE_CMOCKA - we already solve this with automake
conditionals.
2. Create a set of ISC_TEST_* and ISC_*_TEST_ macros to wrap the test
implementations, test lists, and the main test routine, so we don't
have to repeat this all over again. The macros were modeled after
libuv test suite but adapted to cmocka as the test driver.
A simple example of a unit test would be:
ISC_RUN_TEST_IMPL(test1) { assert_true(true); }
ISC_TEST_LIST_START
ISC_TEST_ENTRY(test1)
ISC_TEST_LIST_END
ISC_TEST_MAIN (Discussion: Should this be ISC_TEST_RUN ?)
For more complicated examples including group setup and teardown
functions, and per-test setup and teardown functions.
3. The macros prefix the test functions and cmocka entries, so the name
of the test can now match the tested function name, and we don't have
to append `_test` because `run_test_` is automatically prepended to
the main test function, and `setup_test_` and `teardown_test_` is
prepended to setup and teardown function.
4. Update all the unit tests to use the new syntax and fix a few bits
here and there.
5. In the future, we can separate the test declarations and test
implementations which are going to greatly help with uncluttering the
bigger unit tests like doh_test and netmgr_test, because the test
implementations are not declared static (see `ISC_RUN_TEST_DECLARE`
and `ISC_RUN_TEST_IMPL` for more details.
NOTE: This heavily relies on preprocessor macros, but the result greatly
outweighs all the negatives of using the macros. There's less
duplicated code, the tests are more uniform and the implementation can
be more flexible.
2022-05-02 10:56:42 +02:00
|
|
|
file, line, (unsigned int)result,
|
|
|
|
(unsigned int)expected);
|
2019-11-12 12:15:10 +01:00
|
|
|
set_global_error(result);
|
|
|
|
}
|
|
|
|
}
|
2021-06-03 11:55:31 +10:00
|
|
|
#define subthread_assert_result_equal(observed, expected) \
|
|
|
|
subthread_assert_result_equal(observed, expected, __FILE__, __LINE__)
|
2019-11-12 12:15:10 +01:00
|
|
|
|
2018-02-27 14:29:49 -08:00
|
|
|
static void
|
2022-07-26 13:03:40 +02:00
|
|
|
ticktock(void *arg) {
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
|
|
|
isc_time_t now;
|
|
|
|
isc_time_t base;
|
|
|
|
isc_time_t ulim;
|
|
|
|
isc_time_t llim;
|
|
|
|
isc_interval_t interval;
|
2019-07-04 14:21:15 +02:00
|
|
|
int tick = atomic_fetch_add(&eventcnt, 1);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
UNUSED(arg);
|
|
|
|
|
2018-10-24 08:48:41 -07:00
|
|
|
if (verbose) {
|
2019-07-04 14:21:15 +02:00
|
|
|
print_message("# tick %d\n", tick);
|
2018-10-24 08:48:41 -07:00
|
|
|
}
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
result = isc_time_now(&now);
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_result_equal(result, ISC_R_SUCCESS);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
isc_interval_set(&interval, seconds, nanoseconds);
|
2019-11-12 11:50:11 +01:00
|
|
|
isc_mutex_lock(&lasttime_mx);
|
2018-02-27 14:29:49 -08:00
|
|
|
result = isc_time_add(&lasttime, &interval, &base);
|
2019-11-12 11:50:11 +01:00
|
|
|
isc_mutex_unlock(&lasttime_mx);
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_result_equal(result, ISC_R_SUCCESS);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
isc_interval_set(&interval, FUDGE_SECONDS, FUDGE_NANOSECONDS);
|
|
|
|
result = isc_time_add(&base, &interval, &ulim);
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_result_equal(result, ISC_R_SUCCESS);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
result = isc_time_subtract(&base, &interval, &llim);
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_result_equal(result, ISC_R_SUCCESS);
|
|
|
|
|
|
|
|
subthread_assert_true(isc_time_compare(&llim, &now) <= 0);
|
|
|
|
subthread_assert_true(isc_time_compare(&ulim, &now) >= 0);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2019-11-12 11:50:11 +01:00
|
|
|
isc_interval_set(&interval, 0, 0);
|
|
|
|
isc_mutex_lock(&lasttime_mx);
|
2019-11-12 12:15:10 +01:00
|
|
|
result = isc_time_add(&now, &interval, &lasttime);
|
2019-11-12 11:50:11 +01:00
|
|
|
isc_mutex_unlock(&lasttime_mx);
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_result_equal(result, ISC_R_SUCCESS);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2019-07-04 14:21:15 +02:00
|
|
|
if (atomic_load(&eventcnt) == nevents) {
|
2018-02-27 14:29:49 -08:00
|
|
|
result = isc_time_now(&endtime);
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_result_equal(result, ISC_R_SUCCESS);
|
2022-04-02 00:42:20 +02:00
|
|
|
isc_timer_destroy(&timer);
|
2022-07-26 13:03:40 +02:00
|
|
|
isc_loopmgr_shutdown(loopmgr);
|
2018-02-27 14:29:49 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Individual unit tests
|
|
|
|
*/
|
|
|
|
|
2018-10-24 08:48:41 -07:00
|
|
|
/* timer type ticker */
|
Give the unit tests a big overhaul
The unit tests contain a lot of duplicated code and here's an attempt
to reduce code duplication.
This commit does several things:
1. Remove #ifdef HAVE_CMOCKA - we already solve this with automake
conditionals.
2. Create a set of ISC_TEST_* and ISC_*_TEST_ macros to wrap the test
implementations, test lists, and the main test routine, so we don't
have to repeat this all over again. The macros were modeled after
libuv test suite but adapted to cmocka as the test driver.
A simple example of a unit test would be:
ISC_RUN_TEST_IMPL(test1) { assert_true(true); }
ISC_TEST_LIST_START
ISC_TEST_ENTRY(test1)
ISC_TEST_LIST_END
ISC_TEST_MAIN (Discussion: Should this be ISC_TEST_RUN ?)
For more complicated examples including group setup and teardown
functions, and per-test setup and teardown functions.
3. The macros prefix the test functions and cmocka entries, so the name
of the test can now match the tested function name, and we don't have
to append `_test` because `run_test_` is automatically prepended to
the main test function, and `setup_test_` and `teardown_test_` is
prepended to setup and teardown function.
4. Update all the unit tests to use the new syntax and fix a few bits
here and there.
5. In the future, we can separate the test declarations and test
implementations which are going to greatly help with uncluttering the
bigger unit tests like doh_test and netmgr_test, because the test
implementations are not declared static (see `ISC_RUN_TEST_DECLARE`
and `ISC_RUN_TEST_IMPL` for more details.
NOTE: This heavily relies on preprocessor macros, but the result greatly
outweighs all the negatives of using the macros. There's less
duplicated code, the tests are more uniform and the implementation can
be more flexible.
2022-05-02 10:56:42 +02:00
|
|
|
ISC_RUN_TEST_IMPL(ticker) {
|
2018-02-27 14:29:49 -08:00
|
|
|
isc_interval_t interval;
|
|
|
|
|
2018-10-24 08:48:41 -07:00
|
|
|
UNUSED(state);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
nevents = 12;
|
|
|
|
seconds = 0;
|
|
|
|
nanoseconds = 500000000;
|
|
|
|
|
|
|
|
isc_interval_set(&interval, seconds, nanoseconds);
|
|
|
|
|
2022-03-11 23:08:17 +01:00
|
|
|
setup_test(isc_timertype_ticker, &interval, ticktock);
|
2018-02-27 14:29:49 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2022-07-26 13:03:40 +02:00
|
|
|
test_idle(void *arg) {
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
|
|
|
isc_time_t now;
|
|
|
|
isc_time_t base;
|
|
|
|
isc_time_t ulim;
|
|
|
|
isc_time_t llim;
|
2018-02-27 14:29:49 -08:00
|
|
|
isc_interval_t interval;
|
2019-07-04 14:21:15 +02:00
|
|
|
int tick = atomic_fetch_add(&eventcnt, 1);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
UNUSED(arg);
|
|
|
|
|
2018-10-24 08:48:41 -07:00
|
|
|
if (verbose) {
|
2019-07-04 14:21:15 +02:00
|
|
|
print_message("# tick %d\n", tick);
|
2018-10-24 08:48:41 -07:00
|
|
|
}
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
result = isc_time_now(&now);
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_result_equal(result, ISC_R_SUCCESS);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
isc_interval_set(&interval, seconds, nanoseconds);
|
2019-11-12 11:50:11 +01:00
|
|
|
isc_mutex_lock(&lasttime_mx);
|
2018-02-27 14:29:49 -08:00
|
|
|
result = isc_time_add(&lasttime, &interval, &base);
|
2019-11-12 11:50:11 +01:00
|
|
|
isc_mutex_unlock(&lasttime_mx);
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_result_equal(result, ISC_R_SUCCESS);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
isc_interval_set(&interval, FUDGE_SECONDS, FUDGE_NANOSECONDS);
|
|
|
|
result = isc_time_add(&base, &interval, &ulim);
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_result_equal(result, ISC_R_SUCCESS);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
result = isc_time_subtract(&base, &interval, &llim);
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_result_equal(result, ISC_R_SUCCESS);
|
|
|
|
|
|
|
|
subthread_assert_true(isc_time_compare(&llim, &now) <= 0);
|
|
|
|
subthread_assert_true(isc_time_compare(&ulim, &now) >= 0);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2019-11-12 11:50:11 +01:00
|
|
|
isc_interval_set(&interval, 0, 0);
|
|
|
|
isc_mutex_lock(&lasttime_mx);
|
|
|
|
isc_time_add(&now, &interval, &lasttime);
|
|
|
|
isc_mutex_unlock(&lasttime_mx);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2022-04-02 00:42:20 +02:00
|
|
|
isc_timer_destroy(&timer);
|
2022-07-26 13:03:40 +02:00
|
|
|
isc_loopmgr_shutdown(loopmgr);
|
2018-02-27 14:29:49 -08:00
|
|
|
}
|
|
|
|
|
2018-10-24 08:48:41 -07:00
|
|
|
/* timer type once idles out */
|
Give the unit tests a big overhaul
The unit tests contain a lot of duplicated code and here's an attempt
to reduce code duplication.
This commit does several things:
1. Remove #ifdef HAVE_CMOCKA - we already solve this with automake
conditionals.
2. Create a set of ISC_TEST_* and ISC_*_TEST_ macros to wrap the test
implementations, test lists, and the main test routine, so we don't
have to repeat this all over again. The macros were modeled after
libuv test suite but adapted to cmocka as the test driver.
A simple example of a unit test would be:
ISC_RUN_TEST_IMPL(test1) { assert_true(true); }
ISC_TEST_LIST_START
ISC_TEST_ENTRY(test1)
ISC_TEST_LIST_END
ISC_TEST_MAIN (Discussion: Should this be ISC_TEST_RUN ?)
For more complicated examples including group setup and teardown
functions, and per-test setup and teardown functions.
3. The macros prefix the test functions and cmocka entries, so the name
of the test can now match the tested function name, and we don't have
to append `_test` because `run_test_` is automatically prepended to
the main test function, and `setup_test_` and `teardown_test_` is
prepended to setup and teardown function.
4. Update all the unit tests to use the new syntax and fix a few bits
here and there.
5. In the future, we can separate the test declarations and test
implementations which are going to greatly help with uncluttering the
bigger unit tests like doh_test and netmgr_test, because the test
implementations are not declared static (see `ISC_RUN_TEST_DECLARE`
and `ISC_RUN_TEST_IMPL` for more details.
NOTE: This heavily relies on preprocessor macros, but the result greatly
outweighs all the negatives of using the macros. There's less
duplicated code, the tests are more uniform and the implementation can
be more flexible.
2022-05-02 10:56:42 +02:00
|
|
|
ISC_RUN_TEST_IMPL(once_idle) {
|
2018-02-27 14:29:49 -08:00
|
|
|
isc_interval_t interval;
|
|
|
|
|
2018-10-24 08:48:41 -07:00
|
|
|
UNUSED(state);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
nevents = 1;
|
|
|
|
seconds = 1;
|
|
|
|
nanoseconds = 200000000;
|
|
|
|
|
|
|
|
isc_interval_set(&interval, seconds, nanoseconds);
|
|
|
|
|
2022-03-11 23:08:17 +01:00
|
|
|
setup_test(isc_timertype_once, &interval, test_idle);
|
2018-02-27 14:29:49 -08:00
|
|
|
}
|
|
|
|
|
2018-10-24 08:48:41 -07:00
|
|
|
/* timer reset */
|
2018-02-27 14:29:49 -08:00
|
|
|
static void
|
2022-07-26 13:03:40 +02:00
|
|
|
test_reset(void *arg) {
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
|
|
|
isc_time_t now;
|
|
|
|
isc_time_t base;
|
|
|
|
isc_time_t ulim;
|
|
|
|
isc_time_t llim;
|
2018-02-27 14:29:49 -08:00
|
|
|
isc_interval_t interval;
|
2019-07-04 14:21:15 +02:00
|
|
|
int tick = atomic_fetch_add(&eventcnt, 1);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
UNUSED(arg);
|
|
|
|
|
2018-10-24 08:48:41 -07:00
|
|
|
if (verbose) {
|
2019-07-04 14:21:15 +02:00
|
|
|
print_message("# tick %d\n", tick);
|
2018-10-24 08:48:41 -07:00
|
|
|
}
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Check expired time.
|
|
|
|
*/
|
|
|
|
|
|
|
|
result = isc_time_now(&now);
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_result_equal(result, ISC_R_SUCCESS);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
isc_interval_set(&interval, seconds, nanoseconds);
|
2019-11-12 11:50:11 +01:00
|
|
|
isc_mutex_lock(&lasttime_mx);
|
2018-02-27 14:29:49 -08:00
|
|
|
result = isc_time_add(&lasttime, &interval, &base);
|
2019-11-12 11:50:11 +01:00
|
|
|
isc_mutex_unlock(&lasttime_mx);
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_result_equal(result, ISC_R_SUCCESS);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
isc_interval_set(&interval, FUDGE_SECONDS, FUDGE_NANOSECONDS);
|
|
|
|
result = isc_time_add(&base, &interval, &ulim);
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_result_equal(result, ISC_R_SUCCESS);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
result = isc_time_subtract(&base, &interval, &llim);
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_result_equal(result, ISC_R_SUCCESS);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2019-11-12 12:15:10 +01:00
|
|
|
subthread_assert_true(isc_time_compare(&llim, &now) <= 0);
|
|
|
|
subthread_assert_true(isc_time_compare(&ulim, &now) >= 0);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_interval_set(&interval, 0, 0);
|
|
|
|
isc_mutex_lock(&lasttime_mx);
|
2019-11-12 11:50:11 +01:00
|
|
|
isc_time_add(&now, &interval, &lasttime);
|
|
|
|
isc_mutex_unlock(&lasttime_mx);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
if (tick < 2) {
|
|
|
|
if (tick == 1) {
|
2018-02-27 14:29:49 -08:00
|
|
|
isc_interval_set(&interval, seconds, nanoseconds);
|
2022-07-26 13:03:40 +02:00
|
|
|
isc_timer_start(timer, isc_timertype_once, &interval);
|
2018-02-27 14:29:49 -08:00
|
|
|
}
|
|
|
|
} else {
|
2022-04-02 00:42:20 +02:00
|
|
|
isc_timer_destroy(&timer);
|
2022-07-26 13:03:40 +02:00
|
|
|
isc_loopmgr_shutdown(loopmgr);
|
2018-02-27 14:29:49 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Give the unit tests a big overhaul
The unit tests contain a lot of duplicated code and here's an attempt
to reduce code duplication.
This commit does several things:
1. Remove #ifdef HAVE_CMOCKA - we already solve this with automake
conditionals.
2. Create a set of ISC_TEST_* and ISC_*_TEST_ macros to wrap the test
implementations, test lists, and the main test routine, so we don't
have to repeat this all over again. The macros were modeled after
libuv test suite but adapted to cmocka as the test driver.
A simple example of a unit test would be:
ISC_RUN_TEST_IMPL(test1) { assert_true(true); }
ISC_TEST_LIST_START
ISC_TEST_ENTRY(test1)
ISC_TEST_LIST_END
ISC_TEST_MAIN (Discussion: Should this be ISC_TEST_RUN ?)
For more complicated examples including group setup and teardown
functions, and per-test setup and teardown functions.
3. The macros prefix the test functions and cmocka entries, so the name
of the test can now match the tested function name, and we don't have
to append `_test` because `run_test_` is automatically prepended to
the main test function, and `setup_test_` and `teardown_test_` is
prepended to setup and teardown function.
4. Update all the unit tests to use the new syntax and fix a few bits
here and there.
5. In the future, we can separate the test declarations and test
implementations which are going to greatly help with uncluttering the
bigger unit tests like doh_test and netmgr_test, because the test
implementations are not declared static (see `ISC_RUN_TEST_DECLARE`
and `ISC_RUN_TEST_IMPL` for more details.
NOTE: This heavily relies on preprocessor macros, but the result greatly
outweighs all the negatives of using the macros. There's less
duplicated code, the tests are more uniform and the implementation can
be more flexible.
2022-05-02 10:56:42 +02:00
|
|
|
ISC_RUN_TEST_IMPL(reset) {
|
2018-02-27 14:29:49 -08:00
|
|
|
isc_interval_t interval;
|
|
|
|
|
2018-10-24 08:48:41 -07:00
|
|
|
UNUSED(state);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
nevents = 3;
|
|
|
|
seconds = 0;
|
|
|
|
nanoseconds = 750000000;
|
|
|
|
|
|
|
|
isc_interval_set(&interval, seconds, nanoseconds);
|
|
|
|
|
2022-03-11 23:08:17 +01:00
|
|
|
setup_test(isc_timertype_ticker, &interval, test_reset);
|
2018-02-27 14:29:49 -08:00
|
|
|
}
|
|
|
|
|
Refactor taskmgr to run on top of netmgr
This commit changes the taskmgr to run the individual tasks on the
netmgr internal workers. While an effort has been put into keeping the
taskmgr interface intact, couple of changes have been made:
* The taskmgr has no concept of universal privileged mode - rather the
tasks are either privileged or unprivileged (normal). The privileged
tasks are run as a first thing when the netmgr is unpaused. There
are now four different queues in in the netmgr:
1. priority queue - netievent on the priority queue are run even when
the taskmgr enter exclusive mode and netmgr is paused. This is
needed to properly start listening on the interfaces, free
resources and resume.
2. privileged task queue - only privileged tasks are queued here and
this is the first queue that gets processed when network manager
is unpaused using isc_nm_resume(). All netmgr workers need to
clean the privileged task queue before they all proceed normal
operation. Both task queues are processed when the workers are
finished.
3. task queue - only (traditional) task are scheduled here and this
queue along with privileged task queues are process when the
netmgr workers are finishing. This is needed to process the task
shutdown events.
4. normal queue - this is the queue with netmgr events, e.g. reading,
sending, callbacks and pretty much everything is processed here.
* The isc_taskmgr_create() now requires initialized netmgr (isc_nm_t)
object.
* The isc_nm_destroy() function now waits for indefinite time, but it
will print out the active objects when in tracing mode
(-DNETMGR_TRACE=1 and -DNETMGR_TRACE_VERBOSE=1), the netmgr has been
made a little bit more asynchronous and it might take longer time to
shutdown all the active networking connections.
* Previously, the isc_nm_stoplistening() was a synchronous operation.
This has been changed and the isc_nm_stoplistening() just schedules
the child sockets to stop listening and exits. This was needed to
prevent a deadlock as the the (traditional) tasks are now executed on
the netmgr threads.
* The socket selection logic in isc__nm_udp_send() was flawed, but
fortunatelly, it was broken, so we never hit the problem where we
created uvreq_t on a socket from nmhandle_t, but then a different
socket could be picked up and then we were trying to run the send
callback on a socket that had different threadid than currently
running.
2021-04-09 11:31:19 +02:00
|
|
|
static atomic_bool startflag;
|
2018-02-27 14:29:49 -08:00
|
|
|
static isc_timer_t *tickertimer = NULL;
|
|
|
|
static isc_timer_t *oncetimer = NULL;
|
|
|
|
|
|
|
|
static void
|
2022-07-26 13:03:40 +02:00
|
|
|
tick_event(void *arg) {
|
|
|
|
int tick;
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
UNUSED(arg);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
Refactor taskmgr to run on top of netmgr
This commit changes the taskmgr to run the individual tasks on the
netmgr internal workers. While an effort has been put into keeping the
taskmgr interface intact, couple of changes have been made:
* The taskmgr has no concept of universal privileged mode - rather the
tasks are either privileged or unprivileged (normal). The privileged
tasks are run as a first thing when the netmgr is unpaused. There
are now four different queues in in the netmgr:
1. priority queue - netievent on the priority queue are run even when
the taskmgr enter exclusive mode and netmgr is paused. This is
needed to properly start listening on the interfaces, free
resources and resume.
2. privileged task queue - only privileged tasks are queued here and
this is the first queue that gets processed when network manager
is unpaused using isc_nm_resume(). All netmgr workers need to
clean the privileged task queue before they all proceed normal
operation. Both task queues are processed when the workers are
finished.
3. task queue - only (traditional) task are scheduled here and this
queue along with privileged task queues are process when the
netmgr workers are finishing. This is needed to process the task
shutdown events.
4. normal queue - this is the queue with netmgr events, e.g. reading,
sending, callbacks and pretty much everything is processed here.
* The isc_taskmgr_create() now requires initialized netmgr (isc_nm_t)
object.
* The isc_nm_destroy() function now waits for indefinite time, but it
will print out the active objects when in tracing mode
(-DNETMGR_TRACE=1 and -DNETMGR_TRACE_VERBOSE=1), the netmgr has been
made a little bit more asynchronous and it might take longer time to
shutdown all the active networking connections.
* Previously, the isc_nm_stoplistening() was a synchronous operation.
This has been changed and the isc_nm_stoplistening() just schedules
the child sockets to stop listening and exits. This was needed to
prevent a deadlock as the the (traditional) tasks are now executed on
the netmgr threads.
* The socket selection logic in isc__nm_udp_send() was flawed, but
fortunatelly, it was broken, so we never hit the problem where we
created uvreq_t on a socket from nmhandle_t, but then a different
socket could be picked up and then we were trying to run the send
callback on a socket that had different threadid than currently
running.
2021-04-09 11:31:19 +02:00
|
|
|
if (!atomic_load(&startflag)) {
|
|
|
|
if (verbose) {
|
|
|
|
print_message("# tick_event %d\n", -1);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
tick = atomic_fetch_add(&eventcnt, 1);
|
2018-10-24 08:48:41 -07:00
|
|
|
if (verbose) {
|
2019-07-04 14:21:15 +02:00
|
|
|
print_message("# tick_event %d\n", tick);
|
2018-10-24 08:48:41 -07:00
|
|
|
}
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
/*
|
2022-07-26 13:03:40 +02:00
|
|
|
* On the first tick, purge all remaining tick events.
|
2018-02-27 14:29:49 -08:00
|
|
|
*/
|
2019-07-04 14:21:15 +02:00
|
|
|
if (tick == 0) {
|
2022-07-26 13:03:40 +02:00
|
|
|
isc_timer_destroy(&tickertimer);
|
2018-02-27 14:29:49 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2022-07-26 13:03:40 +02:00
|
|
|
once_event(void *arg) {
|
|
|
|
UNUSED(arg);
|
2022-05-09 11:33:09 +02:00
|
|
|
|
2018-10-24 08:48:41 -07:00
|
|
|
if (verbose) {
|
|
|
|
print_message("# once_event\n");
|
|
|
|
}
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Allow task1 to start processing events.
|
|
|
|
*/
|
Refactor taskmgr to run on top of netmgr
This commit changes the taskmgr to run the individual tasks on the
netmgr internal workers. While an effort has been put into keeping the
taskmgr interface intact, couple of changes have been made:
* The taskmgr has no concept of universal privileged mode - rather the
tasks are either privileged or unprivileged (normal). The privileged
tasks are run as a first thing when the netmgr is unpaused. There
are now four different queues in in the netmgr:
1. priority queue - netievent on the priority queue are run even when
the taskmgr enter exclusive mode and netmgr is paused. This is
needed to properly start listening on the interfaces, free
resources and resume.
2. privileged task queue - only privileged tasks are queued here and
this is the first queue that gets processed when network manager
is unpaused using isc_nm_resume(). All netmgr workers need to
clean the privileged task queue before they all proceed normal
operation. Both task queues are processed when the workers are
finished.
3. task queue - only (traditional) task are scheduled here and this
queue along with privileged task queues are process when the
netmgr workers are finishing. This is needed to process the task
shutdown events.
4. normal queue - this is the queue with netmgr events, e.g. reading,
sending, callbacks and pretty much everything is processed here.
* The isc_taskmgr_create() now requires initialized netmgr (isc_nm_t)
object.
* The isc_nm_destroy() function now waits for indefinite time, but it
will print out the active objects when in tracing mode
(-DNETMGR_TRACE=1 and -DNETMGR_TRACE_VERBOSE=1), the netmgr has been
made a little bit more asynchronous and it might take longer time to
shutdown all the active networking connections.
* Previously, the isc_nm_stoplistening() was a synchronous operation.
This has been changed and the isc_nm_stoplistening() just schedules
the child sockets to stop listening and exits. This was needed to
prevent a deadlock as the the (traditional) tasks are now executed on
the netmgr threads.
* The socket selection logic in isc__nm_udp_send() was flawed, but
fortunatelly, it was broken, so we never hit the problem where we
created uvreq_t on a socket from nmhandle_t, but then a different
socket could be picked up and then we were trying to run the send
callback on a socket that had different threadid than currently
running.
2021-04-09 11:31:19 +02:00
|
|
|
atomic_store(&startflag, true);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
isc_loopmgr_shutdown(loopmgr);
|
|
|
|
isc_timer_destroy(&oncetimer);
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LOOP_SETUP_IMPL(purge) {
|
|
|
|
atomic_init(&eventcnt, 0);
|
|
|
|
atomic_store(&errcnt, ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LOOP_TEARDOWN_IMPL(purge) {
|
|
|
|
assert_int_equal(atomic_load(&errcnt), ISC_R_SUCCESS);
|
|
|
|
assert_int_equal(atomic_load(&eventcnt), 1);
|
2018-02-27 14:29:49 -08:00
|
|
|
}
|
|
|
|
|
2018-10-24 08:48:41 -07:00
|
|
|
/* timer events purged */
|
2022-07-26 13:03:40 +02:00
|
|
|
ISC_LOOP_TEST_SETUP_TEARDOWN_IMPL(purge) {
|
2018-02-27 14:29:49 -08:00
|
|
|
isc_interval_t interval;
|
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
UNUSED(arg);
|
|
|
|
|
|
|
|
if (verbose) {
|
|
|
|
print_message("# purge_run\n");
|
|
|
|
}
|
2018-02-27 14:29:49 -08:00
|
|
|
|
Refactor taskmgr to run on top of netmgr
This commit changes the taskmgr to run the individual tasks on the
netmgr internal workers. While an effort has been put into keeping the
taskmgr interface intact, couple of changes have been made:
* The taskmgr has no concept of universal privileged mode - rather the
tasks are either privileged or unprivileged (normal). The privileged
tasks are run as a first thing when the netmgr is unpaused. There
are now four different queues in in the netmgr:
1. priority queue - netievent on the priority queue are run even when
the taskmgr enter exclusive mode and netmgr is paused. This is
needed to properly start listening on the interfaces, free
resources and resume.
2. privileged task queue - only privileged tasks are queued here and
this is the first queue that gets processed when network manager
is unpaused using isc_nm_resume(). All netmgr workers need to
clean the privileged task queue before they all proceed normal
operation. Both task queues are processed when the workers are
finished.
3. task queue - only (traditional) task are scheduled here and this
queue along with privileged task queues are process when the
netmgr workers are finishing. This is needed to process the task
shutdown events.
4. normal queue - this is the queue with netmgr events, e.g. reading,
sending, callbacks and pretty much everything is processed here.
* The isc_taskmgr_create() now requires initialized netmgr (isc_nm_t)
object.
* The isc_nm_destroy() function now waits for indefinite time, but it
will print out the active objects when in tracing mode
(-DNETMGR_TRACE=1 and -DNETMGR_TRACE_VERBOSE=1), the netmgr has been
made a little bit more asynchronous and it might take longer time to
shutdown all the active networking connections.
* Previously, the isc_nm_stoplistening() was a synchronous operation.
This has been changed and the isc_nm_stoplistening() just schedules
the child sockets to stop listening and exits. This was needed to
prevent a deadlock as the the (traditional) tasks are now executed on
the netmgr threads.
* The socket selection logic in isc__nm_udp_send() was flawed, but
fortunatelly, it was broken, so we never hit the problem where we
created uvreq_t on a socket from nmhandle_t, but then a different
socket could be picked up and then we were trying to run the send
callback on a socket that had different threadid than currently
running.
2021-04-09 11:31:19 +02:00
|
|
|
atomic_init(&startflag, 0);
|
2018-02-27 14:29:49 -08:00
|
|
|
seconds = 1;
|
|
|
|
nanoseconds = 0;
|
|
|
|
|
|
|
|
isc_interval_set(&interval, seconds, 0);
|
|
|
|
|
|
|
|
tickertimer = NULL;
|
2022-07-26 13:03:40 +02:00
|
|
|
isc_timer_create(mainloop, tick_event, NULL, &tickertimer);
|
|
|
|
isc_timer_start(tickertimer, isc_timertype_ticker, &interval);
|
2018-02-27 14:29:49 -08:00
|
|
|
|
|
|
|
oncetimer = NULL;
|
|
|
|
|
|
|
|
isc_interval_set(&interval, (seconds * 2) + 1, 0);
|
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
isc_timer_create(mainloop, once_event, NULL, &oncetimer);
|
|
|
|
isc_timer_start(oncetimer, isc_timertype_once, &interval);
|
2018-10-24 08:48:41 -07:00
|
|
|
}
|
2018-02-27 14:29:49 -08:00
|
|
|
|
2022-09-22 09:43:19 +02:00
|
|
|
/*
|
|
|
|
* Set of tests that check whether the rescheduling works as expected.
|
|
|
|
*/
|
|
|
|
|
|
|
|
uint64_t timer_start;
|
|
|
|
uint64_t timer_stop;
|
|
|
|
uint64_t timer_expect;
|
|
|
|
uint64_t timer_ticks;
|
|
|
|
isc_interval_t timer_interval;
|
|
|
|
isc_timertype_t timer_type;
|
|
|
|
|
|
|
|
ISC_LOOP_TEARDOWN_IMPL(timer_expect) {
|
|
|
|
uint64_t diff = (timer_stop - timer_start) / 1000000000;
|
|
|
|
assert_true(diff == timer_expect);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2023-01-10 10:20:44 +01:00
|
|
|
timer_event(void *arg ISC_ATTR_UNUSED) {
|
2022-09-22 09:43:19 +02:00
|
|
|
if (--timer_ticks == 0) {
|
|
|
|
isc_timer_destroy(&timer);
|
|
|
|
isc_loopmgr_shutdown(loopmgr);
|
|
|
|
timer_stop = uv_hrtime();
|
|
|
|
} else {
|
|
|
|
isc_timer_start(timer, timer_type, &timer_interval);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LOOP_SETUP_IMPL(reschedule_up) {
|
|
|
|
timer_start = uv_hrtime();
|
|
|
|
timer_expect = 1;
|
|
|
|
timer_ticks = 1;
|
|
|
|
timer_type = isc_timertype_once;
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LOOP_TEST_CUSTOM_IMPL(reschedule_up, setup_loop_reschedule_up,
|
|
|
|
teardown_loop_timer_expect) {
|
|
|
|
isc_timer_create(mainloop, timer_event, NULL, &timer);
|
|
|
|
|
|
|
|
/* Schedule the timer to fire immediately */
|
|
|
|
isc_interval_set(&timer_interval, 0, 0);
|
|
|
|
isc_timer_start(timer, timer_type, &timer_interval);
|
|
|
|
|
|
|
|
/* And then reschedule it to 2 seconds */
|
|
|
|
isc_interval_set(&timer_interval, 1, 0);
|
|
|
|
isc_timer_start(timer, timer_type, &timer_interval);
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LOOP_SETUP_IMPL(reschedule_down) {
|
|
|
|
timer_start = uv_hrtime();
|
|
|
|
timer_expect = 0;
|
|
|
|
timer_ticks = 1;
|
|
|
|
timer_type = isc_timertype_once;
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LOOP_TEST_CUSTOM_IMPL(reschedule_down, setup_loop_reschedule_down,
|
|
|
|
teardown_loop_timer_expect) {
|
|
|
|
isc_timer_create(mainloop, timer_event, NULL, &timer);
|
|
|
|
|
|
|
|
/* Schedule the timer to fire at 1 second */
|
|
|
|
isc_interval_set(&timer_interval, 10, 0);
|
|
|
|
isc_timer_start(timer, timer_type, &timer_interval);
|
|
|
|
|
|
|
|
/* And then reschedule it fire immediately */
|
|
|
|
isc_interval_set(&timer_interval, 0, 0);
|
|
|
|
isc_timer_start(timer, timer_type, &timer_interval);
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LOOP_SETUP_IMPL(reschedule_from_callback) {
|
|
|
|
timer_start = uv_hrtime();
|
|
|
|
timer_expect = 1;
|
|
|
|
timer_ticks = 2;
|
|
|
|
timer_type = isc_timertype_once;
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LOOP_TEST_CUSTOM_IMPL(reschedule_from_callback,
|
|
|
|
setup_loop_reschedule_from_callback,
|
|
|
|
teardown_loop_timer_expect) {
|
|
|
|
isc_timer_create(mainloop, timer_event, NULL, &timer);
|
|
|
|
|
2022-11-04 12:02:33 +00:00
|
|
|
isc_interval_set(&timer_interval, 0, NS_PER_SEC / 2);
|
2022-09-22 09:43:19 +02:00
|
|
|
isc_timer_start(timer, timer_type, &timer_interval);
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LOOP_SETUP_IMPL(zero) {
|
|
|
|
timer_start = uv_hrtime();
|
|
|
|
timer_expect = 0;
|
|
|
|
timer_ticks = 1;
|
|
|
|
timer_type = isc_timertype_once;
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LOOP_TEST_CUSTOM_IMPL(zero, setup_loop_zero, teardown_loop_timer_expect) {
|
|
|
|
isc_timer_create(mainloop, timer_event, NULL, &timer);
|
|
|
|
|
|
|
|
/* Schedule the timer to fire immediately (in the next event loop) */
|
|
|
|
isc_interval_set(&timer_interval, 0, 0);
|
|
|
|
isc_timer_start(timer, timer_type, &timer_interval);
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LOOP_SETUP_IMPL(reschedule_ticker) {
|
|
|
|
timer_start = uv_hrtime();
|
|
|
|
timer_expect = 1;
|
|
|
|
timer_ticks = 5;
|
|
|
|
timer_type = isc_timertype_ticker;
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LOOP_TEST_CUSTOM_IMPL(reschedule_ticker, setup_loop_reschedule_ticker,
|
|
|
|
teardown_loop_timer_expect) {
|
|
|
|
isc_timer_create(mainloop, timer_event, NULL, &timer);
|
|
|
|
|
|
|
|
/* Schedule the timer to fire immediately (in the next event loop) */
|
|
|
|
isc_interval_set(&timer_interval, 0, 0);
|
|
|
|
isc_timer_start(timer, timer_type, &timer_interval);
|
|
|
|
|
|
|
|
/* Then fire every 1/4 second */
|
2022-11-04 12:02:33 +00:00
|
|
|
isc_interval_set(&timer_interval, 0, NS_PER_SEC / 4);
|
2022-09-22 09:43:19 +02:00
|
|
|
}
|
|
|
|
|
Give the unit tests a big overhaul
The unit tests contain a lot of duplicated code and here's an attempt
to reduce code duplication.
This commit does several things:
1. Remove #ifdef HAVE_CMOCKA - we already solve this with automake
conditionals.
2. Create a set of ISC_TEST_* and ISC_*_TEST_ macros to wrap the test
implementations, test lists, and the main test routine, so we don't
have to repeat this all over again. The macros were modeled after
libuv test suite but adapted to cmocka as the test driver.
A simple example of a unit test would be:
ISC_RUN_TEST_IMPL(test1) { assert_true(true); }
ISC_TEST_LIST_START
ISC_TEST_ENTRY(test1)
ISC_TEST_LIST_END
ISC_TEST_MAIN (Discussion: Should this be ISC_TEST_RUN ?)
For more complicated examples including group setup and teardown
functions, and per-test setup and teardown functions.
3. The macros prefix the test functions and cmocka entries, so the name
of the test can now match the tested function name, and we don't have
to append `_test` because `run_test_` is automatically prepended to
the main test function, and `setup_test_` and `teardown_test_` is
prepended to setup and teardown function.
4. Update all the unit tests to use the new syntax and fix a few bits
here and there.
5. In the future, we can separate the test declarations and test
implementations which are going to greatly help with uncluttering the
bigger unit tests like doh_test and netmgr_test, because the test
implementations are not declared static (see `ISC_RUN_TEST_DECLARE`
and `ISC_RUN_TEST_IMPL` for more details.
NOTE: This heavily relies on preprocessor macros, but the result greatly
outweighs all the negatives of using the macros. There's less
duplicated code, the tests are more uniform and the implementation can
be more flexible.
2022-05-02 10:56:42 +02:00
|
|
|
ISC_TEST_LIST_START
|
2018-10-24 08:48:41 -07:00
|
|
|
|
2022-07-26 13:03:40 +02:00
|
|
|
ISC_TEST_ENTRY_CUSTOM(ticker, setup_loopmgr, teardown_loopmgr)
|
|
|
|
ISC_TEST_ENTRY_CUSTOM(once_idle, setup_loopmgr, teardown_loopmgr)
|
|
|
|
ISC_TEST_ENTRY_CUSTOM(reset, setup_loopmgr, teardown_loopmgr)
|
|
|
|
ISC_TEST_ENTRY_CUSTOM(purge, setup_loopmgr, teardown_loopmgr)
|
2022-09-22 09:43:19 +02:00
|
|
|
ISC_TEST_ENTRY_CUSTOM(reschedule_up, setup_loopmgr, teardown_loopmgr)
|
|
|
|
ISC_TEST_ENTRY_CUSTOM(reschedule_down, setup_loopmgr, teardown_loopmgr)
|
|
|
|
ISC_TEST_ENTRY_CUSTOM(reschedule_from_callback, setup_loopmgr, teardown_loopmgr)
|
|
|
|
ISC_TEST_ENTRY_CUSTOM(zero, setup_loopmgr, teardown_loopmgr)
|
|
|
|
ISC_TEST_ENTRY_CUSTOM(reschedule_ticker, setup_loopmgr, teardown_loopmgr)
|
2018-10-24 08:48:41 -07:00
|
|
|
|
Give the unit tests a big overhaul
The unit tests contain a lot of duplicated code and here's an attempt
to reduce code duplication.
This commit does several things:
1. Remove #ifdef HAVE_CMOCKA - we already solve this with automake
conditionals.
2. Create a set of ISC_TEST_* and ISC_*_TEST_ macros to wrap the test
implementations, test lists, and the main test routine, so we don't
have to repeat this all over again. The macros were modeled after
libuv test suite but adapted to cmocka as the test driver.
A simple example of a unit test would be:
ISC_RUN_TEST_IMPL(test1) { assert_true(true); }
ISC_TEST_LIST_START
ISC_TEST_ENTRY(test1)
ISC_TEST_LIST_END
ISC_TEST_MAIN (Discussion: Should this be ISC_TEST_RUN ?)
For more complicated examples including group setup and teardown
functions, and per-test setup and teardown functions.
3. The macros prefix the test functions and cmocka entries, so the name
of the test can now match the tested function name, and we don't have
to append `_test` because `run_test_` is automatically prepended to
the main test function, and `setup_test_` and `teardown_test_` is
prepended to setup and teardown function.
4. Update all the unit tests to use the new syntax and fix a few bits
here and there.
5. In the future, we can separate the test declarations and test
implementations which are going to greatly help with uncluttering the
bigger unit tests like doh_test and netmgr_test, because the test
implementations are not declared static (see `ISC_RUN_TEST_DECLARE`
and `ISC_RUN_TEST_IMPL` for more details.
NOTE: This heavily relies on preprocessor macros, but the result greatly
outweighs all the negatives of using the macros. There's less
duplicated code, the tests are more uniform and the implementation can
be more flexible.
2022-05-02 10:56:42 +02:00
|
|
|
ISC_TEST_LIST_END
|
2018-10-24 08:48:41 -07:00
|
|
|
|
Give the unit tests a big overhaul
The unit tests contain a lot of duplicated code and here's an attempt
to reduce code duplication.
This commit does several things:
1. Remove #ifdef HAVE_CMOCKA - we already solve this with automake
conditionals.
2. Create a set of ISC_TEST_* and ISC_*_TEST_ macros to wrap the test
implementations, test lists, and the main test routine, so we don't
have to repeat this all over again. The macros were modeled after
libuv test suite but adapted to cmocka as the test driver.
A simple example of a unit test would be:
ISC_RUN_TEST_IMPL(test1) { assert_true(true); }
ISC_TEST_LIST_START
ISC_TEST_ENTRY(test1)
ISC_TEST_LIST_END
ISC_TEST_MAIN (Discussion: Should this be ISC_TEST_RUN ?)
For more complicated examples including group setup and teardown
functions, and per-test setup and teardown functions.
3. The macros prefix the test functions and cmocka entries, so the name
of the test can now match the tested function name, and we don't have
to append `_test` because `run_test_` is automatically prepended to
the main test function, and `setup_test_` and `teardown_test_` is
prepended to setup and teardown function.
4. Update all the unit tests to use the new syntax and fix a few bits
here and there.
5. In the future, we can separate the test declarations and test
implementations which are going to greatly help with uncluttering the
bigger unit tests like doh_test and netmgr_test, because the test
implementations are not declared static (see `ISC_RUN_TEST_DECLARE`
and `ISC_RUN_TEST_IMPL` for more details.
NOTE: This heavily relies on preprocessor macros, but the result greatly
outweighs all the negatives of using the macros. There's less
duplicated code, the tests are more uniform and the implementation can
be more flexible.
2022-05-02 10:56:42 +02:00
|
|
|
ISC_TEST_MAIN
|