Commit 7c4ed646 authored by Evan Hunt's avatar Evan Hunt
Browse files

convert timer_test

(cherry picked from commit 20cef35e)
parent f524cc71
......@@ -29,4 +29,4 @@ tap_test_program{name='symtab_test'}
tap_test_program{name='task_test'}
tap_test_program{name='taskpool_test'}
tap_test_program{name='time_test'}
atf_test_program{name='timer_test'}
tap_test_program{name='timer_test'}
......@@ -186,8 +186,9 @@ time_test@EXEEXT@: time_test.@O@ ${ISCDEPLIBS}
${ISCLIBS} ${LIBS} ${CMOCKA_LIBS}
timer_test@EXEEXT@: timer_test.@O@ isctest.@O@ ${ISCDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
timer_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${CMOCKA_CFLAGS} \
${LDFLAGS} -o $@ timer_test.@O@ isctest.@O@ \
${ISCLIBS} ${LIBS} ${CMOCKA_LIBS}
unit::
sh ${top_builddir}/unit/unittest.sh
......
......@@ -9,15 +9,23 @@
* information regarding copyright ownership.
*/
/*! \file */
#include <config.h>
#include <atf-c.h>
#if HAVE_CMOCKA
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define UNIT_TESTING
#include <cmocka.h>
#include <isc/condition.h>
#include <isc/commandline.h>
#include <isc/mem.h>
#include <isc/platform.h>
#include <isc/print.h>
......@@ -25,7 +33,6 @@
#include <isc/time.h>
#include <isc/timer.h>
#include <isc/util.h>
#include <isc/util.h>
#include "isctest.h"
......@@ -34,21 +41,43 @@
*/
#ifdef ISC_PLATFORM_USETHREADS
/*
* Helper functions
*/
/* Set to true for verbose output */
static bool verbose = false;
#define FUDGE_SECONDS 0 /* in absence of clock_getres() */
#define FUDGE_NANOSECONDS 500000000 /* in absence of clock_getres() */
static isc_timer_t *timer = NULL;
static isc_condition_t cv;
static isc_mutex_t mx;
static isc_time_t endtime;
static isc_time_t lasttime;
static int seconds;
static int nanoseconds;
static int eventcnt;
static int nevents;
static isc_timer_t *timer = NULL;
static isc_condition_t cv;
static isc_mutex_t mx;
static isc_time_t endtime;
static isc_time_t lasttime;
static int seconds;
static int nanoseconds;
static int eventcnt;
static int nevents;
static int
_setup(void **state) {
isc_result_t result;
UNUSED(state);
/* Timer tests require two worker threads */
result = isc_test_begin(NULL, true, 2);
assert_int_equal(result, ISC_R_SUCCESS);
return (0);
}
static int
_teardown(void **state) {
UNUSED(state);
isc_test_end();
return (0);
}
static void
shutdown(isc_task_t *task, isc_event_t *event) {
......@@ -60,13 +89,13 @@ shutdown(isc_task_t *task, isc_event_t *event) {
* Signal shutdown processing complete.
*/
result = isc_mutex_lock(&mx);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_condition_signal(&cv);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_mutex_unlock(&mx);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
isc_event_free(&event);
}
......@@ -82,33 +111,33 @@ setup_test(isc_timertype_t timertype, isc_time_t *expires,
eventcnt = 0;
result = isc_mutex_init(&mx);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_condition_init(&cv);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
LOCK(&mx);
result = isc_task_create(taskmgr, 0, &task);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_onshutdown(task, shutdown, NULL);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_time_now(&lasttime);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_timer_create(timermgr, timertype, expires, interval,
task, action, (void *)timertype,
&timer);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
/*
* Wait for shutdown processing to complete.
*/
while (eventcnt != nevents) {
result = isc_condition_wait(&cv, &mx);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
}
UNLOCK(&mx);
......@@ -130,7 +159,9 @@ ticktock(isc_task_t *task, isc_event_t *event) {
++eventcnt;
printf("tick %d\n", eventcnt);
if (verbose) {
print_message("# tick %d\n", eventcnt);
}
expected_event_type = ISC_TIMEREVENT_LIFE;
if ((isc_timertype_t) event->ev_arg == isc_timertype_ticker) {
......@@ -138,31 +169,31 @@ ticktock(isc_task_t *task, isc_event_t *event) {
}
if (event->ev_type != expected_event_type) {
printf("expected event type %u, got %u\n",
expected_event_type, event->ev_type);
print_error("# expected event type %u, got %u\n",
expected_event_type, event->ev_type);
}
result = isc_time_now(&now);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
isc_interval_set(&interval, seconds, nanoseconds);
result = isc_time_add(&lasttime, &interval, &base);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
isc_interval_set(&interval, FUDGE_SECONDS, FUDGE_NANOSECONDS);
result = isc_time_add(&base, &interval, &ulim);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_time_subtract(&base, &interval, &llim);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
ATF_CHECK(isc_time_compare(&llim, &now) <= 0);
ATF_CHECK(isc_time_compare(&ulim, &now) >= 0);
assert_true(isc_time_compare(&llim, &now) <= 0);
assert_true(isc_time_compare(&ulim, &now) >= 0);
lasttime = now;
if (eventcnt == nevents) {
result = isc_time_now(&endtime);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
isc_timer_detach(&timer);
isc_task_shutdown(task);
}
......@@ -174,62 +205,46 @@ ticktock(isc_task_t *task, isc_event_t *event) {
* Individual unit tests
*/
ATF_TC(ticker);
ATF_TC_HEAD(ticker, tc) {
atf_tc_set_md_var(tc, "descr", "timer type ticker");
}
ATF_TC_BODY(ticker, tc) {
isc_result_t result;
/* timer type ticker */
static void
ticker(void **state) {
isc_time_t expires;
isc_interval_t interval;
UNUSED(tc);
UNUSED(state);
nevents = 12;
seconds = 0;
nanoseconds = 500000000;
result = isc_test_begin(NULL, true, 2);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
isc_interval_set(&interval, seconds, nanoseconds);
isc_time_settoepoch(&expires);
setup_test(isc_timertype_ticker, &expires, &interval, ticktock);
isc_test_end();
}
ATF_TC(once_life);
ATF_TC_HEAD(once_life, tc) {
atf_tc_set_md_var(tc, "descr", "timer type once reaches lifetime");
}
ATF_TC_BODY(once_life, tc) {
/* timer type once reaches lifetime */
static void
once_life(void **state) {
isc_result_t result;
isc_time_t expires;
isc_interval_t interval;
UNUSED(tc);
UNUSED(state);
nevents = 1;
seconds = 1;
nanoseconds = 100000000;
result = isc_test_begin(NULL, true, 2);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
isc_interval_set(&interval, seconds, nanoseconds);
result = isc_time_nowplusinterval(&expires, &interval);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
isc_interval_set(&interval, 0, 0);
setup_test(isc_timertype_once, &expires, &interval, ticktock);
isc_test_end();
}
static void
test_idle(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
......@@ -241,62 +256,58 @@ test_idle(isc_task_t *task, isc_event_t *event) {
++eventcnt;
printf("tick %d\n", eventcnt);
if (verbose) {
print_message("# tick %d\n", eventcnt);
}
result = isc_time_now(&now);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
isc_interval_set(&interval, seconds, nanoseconds);
result = isc_time_add(&lasttime, &interval, &base);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
isc_interval_set(&interval, FUDGE_SECONDS, FUDGE_NANOSECONDS);
result = isc_time_add(&base, &interval, &ulim);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_time_subtract(&base, &interval, &llim);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
ATF_CHECK(isc_time_compare(&llim, &now) <= 0);
ATF_CHECK(isc_time_compare(&ulim, &now) >= 0);
assert_true(isc_time_compare(&llim, &now) <= 0);
assert_true(isc_time_compare(&ulim, &now) >= 0);
lasttime = now;
ATF_CHECK_EQ(event->ev_type, ISC_TIMEREVENT_IDLE);
assert_int_equal(event->ev_type, ISC_TIMEREVENT_IDLE);
isc_timer_detach(&timer);
isc_task_shutdown(task);
isc_event_free(&event);
}
ATF_TC(once_idle);
ATF_TC_HEAD(once_idle, tc) {
atf_tc_set_md_var(tc, "descr", "timer type once idles out");
}
ATF_TC_BODY(once_idle, tc) {
/* timer type once idles out */
static void
once_idle(void **state) {
isc_result_t result;
isc_time_t expires;
isc_interval_t interval;
UNUSED(tc);
UNUSED(state);
nevents = 1;
seconds = 1;
nanoseconds = 200000000;
result = isc_test_begin(NULL, true, 2);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
isc_interval_set(&interval, seconds + 1, nanoseconds);
result = isc_time_nowplusinterval(&expires, &interval);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
isc_interval_set(&interval, seconds, nanoseconds);
setup_test(isc_timertype_once, &expires, &interval, test_idle);
isc_test_end();
}
/* timer reset */
static void
test_reset(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
......@@ -309,46 +320,48 @@ test_reset(isc_task_t *task, isc_event_t *event) {
++eventcnt;
printf("tick %d\n", eventcnt);
if (verbose) {
print_message("# tick %d\n", eventcnt);
}
/*
* Check expired time.
*/
result = isc_time_now(&now);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
isc_interval_set(&interval, seconds, nanoseconds);
result = isc_time_add(&lasttime, &interval, &base);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
isc_interval_set(&interval, FUDGE_SECONDS, FUDGE_NANOSECONDS);
result = isc_time_add(&base, &interval, &ulim);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_time_subtract(&base, &interval, &llim);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
ATF_CHECK(isc_time_compare(&llim, &now) <= 0);
ATF_CHECK(isc_time_compare(&ulim, &now) >= 0);
assert_true(isc_time_compare(&llim, &now) <= 0);
assert_true(isc_time_compare(&ulim, &now) >= 0);
lasttime = now;
if (eventcnt < 3) {
ATF_CHECK_EQ(event->ev_type, ISC_TIMEREVENT_TICK);
assert_int_equal(event->ev_type, ISC_TIMEREVENT_TICK);
if (eventcnt == 2) {
isc_interval_set(&interval, seconds, nanoseconds);
result = isc_time_nowplusinterval(&expires, &interval);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
isc_interval_set(&interval, 0, 0);
result = isc_timer_reset(timer, isc_timertype_once,
&expires, &interval,
false);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
}
} else {
ATF_CHECK_EQ(event->ev_type, ISC_TIMEREVENT_LIFE);
assert_int_equal(event->ev_type, ISC_TIMEREVENT_LIFE);
isc_timer_detach(&timer);
isc_task_shutdown(task);
......@@ -357,19 +370,12 @@ test_reset(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
}
ATF_TC(reset);
ATF_TC_HEAD(reset, tc) {
atf_tc_set_md_var(tc, "descr", "timer reset");
}
ATF_TC_BODY(reset, tc) {
isc_result_t result;
static void
reset(void **state) {
isc_time_t expires;
isc_interval_t interval;
UNUSED(tc);
result = isc_test_begin(NULL, true, 2);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
UNUSED(state);
nevents = 3;
seconds = 0;
......@@ -379,8 +385,6 @@ ATF_TC_BODY(reset, tc) {
isc_time_settoepoch(&expires);
setup_test(isc_timertype_ticker, &expires, &interval, test_reset);
isc_test_end();
}
static int startflag;
......@@ -399,7 +403,9 @@ static void
start_event(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
printf("start_event\n");
if (verbose) {
print_message("# start_event\n");
}
LOCK(&mx);
while (! startflag) {
......@@ -419,7 +425,9 @@ tick_event(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
++eventcnt;
printf("tick_event %d\n", eventcnt);
if (verbose) {
print_message("# tick_event %d\n", eventcnt);
}
/*
* On the first tick, purge all remaining tick events
......@@ -430,7 +438,7 @@ tick_event(isc_task_t *task, isc_event_t *event) {
isc_interval_set(&interval, seconds, 0);
result = isc_timer_reset(tickertimer, isc_timertype_ticker,
&expires, &interval, true);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
isc_task_shutdown(task);
}
......@@ -442,7 +450,9 @@ static void
once_event(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
printf("once_event\n");
if (verbose) {
print_message("# once_event\n");
}
/*
* Allow task1 to start processing events.
......@@ -451,7 +461,7 @@ once_event(isc_task_t *task, isc_event_t *event) {
startflag = 1;
result = isc_condition_broadcast(&cv);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
UNLOCK(&mx);
isc_event_free(&event);
......@@ -465,7 +475,9 @@ shutdown_purge(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
UNUSED(event);
printf("shutdown_event\n");
if (verbose) {
print_message("# shutdown_event\n");
}
/*
* Signal shutdown processing complete.
......@@ -474,26 +486,21 @@ shutdown_purge(isc_task_t *task, isc_event_t *event) {
shutdownflag = 1;
result = isc_condition_signal(&cv);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
UNLOCK(&mx);
isc_event_free(&event);
}
ATF_TC(purge);
ATF_TC_HEAD(purge, tc) {
atf_tc_set_md_var(tc, "descr", "timer events purged");
}
ATF_TC_BODY(purge, tc) {
/* timer events purged */
static void
purge(void **state) {
isc_result_t result;
isc_event_t *event = NULL;
isc_time_t expires;
isc_interval_t interval;
UNUSED(tc);
result = isc_test_begin(NULL, true, 2);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
UNUSED(state);
startflag = 0;
shutdownflag = 0;
......@@ -502,25 +509,25 @@ ATF_TC_BODY(purge, tc) {
nanoseconds = 0;
result = isc_mutex_init(&mx);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_condition_init(&cv);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_create(taskmgr, 0, &task1);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_onshutdown(task1, shutdown_purge, NULL);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_create(taskmgr, 0, &task2);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
LOCK(&mx);
event = isc_event_allocate(mctx, (void *)1 , (isc_eventtype_t)1,
start_event, NULL, sizeof(*event));
ATF_REQUIRE(event != NULL);
assert_non_null(event);
isc_task_send(task1, &event);
isc_time_settoepoch(&expires);
......@@ -530,64 +537,74 @@ ATF_TC_BODY(purge, tc) {
result = isc_timer_create(timermgr, isc_timertype_ticker,
&expires, &interval, task1,
tick_event, NULL, &tickertimer);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
oncetimer = NULL;
isc_interval_set(&interval, (seconds * 2) + 1, 0);
result = isc_time_nowplusinterval(&expires, &interval);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
isc_interval_set(&interval, 0, 0);
result = isc_timer_create(timermgr, isc_timertype_once,
&expires, &interval, task2,
once_event, NULL, &oncetimer);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
/*
* Wait for shutdown processing to complete.
*/
while (! shutdownflag) {
result = isc_condition_wait(&cv, &mx);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
}
UNLOCK(&mx);
ATF_CHECK_EQ(eventcnt, 1);
assert_int_equal(eventcnt, 1);
isc_timer_detach(&tickertimer);
isc_timer_detach(&oncetimer);
isc_task_destroy(&task1);
isc_task_destroy(&task2);
DESTROYLOCK(&mx);
isc_test_end();
}
#else
ATF_TC(untested);
ATF_TC_HEAD(untested, tc) {
atf_tc_set_md_var(tc, "descr", "skipping nsec3 test");