xo-alloc2: + utest harness for catch2
accept additional commandline arguments
This commit is contained in:
parent
9cf74ea149
commit
908c4908c5
13 changed files with 241 additions and 9 deletions
|
|
@ -4,12 +4,11 @@
|
|||
set(UTEST_EXE utest.alloc2)
|
||||
set(UTEST_SRCS
|
||||
alloc2_utest_main.cpp
|
||||
TestUtil.cpp
|
||||
objectmodel.test.cpp
|
||||
arena.test.cpp
|
||||
IAllocator_Any.test.cpp
|
||||
DArenaIterator.test.cpp
|
||||
# Collector.test.cpp
|
||||
# DX1CollectorIterator.test.cpp
|
||||
Generation.test.cpp
|
||||
Role.test.cpp
|
||||
VisitReason.test.cpp
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@
|
|||
* @author Roland Conybeare, Dec 2025
|
||||
**/
|
||||
|
||||
#include "Allocator.hpp"
|
||||
#include "AllocIterator.hpp"
|
||||
#include "Arena.hpp"
|
||||
//#include "arena/IAllocator_DArena.hpp"
|
||||
#include "TestUtil.hpp"
|
||||
#include <xo/alloc2/Allocator.hpp>
|
||||
#include <xo/alloc2/AllocIterator.hpp>
|
||||
#include <xo/alloc2/Arena.hpp>
|
||||
#include <xo/alloc2/ArenaIterator.hpp>
|
||||
#include "arena/IAllocIterator_DArenaIterator.hpp"
|
||||
#include "padding.hpp"
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
|
|
@ -39,6 +40,8 @@ namespace xo {
|
|||
namespace ut {
|
||||
TEST_CASE("IAllocIterator_Xfer_DArenaIterator", "[alloc2]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* verify IAllocIterator_Xfer is constructible + satisfies concept checks */
|
||||
IAllocIterator_Xfer<DArenaIterator, IAllocIterator_DArenaIterator> xfer;
|
||||
REQUIRE(IAllocIterator_Xfer<DArenaIterator, IAllocIterator_DArenaIterator>::_valid);
|
||||
|
|
@ -46,6 +49,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("IAllocIterator_Any", "[alloc2]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* verify IAllocIterator_Any is constructible + satisfies concept checks */
|
||||
IAllocIterator_Any any;
|
||||
REQUIRE(IAllocIterator_Any::_valid);
|
||||
|
|
@ -53,6 +58,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("obj_IAllocIterator", "[alloc2]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* verify variant obj constructible */
|
||||
obj<AAllocIterator> obj_any;
|
||||
REQUIRE(obj_any.iface());
|
||||
|
|
@ -61,6 +68,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("IAllocIterator-disabled-1", "[alloc2]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* verify iteration over empty arena */
|
||||
/* typed allocator a1o */
|
||||
ArenaConfig cfg { .name_ = "testarena",
|
||||
|
|
@ -97,6 +106,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("IAllocIterator-emptyarena", "[alloc2]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* verify iteration over empty arena */
|
||||
/* typed allocator a1o */
|
||||
ArenaConfig cfg { .name_ = "testarena",
|
||||
|
|
@ -153,7 +164,7 @@ namespace xo {
|
|||
|
||||
TEST_CASE("IAllocIterator-singlearena", "[alloc2]")
|
||||
{
|
||||
scope log(XO_DEBUG(false));
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
ArenaConfig cfg { .name_ = "testarena",
|
||||
.size_ = 64*1024,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
* @author Roland Conybeare, May 2026
|
||||
**/
|
||||
|
||||
#include "TestUtil.hpp"
|
||||
#include "Generation.hpp"
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
|
|
@ -14,6 +15,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("Generation-1", "[Generation]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
REQUIRE(Generation::nursery() == 0);
|
||||
REQUIRE(Generation::g0() == 0);
|
||||
REQUIRE(Generation::g1() == 1);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
* @author Roland Conybeare, May 2026
|
||||
**/
|
||||
|
||||
#include "TestUtil.hpp"
|
||||
#include <xo/alloc2/Allocator.hpp>
|
||||
#include <catch2/catch.hpp>
|
||||
#include <sys/wait.h>
|
||||
|
|
@ -16,6 +17,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("IAllocator_Any", "[alloc2][death]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
// null allocator
|
||||
obj<AAllocator> alloc_any;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
* @author Roland Conybeare, May 2026
|
||||
**/
|
||||
|
||||
#include "TestUtil.hpp"
|
||||
#include <xo/alloc2/ResourceVisitor.hpp>
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
|
|
@ -13,6 +14,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("ResourceVisitor-1", "[resourcevisitor]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
obj<AResourceVisitor> v;
|
||||
|
||||
REQUIRE(v.iface());
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
* @author Roland Conybeare, May 2026
|
||||
**/
|
||||
|
||||
#include "TestUtil.hpp"
|
||||
#include "role.hpp"
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
|
|
@ -13,6 +14,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("Role-1", "[Role]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* 1. there are two distinct valid roles, 'to' and 'from',
|
||||
* 2. valid roles fall in interval [begin, end)
|
||||
*/
|
||||
|
|
|
|||
24
utest/TestUtil.cpp
Normal file
24
utest/TestUtil.cpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/** @file TestUtil.cpp
|
||||
*
|
||||
* @author Roland Conybeare, May 2026
|
||||
**/
|
||||
|
||||
#include "TestUtil.hpp"
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
namespace xo {
|
||||
UtestConfig *
|
||||
UtestConfig::instance() {
|
||||
static UtestConfig s_instance;
|
||||
|
||||
return &s_instance;
|
||||
};
|
||||
|
||||
scope
|
||||
Utest::ut_scope() {
|
||||
return scope(XO_DEBUG(UtestConfig::instance()->debug_flag()),
|
||||
xtag("name", Catch::getResultCapture().getCurrentTestName()));
|
||||
}
|
||||
}
|
||||
|
||||
/* end TestUtil.cpp */
|
||||
44
utest/TestUtil.hpp
Normal file
44
utest/TestUtil.hpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/** @file TestUtil.hpp
|
||||
*
|
||||
* @author Roland Conybeare, May 2026
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
|
||||
namespace xo {
|
||||
|
||||
/** unit-test configuration here
|
||||
*
|
||||
* TODO: promote to its own library, along with UtestListener
|
||||
**/
|
||||
struct UtestConfig {
|
||||
bool debug_flag() const { return debug_flag_; }
|
||||
|
||||
/** announce each test using catch2's listener api **/
|
||||
bool announce_flag_ = false;
|
||||
/** enable debug output for all (!) tests **/
|
||||
bool debug_flag_ = false;
|
||||
|
||||
static UtestConfig * instance();
|
||||
};
|
||||
|
||||
/** RAII logging for catch unit tests
|
||||
*
|
||||
* Use:
|
||||
* TEST_CASE(name, tags, ..)
|
||||
* {
|
||||
* scope log = Utest::ut_scope();
|
||||
*
|
||||
* ...
|
||||
* log && log(xtag("foo", ...));
|
||||
* }
|
||||
**/
|
||||
struct Utest {
|
||||
static scope ut_scope();
|
||||
};
|
||||
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end TestUtil.hpp */
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
* @author Roland Conybeare, May 2026
|
||||
**/
|
||||
|
||||
#include "TestUtil.hpp"
|
||||
#include <xo/alloc2/VisitReason.hpp>
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
|
|
@ -13,6 +14,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("VisitReason-1", "[visitreason]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
REQUIRE(VisitReason::unspecified() == VisitReason::unspecified());
|
||||
|
||||
REQUIRE(VisitReason::unspecified() != VisitReason::forward());
|
||||
|
|
|
|||
|
|
@ -1,6 +1,100 @@
|
|||
/* file alloc2_utest_main.cpp */
|
||||
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch2/catch.hpp"
|
||||
#include "TestUtil.hpp"
|
||||
#include <xo/subsys/Subsystem.hpp>
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
#include <CLI/CLI.hpp>
|
||||
|
||||
#define CATCH_CONFIG_RUNNER
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
namespace xo {
|
||||
|
||||
struct UtestListener : Catch::TestEventListenerBase {
|
||||
using TestEventListenerBase::TestEventListenerBase;
|
||||
|
||||
// TestCasweInfo members: .name, .className, .description, .tags, lineInfo {.file, .line}
|
||||
virtual void testCaseStarting(const Catch::TestCaseInfo & info) override {
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
// preamble
|
||||
|
||||
if (UtestConfig::instance()->announce_flag_) {
|
||||
cerr << "Starting unit test: "
|
||||
<< "[" << info.name << "]"
|
||||
<< " at "
|
||||
<< "[" << info.lineInfo.file << ":" << info.lineInfo.line << "]"
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void testCaseEnded(const Catch::TestCaseStats & stats) override {
|
||||
// postamble
|
||||
}
|
||||
|
||||
// also sectionStarting / sectionEnded
|
||||
|
||||
};
|
||||
|
||||
CATCH_REGISTER_LISTENER(UtestListener);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
using xo::UtestConfig;
|
||||
using xo::scope;
|
||||
using xo::xtag;
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
//cerr << xtag("cli11", CLI11_VERSION) << endl; // version 2.5.0
|
||||
|
||||
CLI::App app{"utest.alloc2: xo-alloc2 unit tests"};
|
||||
app.set_help_flag(); // disable default help impl, see below
|
||||
{
|
||||
app.add_flag("--debug",
|
||||
UtestConfig::instance()->debug_flag_,
|
||||
"enable debug logging (for all tests)");
|
||||
app.add_flag("--announce",
|
||||
UtestConfig::instance()->announce_flag_,
|
||||
"announce each test via UtestListener");
|
||||
}
|
||||
bool help_flag = false;
|
||||
{
|
||||
app.add_flag("--help,-h,-?", help_flag, "print this help message and exit");
|
||||
}
|
||||
|
||||
app.allow_extras();
|
||||
CLI11_PARSE(app, argc, argv);
|
||||
|
||||
std::vector<const char *> argv2 = {argv[0]};
|
||||
|
||||
if (help_flag) {
|
||||
// actual help impl, falls through to Session below
|
||||
|
||||
cout << "utest.alloc2 options" << endl;
|
||||
cout << app.help() << endl;
|
||||
cout << "catch2 options" << endl;
|
||||
|
||||
argv2.push_back("--help");
|
||||
} else {
|
||||
// keep program name
|
||||
for (auto & x : app.remaining())
|
||||
argv2.push_back(x.c_str());
|
||||
|
||||
using xo::Subsystem;
|
||||
Subsystem::initialize_all();
|
||||
|
||||
}
|
||||
|
||||
scope log(XO_DEBUG(UtestConfig::instance()->debug_flag()), "start catch2 session");
|
||||
|
||||
// run catch2's test session / help
|
||||
return Catch::Session().run(argv2.size(), argv2.data());
|
||||
}
|
||||
|
||||
/* end alloc2_utest_main.cpp */
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
* @author Roland Conybeare, Dec 2025
|
||||
**/
|
||||
|
||||
#include "TestUtil.hpp"
|
||||
#include <xo/alloc2/Allocator.hpp>
|
||||
#include <xo/alloc2/Arena.hpp>
|
||||
#include <xo/arena/print.hpp>
|
||||
|
|
@ -33,6 +34,8 @@ namespace xo {
|
|||
namespace ut {
|
||||
TEST_CASE("IAllocator_Xfer_DArena", "[alloc2]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
IAllocator_Xfer<DArena, IAllocator_DArena> xfer;
|
||||
|
||||
REQUIRE(IAllocator_Xfer<DArena, IAllocator_DArena>::_valid);
|
||||
|
|
@ -40,6 +43,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("DArena-medium", "[alloc2][DArena]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
ArenaConfig cfg { .name_ = "testarena",
|
||||
.size_ = 10*1024*1024 };
|
||||
DArena arena = DArena::map(cfg);
|
||||
|
|
@ -83,6 +88,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("allocator-any-1", "[alloc2][AAllocator]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* empty allocator alloc1 */
|
||||
obj<AAllocator> alloc1;
|
||||
|
||||
|
|
@ -122,6 +129,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("allocator-expand-1", "[alloc2][AAllocator]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* typed allocator a1o */
|
||||
ArenaConfig cfg { .name_ = "testarena",
|
||||
.size_ = 1,
|
||||
|
|
@ -160,6 +169,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("allocator-alloc-1", "[alloc2][AAllocator]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* typed allocator a1o */
|
||||
ArenaConfig cfg { .name_ = "testarena",
|
||||
.size_ = 64*1024,
|
||||
|
|
@ -207,6 +218,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("allocator-alloc-2", "[alloc2][Allocator]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
using header_type = AllocHeader;
|
||||
|
||||
/* typed allocator a1o, with object header */
|
||||
|
|
@ -293,6 +306,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("allocator-alloc-3", "[alloc2][Allocator]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
using header_type = AllocHeader;
|
||||
|
||||
/* typed allocator a1o, with object header + guard bytes */
|
||||
|
|
@ -363,6 +378,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("allocator-fail-1", "[alloc2][AAllocator]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* typed allocator a1o */
|
||||
ArenaConfig cfg { .name_ = "testarena",
|
||||
.size_ = 64*1024,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
* @author Roland Conybeare, May 2026
|
||||
**/
|
||||
|
||||
#include "TestUtil.hpp"
|
||||
#include "dp.hpp"
|
||||
#include <xo/alloc2/Allocator.hpp>
|
||||
#include <xo/alloc2/Arena.hpp>
|
||||
|
|
@ -33,6 +34,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("dp-1", "[dp]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
//ArenaConfig cfg { .name_ = "testarena", .size_ = 1024 };
|
||||
//DArena arena = DArena::map(cfg);
|
||||
//auto mm = obj<AAllocator,DArena>(&arena);
|
||||
|
|
@ -55,6 +58,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("dp-2", "[dp]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
uint32_t counter = 0;
|
||||
Foo foo(&counter);
|
||||
|
||||
|
|
@ -77,6 +82,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("dp-DArena", "[dp][DArena]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
ArenaConfig cfg { .name_ = "testarena", .size_ = 1024 };
|
||||
DArena arena = DArena::map(cfg);
|
||||
//auto mm = obj<AAllocator,DArena>(&arena);
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@
|
|||
* Application code will deal with ubox<AComplex,DPolarCoords>
|
||||
**/
|
||||
|
||||
#include "TestUtil.hpp"
|
||||
#include <catch2/catch.hpp>
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
|
|
@ -576,6 +577,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("objectmodel-specific-1", "[objectmodel]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* arg=0, mag=1 -> 1+0i */
|
||||
DPolarCoords polar{0.0, 1.0};
|
||||
IComplex_Specific<DPolarCoords> polar_iface;
|
||||
|
|
@ -588,6 +591,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("objectmodel-specific-2", "[objectmodel]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* arg=0, mag=1 -> 1+0i */
|
||||
DRectCoords rect{1.0, 0.0};
|
||||
IComplex_Specific<DRectCoords> rect_iface;
|
||||
|
|
@ -600,6 +605,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("uniquebox-1", "[objectmodel]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
auto tmp = std::make_unique<DPolarCoords>(0.0, 1.0);
|
||||
OUniqueBox<AComplex, DPolarCoords> box{tmp.release()};
|
||||
|
||||
|
|
@ -611,6 +618,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("router-1", "[objectmodel]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
using Object = OUniqueBox<AComplex, DPolarCoords>;
|
||||
auto tmp = std::make_unique<DPolarCoords>(0.0, 1.0);
|
||||
|
||||
|
|
@ -624,6 +633,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("routing-type-1", "[objectmodel]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
using Object = OUniqueBox<AComplex, DPolarCoords>;
|
||||
auto tmp = std::make_unique<DPolarCoords>(0.0, 1.0);
|
||||
|
||||
|
|
@ -637,6 +648,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("ubox-1", "[objectmodel]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
auto tmp = std::make_unique<DPolarCoords>(0.0, 1.0);
|
||||
ubox<AComplex,DPolarCoords> box{tmp.release()};
|
||||
|
||||
|
|
@ -648,6 +661,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("ubox-2", "[objectmodel]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
auto tmp = std::make_unique<DRectCoords>(1.0, 0.0);
|
||||
ubox<AComplex,DRectCoords> box{tmp.release()};
|
||||
|
||||
|
|
@ -659,12 +674,16 @@ namespace xo {
|
|||
|
||||
TEST_CASE("ubox-any-1", "[objectmodel]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* default ctor */
|
||||
ubox<AComplex> any;
|
||||
}
|
||||
|
||||
TEST_CASE("ubox-any-2", "[objectmodel]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* equivalent to ubox<AComplex,DRectCoords>, but impl doesn't use std::unique_ptr */
|
||||
ubox<AComplex,DRectCoords> any{new DRectCoords{1.0, 0.0}};
|
||||
|
||||
|
|
@ -676,6 +695,8 @@ namespace xo {
|
|||
|
||||
TEST_CASE("ubox-any-3", "[objectmodel]")
|
||||
{
|
||||
auto log = Utest::ut_scope();
|
||||
|
||||
/* equivalent to ubox<AComplex,DRectCoords>, but impl doesn't use std::unique_ptr */
|
||||
ubox<AComplex,DRectCoords> z1{new DRectCoords{1.0, 0.0}};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue