diff --git a/GeoModelCore/GeoModelKernel/CMakeLists.txt b/GeoModelCore/GeoModelKernel/CMakeLists.txt index 3cc3c71147a038106852cd000b778111ffb6a5fa..561d34ef8012fc0a92345e84fa94d62daebcecb4 100644 --- a/GeoModelCore/GeoModelKernel/CMakeLists.txt +++ b/GeoModelCore/GeoModelKernel/CMakeLists.txt @@ -48,7 +48,7 @@ install( FILES ${HEADERS} COMPONENT Development ) - file(GLOB_RECURSE files "tests/*.cxx") +file(GLOB_RECURSE files "tests/*.cxx") foreach(_exeFile ${files}) get_filename_component(_theExec ${_exeFile} NAME_WE) get_filename_component(_theLoc ${_exeFile} DIRECTORY) @@ -58,8 +58,11 @@ foreach(_exeFile ${files}) endif() add_executable(${_theExec} ${_exeFile}) - target_link_libraries( ${_theExec} GeoModelKernel) + target_link_libraries( ${_theExec} GeoModelKernel GTest::GTest GTest::Main) add_test(NAME ${_theExec} COMMAND ${_theExec}) endforeach() +include(GoogleTest) +gtest_discover_tests(testRCBase) + diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/RCBase.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/RCBase.h index 6c2e8b4b6b886eff3aeeff8b719d34b011575920..e0d4bff5c9d064995945a462fa4894713da4fba1 100644 --- a/GeoModelCore/GeoModelKernel/GeoModelKernel/RCBase.h +++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/RCBase.h @@ -7,8 +7,8 @@ * * @brief This is a base class for objects whose memory is managed * through reference counting. Reference-counted objects - * can only be created using - * operator new, the cannot be created on the stack. + * should only be created using + * operator new, they should not be created on the stack. * * The methods ref() and unref() can be called to increase * and decrease the reference count of an object. When diff --git a/GeoModelCore/GeoModelKernel/tests/testRCBase.cxx b/GeoModelCore/GeoModelKernel/tests/testRCBase.cxx new file mode 100644 index 0000000000000000000000000000000000000000..081b84c30e89947151b75205771e22cdabf534a2 --- /dev/null +++ b/GeoModelCore/GeoModelKernel/tests/testRCBase.cxx @@ -0,0 +1,57 @@ +/* + Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "GeoModelKernel/RCBase.h" +#include <gtest/gtest.h> +#include <limits> + +class Stub:public RCBase{ + public: + Stub() = default; + virtual ~Stub() = default; +}; + +TEST(GeoModelKernel, RCBaseStub_CanBeConstructedOnStack) { + EXPECT_NO_THROW([[maybe_unused]] Stub stub); + //Stub stub1; (unused here if the following are commented out) + //none of the following compile (correctly so) + //Stub stub2(stub1); + //Stub stub3 = stub1; + //Stub stub4(std::move(stub1); + //Stub stub5 = std::move(stub3); +} + +TEST(GeoModelKernel, RCBase_CanBeConstructedOnHeap) { + RCBase * p{}; + EXPECT_NO_THROW(p = new RCBase); + EXPECT_NE(p, nullptr); + //deliberate leak here, RCBase d'tor is protected, so cannot delete +} + +TEST(GeoModelKernel, RCBaseStub_CanBeConstructedOnHeap) { + Stub * p{}; + EXPECT_NO_THROW(p = new Stub); + EXPECT_NE(p, nullptr); + //can delete the derived class directly + EXPECT_NO_THROW(delete p); +} + +TEST(GeoModelKernel, RCBaseStub_ReferenceCountOk){ + //do on heap, as is supposed to be + Stub * pStub = new Stub; + EXPECT_EQ(pStub->refCount(), 0); + EXPECT_NO_THROW(pStub->ref()); + EXPECT_EQ(pStub->refCount(), 1); + EXPECT_NO_THROW(pStub->unref()); + //now, where is the object? The pointer has not been set to zero.. so... + //the following line would execute (not crash) and return a nonsense value, + //EXPECT_EQ(pStub->refCount(), 0); //returns 2043 on my machine + //segfault : delete pStub; + Stub * pStub2 = new Stub; + EXPECT_NO_THROW(pStub2->unref()); + EXPECT_EQ(pStub2->refCount(), std::numeric_limits<unsigned int>::max()); + //now it's cursed, so euthanise it + delete pStub2; +} \ No newline at end of file