diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7984a89..fd7f54d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -4,7 +4,7 @@ set(DMOD_AUTHOR_NAME "Patryk Kubiak") set(DMOD_STACK_SIZE 1024) set(DMOD_PRIORITY 0) -dmod_add_executable(${DMOD_MODULE_NAME} ${DMOD_MODULE_VERSION} +dmod_add_test(${DMOD_MODULE_NAME} ${DMOD_MODULE_VERSION} test_dm_sw_ring.c ) diff --git a/tests/test_dm_sw_ring.c b/tests/test_dm_sw_ring.c index 9458cd6..69d6aaa 100644 --- a/tests/test_dm_sw_ring.c +++ b/tests/test_dm_sw_ring.c @@ -1,257 +1,160 @@ #define DMOD_ENABLE_REGISTRATION ON -#include "dmod.h" +#include "dmod_test.h" #include "dm_sw_ring.h" #include -#include #include -static int g_failures = 0; +// ============================================================================ +// Shared test state +// ============================================================================ -#define EXPECT_TRUE(expr) \ - do \ - { \ - if (!(expr)) \ - { \ - DMOD_LOG_ERROR("Expectation failed: %s at %s:%d\n", #expr, __FILE__, __LINE__); \ - g_failures++; \ - } \ - } while (0) +static const dm_sw_ring_flags_t g_flags = + dm_sw_ring_flags_drop_old_data | dm_sw_ring_flags_mutex_sync; -#define EXPECT_EQ_U32(actual, expected) \ - do \ - { \ - uint32_t _actual = (uint32_t)(actual); \ - uint32_t _expected = (uint32_t)(expected); \ - if (_actual != _expected) \ - { \ - DMOD_LOG_ERROR("Expectation failed: %s == %s (actual=%u expected=%u) at %s:%d\n", \ - #actual, #expected, _actual, _expected, __FILE__, __LINE__); \ - g_failures++; \ - } \ - } while (0) -#define EXPECT_EQ_I32(actual, expected) \ - do \ - { \ - int32_t _actual = (int32_t)(actual); \ - int32_t _expected = (int32_t)(expected); \ - if (_actual != _expected) \ - { \ - DMOD_LOG_ERROR("Expectation failed: %s == %s (actual=%d expected=%d) at %s:%d\n", \ - #actual, #expected, _actual, _expected, __FILE__, __LINE__); \ - g_failures++; \ - } \ - } while (0) -#define EXPECT_EQ_BOOL(actual, expected) \ - do \ - { \ - bool _actual = ((actual) ? true : false); \ - bool _expected = ((expected) ? true : false); \ - if (_actual != _expected) \ - { \ - DMOD_LOG_ERROR("Expectation failed: %s == %s (actual=%d expected=%d) at %s:%d\n", \ - #actual, #expected, (int)_actual, (int)_expected, __FILE__, __LINE__); \ - g_failures++; \ - } \ - } while (0) -#define EXPECT_EQ_U8(actual, expected) \ - do \ - { \ - uint8_t _actual = (uint8_t)(actual); \ - uint8_t _expected = (uint8_t)(expected); \ - if (_actual != _expected) \ - { \ - DMOD_LOG_ERROR("Expectation failed: %s == %s (actual=%u expected=%u) at %s:%d\n", \ - #actual, #expected, _actual, _expected, __FILE__, __LINE__); \ - g_failures++; \ - } \ - } while (0) +static dm_sw_ring_t g_ring = NULL; +static uint8_t g_io_buf[8]; -typedef struct test_context -{ - dm_sw_ring_t ring; - dm_sw_ring_flags_t ring_flags; - uint8_t io_buffer[8]; -} test_context_t; - -typedef void (*test_setup_fn)(test_context_t* context); -typedef void (*test_step_fn)(test_context_t* context); -typedef void (*test_teardown_fn)(test_context_t* context); +// ============================================================================ +// Lifecycle hooks +// ============================================================================ -static void setup_ring_capacity_4(test_context_t* context) +void dmod_test_setup(void) { - context->ring = dm_sw_ring_create(4, context->ring_flags); - EXPECT_TRUE(context->ring != NULL); + g_ring = dm_sw_ring_create(4, g_flags); + memset(g_io_buf, 0, sizeof(g_io_buf)); } -static void teardown_ring(test_context_t* context) +void dmod_test_teardown(void) { - if (context->ring != NULL) + if (g_ring != NULL) { - dm_sw_ring_destroy(context->ring); - context->ring = NULL; + dm_sw_ring_destroy(g_ring); + g_ring = NULL; } } -static void run_test_step(const char* name, test_context_t* context, test_setup_fn setup, test_step_fn step, test_teardown_fn teardown) -{ - int failures_before = g_failures; - DMOD_LOG_STEP_BEGIN("%s\n", name); +// ============================================================================ +// Test steps +// ============================================================================ - if (setup != NULL) - { - setup(context); - } - if (step != NULL && context->ring != NULL) - { - step(context); - } - if (teardown != NULL) - { - teardown(context); - } +DMOD_TEST_STEP(dm_sw_ring_create) +{ + /* The ring created by setup is not needed for this test */ + dm_sw_ring_destroy(g_ring); + g_ring = NULL; - DMOD_LOG_STEP((g_failures > failures_before) ? 1 : 0, "%s\n", name); -} + dm_sw_ring_t ring = dm_sw_ring_create(4, g_flags); + DMOD_TEST_EXPECT_NOT_NULL(ring); + DMOD_TEST_EXPECT_NULL(dm_sw_ring_create(0, g_flags)); -static void test_create_step(test_context_t* context) -{ - dm_sw_ring_t ring = dm_sw_ring_create(4, context->ring_flags); - EXPECT_TRUE(ring != NULL); - EXPECT_TRUE(dm_sw_ring_create(0, context->ring_flags) == NULL); if (ring != NULL) { dm_sw_ring_destroy(ring); } } -static void test_destroy_step(test_context_t* context) +DMOD_TEST_STEP(dm_sw_ring_destroy) { - EXPECT_TRUE(context->ring != NULL); - dm_sw_ring_destroy(context->ring); - context->ring = NULL; + DMOD_TEST_EXPECT_NOT_NULL(g_ring); + dm_sw_ring_destroy(g_ring); + g_ring = NULL; /* prevent double-free in teardown */ } -static void test_write_step(test_context_t* context) +DMOD_TEST_STEP(dm_sw_ring_write) { const uint8_t data[] = {10, 11, 12, 13, 14}; - EXPECT_EQ_U32(dm_sw_ring_write(context->ring, NULL, 1), 0); - EXPECT_EQ_U32(dm_sw_ring_size(context->ring), 0); - EXPECT_EQ_U32(dm_sw_ring_write(context->ring, data, 5), 5); - EXPECT_EQ_U32(dm_sw_ring_size(context->ring), 4); + + DMOD_TEST_EXPECT_EQ(dm_sw_ring_write(g_ring, NULL, 1), 0u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_size(g_ring), 0u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_write(g_ring, data, 5), 5u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_size(g_ring), 4u); } -static void test_read_step(test_context_t* context) +DMOD_TEST_STEP(dm_sw_ring_read) { const uint8_t data[] = {1, 2, 3}; - memset(context->io_buffer, 0, sizeof(context->io_buffer)); - EXPECT_EQ_U32(dm_sw_ring_write(context->ring, data, 3), 3); - EXPECT_EQ_U32(dm_sw_ring_read(context->ring, NULL, 1), 0); - EXPECT_EQ_U32(dm_sw_ring_size(context->ring), 3); - EXPECT_EQ_U32(dm_sw_ring_read(context->ring, context->io_buffer, 2), 2); - EXPECT_EQ_U8(context->io_buffer[0], 1); - EXPECT_EQ_U8(context->io_buffer[1], 2); + + DMOD_TEST_EXPECT_EQ(dm_sw_ring_write(g_ring, data, 3), 3u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_read(g_ring, NULL, 1), 0u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_size(g_ring), 3u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_read(g_ring, g_io_buf, 2), 2u); + DMOD_TEST_EXPECT_EQ(g_io_buf[0], 1u); + DMOD_TEST_EXPECT_EQ(g_io_buf[1], 2u); } -static void test_capacity_step(test_context_t* context) +DMOD_TEST_STEP(dm_sw_ring_capacity) { - EXPECT_EQ_U32(dm_sw_ring_capacity(context->ring), 4); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_capacity(g_ring), 4u); } -static void test_size_step(test_context_t* context) +DMOD_TEST_STEP(dm_sw_ring_size) { const uint8_t data[] = {1, 2, 3}; - EXPECT_EQ_U32(dm_sw_ring_size(context->ring), 0); - EXPECT_EQ_U32(dm_sw_ring_write(context->ring, data, 3), 3); - EXPECT_EQ_U32(dm_sw_ring_size(context->ring), 3); - EXPECT_EQ_U32(dm_sw_ring_discard(context->ring, 1), 1); - EXPECT_EQ_U32(dm_sw_ring_size(context->ring), 2); + + DMOD_TEST_EXPECT_EQ(dm_sw_ring_size(g_ring), 0u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_write(g_ring, data, 3), 3u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_size(g_ring), 3u); + DMOD_TEST_EXPECT_EQ((uint32_t)dm_sw_ring_discard(g_ring, 1), 1u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_size(g_ring), 2u); } -static void test_available_space_step(test_context_t* context) +DMOD_TEST_STEP(dm_sw_ring_available_space) { const uint8_t data[] = {1, 2, 3}; - EXPECT_EQ_U32(dm_sw_ring_available_space(context->ring), 4); - EXPECT_EQ_U32(dm_sw_ring_write(context->ring, data, 3), 3); - EXPECT_EQ_U32(dm_sw_ring_available_space(context->ring), 1); + + DMOD_TEST_EXPECT_EQ(dm_sw_ring_available_space(g_ring), 4u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_write(g_ring, data, 3), 3u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_available_space(g_ring), 1u); } -static void test_peek_step(test_context_t* context) +DMOD_TEST_STEP(dm_sw_ring_peek) { const uint8_t data[] = {1, 2, 3, 4}; - memset(context->io_buffer, 0, sizeof(context->io_buffer)); - EXPECT_EQ_U32(dm_sw_ring_write(context->ring, data, 4), 4); - EXPECT_EQ_I32(dm_sw_ring_peek(context->ring, NULL, 1), -1); - EXPECT_EQ_I32(dm_sw_ring_peek(context->ring, context->io_buffer, 4), 4); - EXPECT_EQ_U8(context->io_buffer[0], 1); - EXPECT_EQ_U8(context->io_buffer[3], 4); - EXPECT_EQ_U32(dm_sw_ring_size(context->ring), 4); + + DMOD_TEST_EXPECT_EQ(dm_sw_ring_write(g_ring, data, 4), 4u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_peek(g_ring, NULL, 1), -1); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_peek(g_ring, g_io_buf, 4), 4); + DMOD_TEST_EXPECT_EQ(g_io_buf[0], 1u); + DMOD_TEST_EXPECT_EQ(g_io_buf[3], 4u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_size(g_ring), 4u); } -static void test_discard_step(test_context_t* context) +DMOD_TEST_STEP(dm_sw_ring_discard) { const uint8_t data[] = {4, 5, 6}; - EXPECT_EQ_U32(dm_sw_ring_write(context->ring, data, 3), 3); - EXPECT_EQ_I32(dm_sw_ring_discard(context->ring, 0), 0); - EXPECT_EQ_I32(dm_sw_ring_discard(context->ring, 1), 1); - EXPECT_EQ_U32(dm_sw_ring_size(context->ring), 2); + + DMOD_TEST_EXPECT_EQ(dm_sw_ring_write(g_ring, data, 3), 3u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_discard(g_ring, 0), 0); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_discard(g_ring, 1), 1); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_size(g_ring), 2u); } -static void test_clear_step(test_context_t* context) +DMOD_TEST_STEP(dm_sw_ring_clear) { const uint8_t data[] = {1, 2, 3, 4}; - EXPECT_EQ_U32(dm_sw_ring_write(context->ring, data, 4), 4); - EXPECT_EQ_I32(dm_sw_ring_clear(context->ring), 0); - EXPECT_EQ_U32(dm_sw_ring_size(context->ring), 0); + + DMOD_TEST_EXPECT_EQ(dm_sw_ring_write(g_ring, data, 4), 4u); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_clear(g_ring), 0); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_size(g_ring), 0u); } -static void test_is_full_step(test_context_t* context) +DMOD_TEST_STEP(dm_sw_ring_is_full) { const uint8_t data[] = {1, 2, 3, 4}; - EXPECT_EQ_BOOL(dm_sw_ring_is_full(context->ring), false); - EXPECT_EQ_U32(dm_sw_ring_write(context->ring, data, 4), 4); - EXPECT_EQ_BOOL(dm_sw_ring_is_full(context->ring), true); -} -static void test_is_empty_step(test_context_t* context) -{ - const uint8_t data[] = {1}; - EXPECT_EQ_BOOL(dm_sw_ring_is_empty(context->ring), true); - EXPECT_EQ_U32(dm_sw_ring_write(context->ring, data, 1), 1); - EXPECT_EQ_BOOL(dm_sw_ring_is_empty(context->ring), false); - EXPECT_EQ_U32(dm_sw_ring_read(context->ring, context->io_buffer, 1), 1); - EXPECT_EQ_BOOL(dm_sw_ring_is_empty(context->ring), true); + DMOD_TEST_EXPECT_FALSE(dm_sw_ring_is_full(g_ring)); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_write(g_ring, data, 4), 4u); + DMOD_TEST_EXPECT_TRUE(dm_sw_ring_is_full(g_ring)); } -int main(int argc, char** argv) +DMOD_TEST_STEP(dm_sw_ring_is_empty) { - (void)argc; - (void)argv; - - test_context_t context = { - .ring = NULL, - .ring_flags = dm_sw_ring_flags_drop_old_data | dm_sw_ring_flags_mutex_sync, - .io_buffer = {0} - }; - - run_test_step("dm_sw_ring_create", &context, NULL, test_create_step, NULL); - run_test_step("dm_sw_ring_destroy", &context, setup_ring_capacity_4, test_destroy_step, teardown_ring); - run_test_step("dm_sw_ring_write", &context, setup_ring_capacity_4, test_write_step, teardown_ring); - run_test_step("dm_sw_ring_read", &context, setup_ring_capacity_4, test_read_step, teardown_ring); - run_test_step("dm_sw_ring_capacity", &context, setup_ring_capacity_4, test_capacity_step, teardown_ring); - run_test_step("dm_sw_ring_size", &context, setup_ring_capacity_4, test_size_step, teardown_ring); - run_test_step("dm_sw_ring_available_space", &context, setup_ring_capacity_4, test_available_space_step, teardown_ring); - run_test_step("dm_sw_ring_peek", &context, setup_ring_capacity_4, test_peek_step, teardown_ring); - run_test_step("dm_sw_ring_discard", &context, setup_ring_capacity_4, test_discard_step, teardown_ring); - run_test_step("dm_sw_ring_clear", &context, setup_ring_capacity_4, test_clear_step, teardown_ring); - run_test_step("dm_sw_ring_is_full", &context, setup_ring_capacity_4, test_is_full_step, teardown_ring); - run_test_step("dm_sw_ring_is_empty", &context, setup_ring_capacity_4, test_is_empty_step, teardown_ring); - - if (g_failures == 0) - { - DMOD_LOG_INFO("All dm_sw_ring API checks passed\n"); - return 0; - } + const uint8_t data[] = {1}; - DMOD_LOG_ERROR("dm_sw_ring API checks failed: %d\n", g_failures); - return 1; + DMOD_TEST_EXPECT_TRUE(dm_sw_ring_is_empty(g_ring)); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_write(g_ring, data, 1), 1u); + DMOD_TEST_EXPECT_FALSE(dm_sw_ring_is_empty(g_ring)); + DMOD_TEST_EXPECT_EQ(dm_sw_ring_read(g_ring, g_io_buf, 1), 1u); + DMOD_TEST_EXPECT_TRUE(dm_sw_ring_is_empty(g_ring)); } +