Module records and aliases
Installation records what a module reports about itself. dpm_install_module opens a module once, writes its version and description to a .meta file in /var/lib/dpm/metadata/, and records the alternate names it declared in modules.aliases beside it. dpm_uninstall_module removes both, leaving the module file in place. dpm_list_modules reads those records and opens no module. A module with no record lists with a version of <uninstalled> and still loads when a caller names it. An unreadable or absent metadata directory costs the listing its detail and costs nothing else. Aliases give a module alternate names, declared through the new dpm_module_aliases contract symbol or added with dpm_add_module_alias. A name is recorded once: one already serving as an alias, or belonging to an installed module, is refused rather than repointed. dpm_require matches a name against the installed modules, then the alias table, then the module path. The metadata directory is a fifth override field and the -M flag, and [modules] metadata in core.conf. The test suite is four binaries covering context, modules, records, and aliases, each a ctest case of its own, alongside the CLI cases.
This commit is contained in:
87
tests/harness.hpp
Normal file
87
tests/harness.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @file harness.hpp
|
||||
* @brief What every test binary shares: counting, reporting, fixture paths
|
||||
*
|
||||
* Each test binary covers one area of the library and is registered as
|
||||
* its own ctest case, so a failure names the area it happened in. This
|
||||
* header carries what all of them need and nothing specific to any one.
|
||||
*
|
||||
* @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/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <dpm/core.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#ifndef TEST_FIXTURE_MODULES
|
||||
#error "TEST_FIXTURE_MODULES must be defined"
|
||||
#endif
|
||||
#ifndef TEST_FIXTURE_CONF
|
||||
#error "TEST_FIXTURE_CONF must be defined"
|
||||
#endif
|
||||
#ifndef TEST_FIXTURE_METADATA
|
||||
#error "TEST_FIXTURE_METADATA must be defined"
|
||||
#endif
|
||||
#ifndef TEST_SCRATCH_ROOT
|
||||
#error "TEST_SCRATCH_ROOT must be defined"
|
||||
#endif
|
||||
|
||||
/** Assertions run and assertions failed, reported by harness_report(). */
|
||||
static int g_checks = 0;
|
||||
static int g_failures = 0;
|
||||
|
||||
/**
|
||||
* @brief Records one assertion and reports it when it fails
|
||||
*
|
||||
* Every failure names the file and line, so a ctest case that fails
|
||||
* points at the assertion rather than at the binary.
|
||||
*/
|
||||
#define CHECK(cond) \
|
||||
do { \
|
||||
g_checks++; \
|
||||
if (!(cond)) { \
|
||||
g_failures++; \
|
||||
std::fprintf(stderr, "FAIL %s:%d: %s\n", __FILE__, __LINE__, \
|
||||
#cond); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief Reports whether the context's last error carries a substring
|
||||
*
|
||||
* @param ctx The context to read
|
||||
* @param needle The text the reason is expected to contain
|
||||
* @return true when a reason is recorded and contains needle
|
||||
*/
|
||||
static inline bool error_contains(dpm_ctx* ctx, const char* needle) {
|
||||
const char* err = dpm_get_last_error(ctx);
|
||||
return err != nullptr && std::strstr(err, needle) != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints the tally and yields the process exit status
|
||||
*
|
||||
* @return 0 when every assertion passed, 1 otherwise
|
||||
*/
|
||||
static inline int harness_report(const char* suite) {
|
||||
std::printf("%s: %d checks, %d failures\n", suite, g_checks, g_failures);
|
||||
return g_failures == 0 ? 0 : 1;
|
||||
}
|
||||
Reference in New Issue
Block a user