/** * @file test_modules.cpp * @brief Load-time validation, module acquisition, and dispatch * * @copyright Copyright (c) 2026 SILO GROUP LLC * @author Chris Punches * * Part of the Dark Horse Linux Package Manager (DPM) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #include "harness.hpp" int main(void) { dpm_open_overrides overrides = {TEST_FIXTURE_CONF, TEST_FIXTURE_MODULES, nullptr, -1, TEST_FIXTURE_METADATA}; dpm_ctx* ctx = dpm_open(&overrides); CHECK(ctx != nullptr); if (!ctx) { std::fprintf(stderr, "cannot continue without a context\n"); return 1; } /* ---- every broken fixture is refused, and the reason says why ---- */ { CHECK(dpm_require(ctx, "missing_symbols") == nullptr); CHECK(error_contains(ctx, "missing required contract symbols")); CHECK(error_contains(ctx, "dpm_module_execute")); CHECK(error_contains(ctx, "dpm_module_aliases")); CHECK(dpm_require(ctx, "bad_version") == nullptr); CHECK(error_contains(ctx, "malformed version")); CHECK(dpm_require(ctx, "nonexistent") == nullptr); CHECK(error_contains(ctx, "not found")); } /* ---- a bad argument is refused without touching the module path ---- */ { CHECK(dpm_require(nullptr, "good") == nullptr); CHECK(dpm_require(ctx, nullptr) == nullptr); CHECK(dpm_require(ctx, "") == nullptr); } /* ---- the known-good fixture loads and reports what it declares ---- */ { dpm_module* good = dpm_require(ctx, "good"); CHECK(good != nullptr); if (!good) { dpm_close(ctx); return harness_report("modules"); } /* a module is opened at most once per context */ CHECK(dpm_require(ctx, "good") == good); dpm_module_info seen; CHECK(dpm_get_module_info(ctx, good, &seen) == 0); CHECK(std::strcmp(seen.name, "good") == 0); CHECK(std::strcmp(seen.version, "1.2.3") == 0); CHECK(seen.description != nullptr && *seen.description); CHECK(dpm_get_module_info(ctx, nullptr, &seen) != 0); CHECK(dpm_get_module_info(ctx, good, nullptr) != 0); CHECK(dpm_get_module_info(nullptr, good, &seen) != 0); /* dispatch returns the module's own value, so a round trip is observable with no compile-time knowledge of the module */ CHECK(dpm_execute(ctx, good, "ping", 0, nullptr) == 42); CHECK(dpm_execute(ctx, good, "anything_else", 0, nullptr) == 0); CHECK(dpm_execute(ctx, good, nullptr, 0, nullptr) == 0); CHECK(dpm_execute(nullptr, good, "ping", 0, nullptr) == 1); CHECK(dpm_execute(ctx, nullptr, "ping", 0, nullptr) == 1); } dpm_close(ctx); return harness_report("modules"); }