Files
dpm-core-ng/tests/harness.hpp
Christopher M. Punches 0291e61fd8 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.
2026-08-24 03:51:39 -04:00

88 lines
3.2 KiB
C++

/**
* @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;
}