Initial commit: DPM core library, CLI, bundled info module, and tests
This commit is contained in:
6
tests/fixtures/conf/core.conf
vendored
Normal file
6
tests/fixtures/conf/core.conf
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
[logging]
|
||||
log_level = ERROR
|
||||
write_to_log = false
|
||||
|
||||
[modules]
|
||||
path = /nonexistent/from/config
|
||||
5
tests/fixtures/conf/testmod.conf
vendored
Normal file
5
tests/fixtures/conf/testmod.conf
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
[main]
|
||||
key = value
|
||||
|
||||
[section2]
|
||||
other = 42
|
||||
95
tests/fixtures/src/bad_magic.cpp
vendored
Normal file
95
tests/fixtures/src/bad_magic.cpp
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @file bad_magic.cpp
|
||||
* @brief Broken fixture: API table with a wrong magic constant
|
||||
*
|
||||
* Contract-complete, but its declared table opens with garbage instead
|
||||
* of the spec magic. Core must refuse it at validation step 5.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <cstdint>
|
||||
|
||||
namespace {
|
||||
|
||||
struct table_header {
|
||||
uint32_t magic;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
struct manifest_entry {
|
||||
const char* api_name;
|
||||
int table_version;
|
||||
const char* symbol;
|
||||
};
|
||||
|
||||
struct manifest {
|
||||
uint32_t count;
|
||||
const manifest_entry* entries;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
struct badmagic_api_v1_s {
|
||||
table_header hdr;
|
||||
int (*ping)(void);
|
||||
};
|
||||
|
||||
static int ping(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
extern const struct badmagic_api_v1_s badmagic_api_v1;
|
||||
const struct badmagic_api_v1_s badmagic_api_v1 = {
|
||||
{ 0xDEADBEEFu, sizeof(struct badmagic_api_v1_s) },
|
||||
ping,
|
||||
};
|
||||
}
|
||||
|
||||
extern "C" const char* dpm_module_version(void)
|
||||
{
|
||||
return "1.0.0";
|
||||
}
|
||||
|
||||
extern "C" const char* dpm_module_description(void)
|
||||
{
|
||||
return "Fixture with a bad table magic.";
|
||||
}
|
||||
|
||||
extern "C" const char* dpm_module_core_min(void)
|
||||
{
|
||||
return "0.1.0";
|
||||
}
|
||||
|
||||
extern "C" const void* dpm_module_manifest(void)
|
||||
{
|
||||
static const manifest_entry entries[] = {
|
||||
{ "badmagic", 1, "badmagic_api_v1" },
|
||||
};
|
||||
static const manifest m = { 1, entries };
|
||||
return &m;
|
||||
}
|
||||
|
||||
extern "C" int dpm_module_execute(void* ctx, const char* command,
|
||||
int argc, char** argv)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)command;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return 0;
|
||||
}
|
||||
69
tests/fixtures/src/bad_version.cpp
vendored
Normal file
69
tests/fixtures/src/bad_version.cpp
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @file bad_version.cpp
|
||||
* @brief Broken fixture: malformed module version string
|
||||
*
|
||||
* Contract-complete, but dpm_module_version() returns something that
|
||||
* is not X.Y.Z. Core must refuse it at validation step 3.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <cstdint>
|
||||
|
||||
namespace {
|
||||
|
||||
struct manifest_entry {
|
||||
const char* api_name;
|
||||
int table_version;
|
||||
const char* symbol;
|
||||
};
|
||||
|
||||
struct manifest {
|
||||
uint32_t count;
|
||||
const manifest_entry* entries;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" const char* dpm_module_version(void)
|
||||
{
|
||||
return "banana";
|
||||
}
|
||||
|
||||
extern "C" const char* dpm_module_description(void)
|
||||
{
|
||||
return "Fixture with a malformed version.";
|
||||
}
|
||||
|
||||
extern "C" const char* dpm_module_core_min(void)
|
||||
{
|
||||
return "0.1.0";
|
||||
}
|
||||
|
||||
extern "C" const void* dpm_module_manifest(void)
|
||||
{
|
||||
static const manifest m = { 0, nullptr };
|
||||
return &m;
|
||||
}
|
||||
|
||||
extern "C" int dpm_module_execute(void* ctx, const char* command,
|
||||
int argc, char** argv)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)command;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return 0;
|
||||
}
|
||||
70
tests/fixtures/src/core_too_new.cpp
vendored
Normal file
70
tests/fixtures/src/core_too_new.cpp
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @file core_too_new.cpp
|
||||
* @brief Broken fixture: demands a core newer than any that exists
|
||||
*
|
||||
* Contract-complete, but dpm_module_core_min() reports 99.0.0. Core
|
||||
* must refuse it at validation step 2 with a message naming the
|
||||
* remedy (update core).
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <cstdint>
|
||||
|
||||
namespace {
|
||||
|
||||
struct manifest_entry {
|
||||
const char* api_name;
|
||||
int table_version;
|
||||
const char* symbol;
|
||||
};
|
||||
|
||||
struct manifest {
|
||||
uint32_t count;
|
||||
const manifest_entry* entries;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" const char* dpm_module_version(void)
|
||||
{
|
||||
return "1.0.0";
|
||||
}
|
||||
|
||||
extern "C" const char* dpm_module_description(void)
|
||||
{
|
||||
return "Fixture demanding a future core.";
|
||||
}
|
||||
|
||||
extern "C" const char* dpm_module_core_min(void)
|
||||
{
|
||||
return "99.0.0";
|
||||
}
|
||||
|
||||
extern "C" const void* dpm_module_manifest(void)
|
||||
{
|
||||
static const manifest m = { 0, nullptr };
|
||||
return &m;
|
||||
}
|
||||
|
||||
extern "C" int dpm_module_execute(void* ctx, const char* command,
|
||||
int argc, char** argv)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)command;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return 0;
|
||||
}
|
||||
96
tests/fixtures/src/good.cpp
vendored
Normal file
96
tests/fixtures/src/good.cpp
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @file good.cpp
|
||||
* @brief Known-good stub module fixture
|
||||
*
|
||||
* A complete, valid DPM module written against the documented module
|
||||
* contract with its own declarations — no core headers — exactly as a
|
||||
* standalone module author would. Used to validate core's happy path.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <cstdint>
|
||||
|
||||
namespace {
|
||||
|
||||
struct table_header {
|
||||
uint32_t magic;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
struct manifest_entry {
|
||||
const char* api_name;
|
||||
int table_version;
|
||||
const char* symbol;
|
||||
};
|
||||
|
||||
struct manifest {
|
||||
uint32_t count;
|
||||
const manifest_entry* entries;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
struct good_api_v1_s {
|
||||
table_header hdr;
|
||||
int (*ping)(void);
|
||||
};
|
||||
|
||||
static int ping(void)
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
extern const struct good_api_v1_s good_api_v1;
|
||||
const struct good_api_v1_s good_api_v1 = {
|
||||
{ 0x314D5044u /* "DPM1" */, sizeof(struct good_api_v1_s) },
|
||||
ping,
|
||||
};
|
||||
}
|
||||
|
||||
extern "C" const char* dpm_module_version(void)
|
||||
{
|
||||
return "1.2.3";
|
||||
}
|
||||
|
||||
extern "C" const char* dpm_module_description(void)
|
||||
{
|
||||
return "Known-good stub module.";
|
||||
}
|
||||
|
||||
extern "C" const char* dpm_module_core_min(void)
|
||||
{
|
||||
return "0.1.0";
|
||||
}
|
||||
|
||||
extern "C" const void* dpm_module_manifest(void)
|
||||
{
|
||||
static const manifest_entry entries[] = {
|
||||
{ "good", 1, "good_api_v1" },
|
||||
};
|
||||
static const manifest m = { 1, entries };
|
||||
return &m;
|
||||
}
|
||||
|
||||
extern "C" int dpm_module_execute(void* ctx, const char* command,
|
||||
int argc, char** argv)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)command;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return 0;
|
||||
}
|
||||
72
tests/fixtures/src/lying_manifest.cpp
vendored
Normal file
72
tests/fixtures/src/lying_manifest.cpp
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @file lying_manifest.cpp
|
||||
* @brief Broken fixture: manifest declares an API it doesn't export
|
||||
*
|
||||
* Contract-complete, but its manifest names a table symbol that does
|
||||
* not exist in the .so. Core must refuse it at validation step 4.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <cstdint>
|
||||
|
||||
namespace {
|
||||
|
||||
struct manifest_entry {
|
||||
const char* api_name;
|
||||
int table_version;
|
||||
const char* symbol;
|
||||
};
|
||||
|
||||
struct manifest {
|
||||
uint32_t count;
|
||||
const manifest_entry* entries;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" const char* dpm_module_version(void)
|
||||
{
|
||||
return "1.0.0";
|
||||
}
|
||||
|
||||
extern "C" const char* dpm_module_description(void)
|
||||
{
|
||||
return "Fixture whose manifest lies.";
|
||||
}
|
||||
|
||||
extern "C" const char* dpm_module_core_min(void)
|
||||
{
|
||||
return "0.1.0";
|
||||
}
|
||||
|
||||
extern "C" const void* dpm_module_manifest(void)
|
||||
{
|
||||
static const manifest_entry entries[] = {
|
||||
{ "ghost", 1, "ghost_api_v1" },
|
||||
};
|
||||
static const manifest m = { 1, entries };
|
||||
return &m;
|
||||
}
|
||||
|
||||
extern "C" int dpm_module_execute(void* ctx, const char* command,
|
||||
int argc, char** argv)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)command;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return 0;
|
||||
}
|
||||
33
tests/fixtures/src/missing_symbols.cpp
vendored
Normal file
33
tests/fixtures/src/missing_symbols.cpp
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @file missing_symbols.cpp
|
||||
* @brief Broken fixture: exports only part of the module contract
|
||||
*
|
||||
* Missing dpm_module_execute, dpm_module_core_min, and
|
||||
* dpm_module_manifest. Core must refuse it at validation step 1 and
|
||||
* name the missing symbols.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
extern "C" const char* dpm_module_version(void)
|
||||
{
|
||||
return "1.0.0";
|
||||
}
|
||||
|
||||
extern "C" const char* dpm_module_description(void)
|
||||
{
|
||||
return "Fixture missing most of the contract.";
|
||||
}
|
||||
196
tests/test_core.cpp
Normal file
196
tests/test_core.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* @file test_core.cpp
|
||||
* @brief Core test binary: drives libdpm-core through its public C API
|
||||
*
|
||||
* Exercises context lifecycle, configuration, the full load-time
|
||||
* validation matrix against the fixture modules, versioned require,
|
||||
* typed API access, generic dispatch, and enumeration. Exits nonzero
|
||||
* on any failure.
|
||||
*
|
||||
* @copyright Copyright (c) 2026 SILO GROUP LLC
|
||||
* @author Chris Punches <chris.punches@silogroup.org>
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <dpm/core.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#ifndef TEST_FIXTURE_MODULES
|
||||
#error "TEST_FIXTURE_MODULES must be defined"
|
||||
#endif
|
||||
#ifndef TEST_FIXTURE_CONF
|
||||
#error "TEST_FIXTURE_CONF must be defined"
|
||||
#endif
|
||||
|
||||
static int g_failures = 0;
|
||||
static int g_checks = 0;
|
||||
|
||||
#define CHECK(cond) \
|
||||
do { \
|
||||
g_checks++; \
|
||||
if (!(cond)) { \
|
||||
g_failures++; \
|
||||
std::fprintf(stderr, "FAIL %s:%d: %s\n", __FILE__, __LINE__, \
|
||||
#cond); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static bool error_contains(dpm_ctx* ctx, const char* needle)
|
||||
{
|
||||
const char* err = dpm_last_error(ctx);
|
||||
return err != nullptr && std::strstr(err, needle) != nullptr;
|
||||
}
|
||||
|
||||
/* Mirror of the good fixture's table layout (consumer-side spec decl). */
|
||||
struct good_api_v1_s {
|
||||
dpm_api_table_header hdr;
|
||||
int (*ping)(void);
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* ---- dpm_open: invalid explicit override refuses ---- */
|
||||
{
|
||||
dpm_open_overrides bad = {"/does/not/exist/conf", nullptr, nullptr, -1};
|
||||
CHECK(dpm_open(&bad) == nullptr);
|
||||
|
||||
dpm_open_overrides bad_level = {nullptr, nullptr, nullptr, 99};
|
||||
CHECK(dpm_open(&bad_level) == nullptr);
|
||||
}
|
||||
|
||||
/* ---- context with fixture config and fixture module path ---- */
|
||||
dpm_open_overrides overrides = {TEST_FIXTURE_CONF, TEST_FIXTURE_MODULES,
|
||||
nullptr, -1};
|
||||
dpm_ctx* ctx = dpm_open(&overrides);
|
||||
CHECK(ctx != nullptr);
|
||||
if (!ctx) {
|
||||
std::fprintf(stderr, "cannot continue without a context\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ---- services ---- */
|
||||
{
|
||||
CHECK(std::strcmp(dpm_core_version(), DPM_CORE_VERSION_EXPECTED) == 0);
|
||||
|
||||
/* config: values resolve per-module, per-section */
|
||||
const char* v = dpm_config_get(ctx, "testmod", "main", "key");
|
||||
CHECK(v != nullptr && std::strcmp(v, "value") == 0);
|
||||
v = dpm_config_get(ctx, "testmod", "section2", "other");
|
||||
CHECK(v != nullptr && std::strcmp(v, "42") == 0);
|
||||
CHECK(dpm_config_get(ctx, "testmod", "main", "absent") == nullptr);
|
||||
CHECK(dpm_config_get(ctx, "nomodule", "main", "key") == nullptr);
|
||||
|
||||
/* module-path override wins over the config value */
|
||||
const char* path = dpm_module_path(ctx);
|
||||
CHECK(path != nullptr &&
|
||||
std::strncmp(path, TEST_FIXTURE_MODULES,
|
||||
std::strlen(TEST_FIXTURE_MODULES)) == 0);
|
||||
}
|
||||
|
||||
/* ---- validation matrix: every broken fixture refused, precisely ---- */
|
||||
{
|
||||
CHECK(dpm_require(ctx, "missing_symbols", nullptr) == nullptr);
|
||||
CHECK(error_contains(ctx, "missing required contract symbols"));
|
||||
CHECK(error_contains(ctx, "dpm_module_execute"));
|
||||
|
||||
CHECK(dpm_require(ctx, "core_too_new", nullptr) == nullptr);
|
||||
CHECK(error_contains(ctx, "update core"));
|
||||
|
||||
CHECK(dpm_require(ctx, "bad_version", nullptr) == nullptr);
|
||||
CHECK(error_contains(ctx, "malformed version"));
|
||||
|
||||
CHECK(dpm_require(ctx, "lying_manifest", nullptr) == nullptr);
|
||||
CHECK(error_contains(ctx, "does not resolve"));
|
||||
|
||||
CHECK(dpm_require(ctx, "bad_magic", nullptr) == nullptr);
|
||||
CHECK(error_contains(ctx, "magic"));
|
||||
|
||||
CHECK(dpm_require(ctx, "nonexistent", nullptr) == nullptr);
|
||||
CHECK(error_contains(ctx, "not found"));
|
||||
}
|
||||
|
||||
/* ---- known-good module: require, versions, api, execute ---- */
|
||||
{
|
||||
dpm_module* good = dpm_require(ctx, "good", nullptr);
|
||||
CHECK(good != nullptr);
|
||||
|
||||
/* loaded at most once per context */
|
||||
CHECK(dpm_require(ctx, "good", nullptr) == good);
|
||||
|
||||
/* minimum-version negotiation */
|
||||
CHECK(dpm_require(ctx, "good", "1.0.0") == good);
|
||||
CHECK(dpm_require(ctx, "good", "1.2.3") == good);
|
||||
CHECK(dpm_require(ctx, "good", "2.0.0") == nullptr);
|
||||
CHECK(error_contains(ctx, "below required minimum"));
|
||||
CHECK(dpm_require(ctx, "good", "not.a.version") == nullptr);
|
||||
CHECK(error_contains(ctx, "malformed minimum version"));
|
||||
|
||||
/* typed access */
|
||||
const void* table = dpm_get_api(ctx, good, "good", 1);
|
||||
CHECK(table != nullptr);
|
||||
if (table) {
|
||||
const auto* api = static_cast<const good_api_v1_s*>(table);
|
||||
CHECK(api->hdr.magic == DPM_API_TABLE_MAGIC);
|
||||
CHECK(api->hdr.size == sizeof(good_api_v1_s));
|
||||
CHECK(api->ping() == 42);
|
||||
}
|
||||
|
||||
/* absent api/version pairs are known from the manifest */
|
||||
CHECK(dpm_get_api(ctx, good, "good", 2) == nullptr);
|
||||
CHECK(dpm_get_api(ctx, good, "ghost", 1) == nullptr);
|
||||
|
||||
/* generic dispatch */
|
||||
CHECK(dpm_execute(ctx, good, nullptr, 0, nullptr) == 0);
|
||||
}
|
||||
|
||||
/* ---- enumeration: only the valid module surfaces ---- */
|
||||
{
|
||||
dpm_cursor* cur = dpm_list_modules(ctx);
|
||||
CHECK(cur != nullptr);
|
||||
if (cur) {
|
||||
int count = 0;
|
||||
dpm_module_info info;
|
||||
while (dpm_cursor_next(cur, &info) == 0) {
|
||||
count++;
|
||||
CHECK(std::strcmp(info.name, "good") == 0);
|
||||
CHECK(std::strcmp(info.version, "1.2.3") == 0);
|
||||
CHECK(std::strcmp(info.core_min, "0.1.0") == 0);
|
||||
CHECK(info.description != nullptr && *info.description);
|
||||
}
|
||||
CHECK(count == 1);
|
||||
dpm_cursor_free(cur);
|
||||
}
|
||||
|
||||
/* unreadable module path refuses with a reason */
|
||||
dpm_open_overrides bad_path = {TEST_FIXTURE_CONF, "/does/not/exist",
|
||||
nullptr, -1};
|
||||
dpm_ctx* ctx2 = dpm_open(&bad_path);
|
||||
CHECK(ctx2 != nullptr);
|
||||
if (ctx2) {
|
||||
CHECK(dpm_list_modules(ctx2) == nullptr);
|
||||
CHECK(error_contains(ctx2, "module path"));
|
||||
dpm_close(ctx2);
|
||||
}
|
||||
}
|
||||
|
||||
dpm_close(ctx);
|
||||
|
||||
std::printf("%d checks, %d failures\n", g_checks, g_failures);
|
||||
return g_failures == 0 ? 0 : 1;
|
||||
}
|
||||
Reference in New Issue
Block a user