From fe327bf9ea78281e39e732e242f210015bc39d8f Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Sun, 25 Oct 2026 20:55:02 +0100 Subject: Add mutex unit test --- tests/t_mutex.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 tests/t_mutex.c diff --git a/tests/t_mutex.c b/tests/t_mutex.c new file mode 100644 index 0000000..3307d70 --- /dev/null +++ b/tests/t_mutex.c @@ -0,0 +1,107 @@ +/* This software was written by Dirk Engling + It is considered beerware. Prost. Skol. Cheers or whatever. + + $id$ */ + +/* System */ +#include +#include + +/* Opentracker */ +#include "ot_mutex.h" +#include "test.h" + +/* A worker asks for a class of task and blocks until one turns up, so a task + whose class matches no worker is never claimed and whoever is waiting for + its answer waits forever. These cases pin the matching. */ + +static void case_task_goes_to_its_own_class(void) { + ot_tasktype asked; + ot_taskid taskid; + + test_case("a worker is handed the task of the class it asked for"); + CHECK_INT(mutex_workqueue_pushtask(41, TASK_FULLSCRAPE_TPB_ASCII), 0); + asked = TASK_FULLSCRAPE; + taskid = mutex_workqueue_poptask(&asked); + CHECK(taskid != 0); + + test_case("and the full task type, not just its class"); + CHECK_INT(asked, TASK_FULLSCRAPE_TPB_ASCII); + mutex_workqueue_canceltask(41); +} + +static void case_flags_survive_the_queue(void) { + ot_tasktype asked; + + test_case("flags outside the class mask are carried through"); + CHECK_INT(mutex_workqueue_pushtask(42, TASK_FULLSCRAPE_TPB_URLENCODED | TASK_FLAG_GZIP), 0); + asked = TASK_FULLSCRAPE; + CHECK(mutex_workqueue_poptask(&asked) != 0); + CHECK_INT(asked, TASK_FULLSCRAPE_TPB_URLENCODED | TASK_FLAG_GZIP); + mutex_workqueue_canceltask(42); +} + +static void case_classes_do_not_cross(void) { + ot_tasktype asked; + ot_taskid taskid; + + test_case("a stats worker passes over a fullscrape task"); + CHECK_INT(mutex_workqueue_pushtask(43, TASK_FULLSCRAPE_TPB_BINARY), 0); + CHECK_INT(mutex_workqueue_pushtask(44, TASK_STATS_PEERS), 0); + + asked = TASK_STATS; + taskid = mutex_workqueue_poptask(&asked); + CHECK(taskid != 0); + CHECK_INT(asked, TASK_STATS_PEERS); + + test_case("and leaves it for the one that wants it"); + asked = TASK_FULLSCRAPE; + taskid = mutex_workqueue_poptask(&asked); + CHECK(taskid != 0); + CHECK_INT(asked, TASK_FULLSCRAPE_TPB_BINARY); + + mutex_workqueue_canceltask(43); + mutex_workqueue_canceltask(44); +} + +static void case_every_task_gets_its_own_id(void) { + ot_tasktype asked; + ot_taskid first, second; + + test_case("two queued tasks are handed out under different ids"); + CHECK_INT(mutex_workqueue_pushtask(45, TASK_FULLSCRAPE), 0); + CHECK_INT(mutex_workqueue_pushtask(46, TASK_FULLSCRAPE), 0); + + asked = TASK_FULLSCRAPE; + first = mutex_workqueue_poptask(&asked); + asked = TASK_FULLSCRAPE; + second = mutex_workqueue_poptask(&asked); + CHECK(first != 0); + CHECK(second != 0); + CHECK(first != second); + + mutex_workqueue_canceltask(45); + mutex_workqueue_canceltask(46); +} + +static void case_cancelled_task_is_not_handed_out(void) { + ot_tasktype asked; + + test_case("a cancelled task is gone before any worker sees it"); + CHECK_INT(mutex_workqueue_pushtask(47, TASK_FULLSCRAPE_TPB_ASCII_PLUS), 0); + CHECK_INT(mutex_workqueue_pushtask(48, TASK_FULLSCRAPE), 0); + mutex_workqueue_canceltask(47); + + asked = TASK_FULLSCRAPE; + CHECK(mutex_workqueue_poptask(&asked) != 0); + CHECK_INT(asked, TASK_FULLSCRAPE); + mutex_workqueue_canceltask(48); +} + +void test_mutex(void) { + case_task_goes_to_its_own_class(); + case_flags_survive_the_queue(); + case_classes_do_not_cross(); + case_every_task_gets_its_own_id(); + case_cancelled_task_is_not_handed_out(); +} -- cgit v1.3