From ab886422bf609567e2e059a7b0f800fc76524b86 Mon Sep 17 00:00:00 2001 From: AndreaRigoni Date: Sat, 18 Apr 2026 18:02:49 +0000 Subject: [PATCH] test: expand SmartPointer and thread affinity test coverage and update build preset --- .agents/rules/micromamba_build.md | 2 +- src/Core/testing/AffinityTest.cpp | 54 +++++++++++++++++++++++---- src/Core/testing/SmartPointerTest.cpp | 31 +++++++++++++-- 3 files changed, 76 insertions(+), 11 deletions(-) diff --git a/.agents/rules/micromamba_build.md b/.agents/rules/micromamba_build.md index 774aab3..b661c85 100644 --- a/.agents/rules/micromamba_build.md +++ b/.agents/rules/micromamba_build.md @@ -18,7 +18,7 @@ This rule provides instructions for building the uLib project using the micromam ```bash export MAMBA_EXE="/home/share/micromamba/bin/micromamba" export MAMBA_ROOT_PREFIX="/home/share/micromamba" - export PRESET="clang-make" + export PRESET="clang-debug" eval "$(${MAMBA_EXE} shell hook --shell bash)" micromamba activate uLib ``` diff --git a/src/Core/testing/AffinityTest.cpp b/src/Core/testing/AffinityTest.cpp index 3b56c36..08358fd 100644 --- a/src/Core/testing/AffinityTest.cpp +++ b/src/Core/testing/AffinityTest.cpp @@ -10,17 +10,52 @@ using namespace uLib; +std::vector GetAvailableCpus() { + std::vector available; +#ifdef __linux__ + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + if (sched_getaffinity(0, sizeof(cpu_set_t), &cpuset) == 0) { + for (int i = 0; i < CPU_SETSIZE; ++i) { + if (CPU_ISSET(i, &cpuset)) { + available.push_back(i); + } + } + } +#endif + return available; +} + +class TestThread : public Thread { +public: + void Run() override { + Thread::Sleep(200); + } +}; + void TestThreadAffinity() { std::cout << "Testing Thread Affinity..." << std::endl; #ifdef __linux__ - Thread t; + auto available = GetAvailableCpus(); + if (available.empty()) { + std::cout << " No CPUs available for affinity test, skipping." << std::endl; + return; + } + int target_cpu = available[0]; + std::cout << " Using CPU " << target_cpu << std::endl; + + TestThread t; t.Start(); - t.SetAffinity(0); // Bind to CPU 0 + t.SetAffinity(target_cpu); cpu_set_t cpuset; CPU_ZERO(&cpuset); - pthread_getaffinity_np(t.GetNativeHandle(), sizeof(cpu_set_t), &cpuset); - assert(CPU_ISSET(0, &cpuset)); + int s = pthread_getaffinity_np(t.GetNativeHandle(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + std::cerr << "Error: pthread_getaffinity_np failed with code " << s << std::endl; + assert(false); + } + assert(CPU_ISSET(target_cpu, &cpuset)); t.Join(); std::cout << " Passed (Thread bound to CPU 0)." << std::endl; @@ -32,9 +67,15 @@ void TestThreadAffinity() { void TestTeamAffinity() { std::cout << "Testing Team Affinity..." << std::endl; #ifdef __linux__ -#ifdef _OPENMP + auto available = GetAvailableCpus(); + if (available.size() < 2) { + std::cout << " Not enough CPUs available for Team affinity test, skipping." << std::endl; + return; + } + std::vector cpus = {available[0], available[1]}; + std::cout << " Using CPUs " << cpus[0] << ", " << cpus[1] << std::endl; + Team team(2); - std::vector cpus = {0, 1}; team.SetAffinity(cpus); // We check affinity inside a parallel region @@ -48,7 +89,6 @@ void TestTeamAffinity() { assert(CPU_ISSET(expected_cpu, &cpuset)); } std::cout << " Passed (Team threads bound correctly)." << std::endl; -#endif #else std::cout << " Affinity not supported on this OS, skipping." << std::endl; #endif diff --git a/src/Core/testing/SmartPointerTest.cpp b/src/Core/testing/SmartPointerTest.cpp index 5a2e129..6305351 100644 --- a/src/Core/testing/SmartPointerTest.cpp +++ b/src/Core/testing/SmartPointerTest.cpp @@ -27,6 +27,7 @@ #include +#include "Core/Object.h" #include "Core/SmartPointer.h" #include "testing-prototype.h" @@ -34,12 +35,12 @@ using namespace uLib; namespace Test { -struct ObjectMockInterface { +struct ObjectMockInterface : public Object { virtual void PrintValue()=0; virtual int& Value()=0; }; -class ObjectMock : ObjectMockInterface { +class ObjectMock : public ObjectMockInterface { int value; public: int& Value() { return value; } @@ -72,12 +73,15 @@ int main () { SmartPointer spt(new Test::ObjectMock); TEST1(test_smpt(spt)); } + { SmartPointer spt; TEST1(test_smpt(spt)); } + { - SmartPointer spt = new SmartPointer; + SmartPointer base_spt; + SmartPointer spt = &base_spt; TEST1(test_smpt(spt)); } @@ -88,7 +92,28 @@ int main () { TEST1(test_smpt(spt)); } + { + Test::ObjectMock obj; + SmartPointer spt1 = obj; + SmartPointer spt2 = obj; + SmartPointer spt = obj; + } + { + Test::ObjectMock *obj = new Test::ObjectMock; + SmartPointer spt(obj); + SmartPointer spt2(spt); + SmartPointer spt3(spt); + SmartPointer spt4(spt2); + spt->Value() = 123; + spt2->Value() = 456; + spt3->Value() = 789; + spt4->Value() = 101112; + TEST1(spt->Value() == 101112); + TEST1(spt2->Value() == 101112); + TEST1(spt3->Value() == 101112); + TEST1(spt4->Value() == 101112); + } END_TESTING; }