/* * Copyright (C) 2024, 2025 Nicolas Dato * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "../src/itc.h" #include "test.h" #include #include #include static void test_itc_alloc_free(void) { itc *ctx; TEST((ctx = itc_alloc(0)) == NULL); TEST((ctx = itc_alloc(1)) != NULL); itc_free(&ctx, NULL); TEST(ctx == NULL); } static void test_itc_inject_retrieve(void) { unsigned int i; unsigned int *e[3] = {NULL}; int *r; itc *ctx; for (i = 0; i < sizeof(e)/sizeof(e[0]); i++) { e[i] = malloc(sizeof(*e[i])); *e[i] = i; } ctx = itc_alloc(3); TEST(itc_inject(ctx, 0, e[0]) == 0); TEST(itc_inject(ctx, 0, e[1]) == 0); TEST(itc_inject(ctx, 0, e[2]) == 0); TEST((r = itc_retrieve(ctx, 0)) != NULL); TEST(*r == 0); TEST((r = itc_retrieve(ctx, 0)) != NULL); TEST(*r == 1); TEST(itc_inject(ctx, 0, e[0]) == 0); TEST(itc_inject(ctx, 0, e[1]) == 0); TEST((r = itc_retrieve(ctx, 0)) != NULL); TEST(*r == 2); TEST((r = itc_retrieve(ctx, 0)) != NULL); TEST(*r == 0); TEST((r = itc_retrieve(ctx, 0)) != NULL); TEST(*r == 1); TEST(itc_retrieve(ctx, 0) == NULL); TEST(itc_inject(ctx, 0, e[0]) == 0); itc_free(&ctx, free); e[0] = malloc(sizeof(*e[0])); *e[0] = 0; ctx = itc_alloc(2); TEST(itc_inject(ctx, 0, e[0]) == 0); TEST(itc_inject(ctx, 0, e[1]) == 0); TEST(itc_inject(ctx, 0, e[2])); TEST((r = itc_retrieve(ctx, 0)) != NULL); TEST(*r == 0); TEST((r = itc_retrieve(ctx, 0)) != NULL); TEST(*r == 1); TEST(itc_retrieve(ctx, 0) == NULL); itc_free(&ctx, free); for (i = 0; i < sizeof(e)/sizeof(e[0]); i++) { free(e[i]); } } static void test_itc_queued_slots(void) { itc *ctx; ctx = itc_alloc(3); TEST(itc_get_queued(NULL) < 0); TEST(itc_get_queued(ctx) == 0); TEST(itc_get_slots(NULL) < 0); TEST(itc_get_slots(ctx) == 3); itc_inject(ctx, 0, NULL); TEST(itc_get_queued(ctx) == 0); TEST(itc_get_slots(ctx) == 3); itc_inject(ctx, 0, ctx); TEST(itc_get_queued(ctx) == 1); TEST(itc_get_slots(ctx) == 3); itc_inject(ctx, 0, ctx); TEST(itc_get_queued(ctx) == 2); TEST(itc_get_slots(ctx) == 3); itc_retrieve(ctx, 0); TEST(itc_get_queued(ctx) == 1); TEST(itc_get_slots(ctx) == 3); itc_retrieve(ctx, 0); TEST(itc_get_queued(ctx) == 0); TEST(itc_get_slots(ctx) == 3); itc_free(&ctx, NULL); } static void *test_itc_wait_empty_th(void *_ctx) { itc *ctx = _ctx; int *e; sleep(2); TEST(ctx != NULL); TEST((e = itc_retrieve(ctx, 0)) != NULL); TEST(*e == 0); free(e); TEST((e = itc_retrieve(ctx, 0)) != NULL); TEST(*e == 1); free(e); TEST((e = itc_retrieve(ctx, 0)) != NULL); TEST(*e == 2); free(e); TEST(itc_retrieve(ctx, 0) == NULL); return NULL; } static void test_itc_wait_empty(void) { itc *ctx; pthread_t th; int *e[3]; int i; for (i = 0; i < 3; i++) { e[i] = malloc(sizeof(int)); *e[i] = i; } ctx = itc_alloc(3); itc_inject(ctx, 0, e[0]); itc_inject(ctx, 0, e[1]); itc_inject(ctx, 0, e[2]); pthread_create(&th, NULL, test_itc_wait_empty_th, ctx); pthread_detach(th); itc_wait_empty(ctx); sleep(2); TEST(itc_get_queued(ctx) == 0); TEST(itc_retrieve(ctx, 0) == NULL); itc_free(&ctx, NULL); } static void test_itc_discard_all(void) { itc *ctx; unsigned int *e[4]; unsigned int i; for (i = 0; i < sizeof(e)/sizeof(e[0]); i++) { e[i] = malloc(sizeof(*e[i])); *e[i] = i; } ctx = itc_alloc(5); itc_discard_all(ctx, free); TEST(itc_get_queued(ctx) == 0); itc_inject(ctx, 0, e[0]); itc_inject(ctx, 0, e[1]); itc_inject(ctx, 0, e[2]); itc_inject(ctx, 0, e[3]); itc_discard_all(ctx, free); TEST(itc_get_queued(ctx) == 0); itc_free(&ctx, NULL); } int main(int argc, char **argv) { (void)argc; (void)argv; test_itc_alloc_free(); test_itc_inject_retrieve(); test_itc_queued_slots(); test_itc_wait_empty(); test_itc_discard_all(); return 0; }