yams/tests/common/plugins_catch2.h
trvon 69f6f63f55
fix(security): harden fold-flagged guards
Signed-off-by: trvon <me@trevon.dev>
2026-05-17 23:50:32 -04:00

70 lines
3.1 KiB
C++

// Catch2 replacement for tests/common/plugins.h.
// Provides a dlopen/dlclose RAII helper and a plugin-missing skip macro that
// uses Catch2's SKIP(...) instead of GTEST_SKIP().
#pragma once
#include <cstddef>
#include <cstdint>
#include <string>
#include <yams/compat/dlfcn.h>
#include <catch2/catch_test_macros.hpp>
#include <yams/plugins/abi.h>
// RAII handle for dlopen/dlclose in tests
struct TestPluginHandle {
void* handle{nullptr};
TestPluginHandle() = default;
TestPluginHandle(const TestPluginHandle&) = delete;
TestPluginHandle& operator=(const TestPluginHandle&) = delete;
TestPluginHandle(TestPluginHandle&& o) noexcept : handle(o.handle) { o.handle = nullptr; }
TestPluginHandle& operator=(TestPluginHandle&& o) noexcept {
if (this != &o) {
if (handle)
dlclose(handle);
handle = o.handle;
o.handle = nullptr;
}
return *this;
}
~TestPluginHandle() {
if (handle)
dlclose(handle);
}
bool open(const char* so_path, int flags = RTLD_LAZY | RTLD_LOCAL) {
handle = dlopen(so_path, flags);
return handle != nullptr;
}
template <class T> T sym(const char* name) const {
return reinterpret_cast<T>(dlsym(handle, name));
}
};
#ifndef YAMS_TRY_AUTO_DOWNLOAD
#define YAMS_TRY_AUTO_DOWNLOAD(lang) (false)
#endif
// Standardized skip for env/resource dependent plugins (grammars, models, etc.)
// rc: plugin call return code, out_ptr: optional result struct with `error` field, reason: context
#define PLUGIN_MISSING_SKIP(rc, out_ptr, reason) \
do { \
auto* _yams_out_ptr = (out_ptr); \
const bool _yams_missing = (rc) == YAMS_PLUGIN_ERR_NOT_FOUND; \
bool _yams_has_error = false; \
if (_yams_out_ptr != nullptr) { \
_yams_has_error = _yams_out_ptr->error != nullptr; \
} \
if (_yams_missing || _yams_has_error) { \
std::string _yams_skip_msg = (reason); \
if (_yams_out_ptr != nullptr && _yams_out_ptr->error != nullptr) { \
_yams_skip_msg += " \xE2\x80\x94 "; \
_yams_skip_msg += _yams_out_ptr->error; \
} \
SKIP("Plugin missing dependency: " + _yams_skip_msg); \
} \
} while (0)