/** * @file version.c * @brief Unit tests for the version macros and the linked-library accessor. * * These assert that the several places the version appears cannot drift: the * string, the numeric components, and what the shared library reports at * runtime all come from one project() call, and this is what proves it. */ #include #include #include #include #include #include "testutil.h" /** * @brief The version string and the numeric components must describe one version. * * They are separate substitutions in version.h.in, so a mangled template can * leave them disagreeing and nothing else would notice. */ akerr_ErrorContext *test_version_string_matches_components(void) { PREPARE_ERROR(e); char assembled[64]; ATTEMPT { snprintf(assembled, sizeof(assembled), "%d.%d.%d", AKGL_VERSION_MAJOR, AKGL_VERSION_MINOR, AKGL_VERSION_PATCH); TEST_ASSERT(e, strcmp(assembled, AKGL_VERSION) == 0, "AKGL_VERSION is \"%s\" but the components assemble to \"%s\"", AKGL_VERSION, assembled); } CLEANUP { } PROCESS(e) { } FINISH(e, true); SUCCEED_RETURN(e); } /** * @brief The linked library must report the version its headers were generated from. * * In this build tree they are the same tree, so this can only fail if the test * picked up an installed libakgl off LD_LIBRARY_PATH instead of the one just * built -- which is precisely the mispairing the accessor exists to catch. */ akerr_ErrorContext *test_version_linked_matches_compiled(void) { PREPARE_ERROR(e); ATTEMPT { TEST_ASSERT(e, akgl_version() != NULL, "akgl_version returned NULL"); TEST_ASSERT(e, strcmp(akgl_version(), AKGL_VERSION) == 0, "linked libakgl reports \"%s\" but the headers say \"%s\"", akgl_version(), AKGL_VERSION); } CLEANUP { } PROCESS(e) { } FINISH(e, true); SUCCEED_RETURN(e); } /** * @brief AKGL_VERSION_AT_LEAST must order versions correctly at the boundaries. * * Checked against the current version rather than fixed literals, so the test * does not have to be rewritten every time the version is bumped. */ akerr_ErrorContext *test_version_at_least_boundaries(void) { PREPARE_ERROR(e); ATTEMPT { TEST_ASSERT(e, AKGL_VERSION_AT_LEAST(AKGL_VERSION_MAJOR, AKGL_VERSION_MINOR, AKGL_VERSION_PATCH), "AKGL_VERSION_AT_LEAST rejected the current version"); TEST_ASSERT(e, !AKGL_VERSION_AT_LEAST(AKGL_VERSION_MAJOR, AKGL_VERSION_MINOR, AKGL_VERSION_PATCH + 1), "AKGL_VERSION_AT_LEAST accepted a later patch"); TEST_ASSERT(e, !AKGL_VERSION_AT_LEAST(AKGL_VERSION_MAJOR, AKGL_VERSION_MINOR + 1, 0), "AKGL_VERSION_AT_LEAST accepted a later minor"); TEST_ASSERT(e, !AKGL_VERSION_AT_LEAST(AKGL_VERSION_MAJOR + 1, 0, 0), "AKGL_VERSION_AT_LEAST accepted a later major"); TEST_ASSERT(e, AKGL_VERSION_AT_LEAST(AKGL_VERSION_MAJOR, AKGL_VERSION_MINOR, 0), "AKGL_VERSION_AT_LEAST rejected an earlier patch"); } CLEANUP { } PROCESS(e) { } FINISH(e, true); SUCCEED_RETURN(e); } int main(void) { PREPARE_ERROR(errctx); ATTEMPT { CATCH(errctx, akgl_error_init()); TEST_TRAP_UNHANDLED_ERRORS(); CATCH(errctx, test_version_string_matches_components()); CATCH(errctx, test_version_linked_matches_compiled()); CATCH(errctx, test_version_at_least_boundaries()); } CLEANUP { } PROCESS(errctx) { } FINISH_NORETURN(errctx); }