diff --git a/src/mesh/DualMeshManager.cpp b/src/mesh/DualMeshManager.cpp index 3917866b401590d61e312bf9338f10f7eb9f8975..11f09ff2172dbd9ca02f88293a39de53323fda77 100644 --- a/src/mesh/DualMeshManager.cpp +++ b/src/mesh/DualMeshManager.cpp @@ -24,6 +24,7 @@ DualMeshManager::destroy() Assert(m_instance != nullptr, "DualMeshManager was not created!"); if (m_instance->m_mesh_to_dual_mesh_map.size() > 0) { + // LCOV_EXCL_START std::stringstream error; error << ": some meshes are still registered\n"; for (const auto& [key, parent_mesh] : m_instance->m_mesh_to_dual_mesh_map) { @@ -31,6 +32,7 @@ DualMeshManager::destroy() << " dual mesh of " << rang::fgB::yellow << parent_mesh.get() << rang::style::reset << '\n'; } throw UnexpectedError(error.str()); + // LCOV_EXCL_STOP } delete m_instance; m_instance = nullptr; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ecc4880c2a86b48f73ad73eec93578eeb06188ac..c635fde526cd1e55218b8a0f5c8e97e18de9204d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -65,12 +65,13 @@ add_executable (unit_tests test_CubeTransformation.cpp test_DataVariant.cpp test_Demangle.cpp - test_DualConnectivityManager.cpp test_DiscreteFunctionDescriptorP0.cpp test_DiscreteFunctionDescriptorP0Vector.cpp test_DiscreteFunctionType.cpp test_DiscreteFunctionUtils.cpp test_DoWhileProcessor.cpp + test_DualConnectivityManager.cpp + test_DualMeshManager.cpp test_EdgeIntegrator.cpp test_EigenvalueSolver.cpp test_EmbeddedData.cpp diff --git a/tests/test_DualMeshManager.cpp b/tests/test_DualMeshManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6e24f7aa99e558ebfd5ed621244a4a99e073bf37 --- /dev/null +++ b/tests/test_DualMeshManager.cpp @@ -0,0 +1,99 @@ +#include <catch2/catch_test_macros.hpp> +#include <catch2/matchers/catch_matchers_all.hpp> + +#include <MeshDataBaseForTests.hpp> +#include <mesh/DualMeshManager.hpp> + +#include <mesh/Connectivity.hpp> +#include <mesh/Mesh.hpp> + +// clazy:excludeall=non-pod-global-static + +TEST_CASE("DualMeshManager", "[mesh]") +{ + using ConnectivityType = Connectivity<2>; + using MeshType = Mesh<ConnectivityType>; + + std::shared_ptr<const MeshType> mesh = MeshDataBaseForTests::get().hybrid2DMesh(); + + SECTION("diamond dual mesh access") + { + std::shared_ptr p_diamond_dual_mesh = DualMeshManager::instance().getDiamondDualMesh(mesh); + + const auto ref_counter = p_diamond_dual_mesh.use_count(); + + { + std::shared_ptr p_diamond_dual_mesh2 = DualMeshManager::instance().getDiamondDualMesh(mesh); + + REQUIRE(p_diamond_dual_mesh == p_diamond_dual_mesh2); + REQUIRE(p_diamond_dual_mesh.use_count() == ref_counter + 1); + } + + REQUIRE(p_diamond_dual_mesh.use_count() == ref_counter); + + DualMeshManager::instance().deleteMesh(mesh.get()); + REQUIRE(p_diamond_dual_mesh.use_count() == ref_counter - 1); + + // Can delete mesh from the list again. This means that no + // dual mesh associated with it is managed. + REQUIRE_NOTHROW(DualMeshManager::instance().deleteMesh(mesh.get())); + REQUIRE(p_diamond_dual_mesh.use_count() == ref_counter - 1); + + // A new dual mesh is built + std::shared_ptr p_diamond_dual_mesh_rebuilt = DualMeshManager::instance().getDiamondDualMesh(mesh); + REQUIRE(p_diamond_dual_mesh != p_diamond_dual_mesh_rebuilt); + REQUIRE(p_diamond_dual_mesh.get() != p_diamond_dual_mesh_rebuilt.get()); + + // Exactly two references to the dual mesh. One here and + // one in the manager. + REQUIRE(p_diamond_dual_mesh_rebuilt.use_count() == 2); + } + + SECTION("median dual mesh access") + { + std::shared_ptr p_median_dual_mesh = DualMeshManager::instance().getMedianDualMesh(mesh); + + const auto ref_counter = p_median_dual_mesh.use_count(); + + { + std::shared_ptr p_median_dual_mesh2 = DualMeshManager::instance().getMedianDualMesh(mesh); + + REQUIRE(p_median_dual_mesh == p_median_dual_mesh2); + REQUIRE(p_median_dual_mesh.use_count() == ref_counter + 1); + } + + REQUIRE(p_median_dual_mesh.use_count() == ref_counter); + + DualMeshManager::instance().deleteMesh(mesh.get()); + REQUIRE(p_median_dual_mesh.use_count() == ref_counter - 1); + + // Can delete mesh from the list again. This means that no + // dual mesh associated with it is managed. + REQUIRE_NOTHROW(DualMeshManager::instance().deleteMesh(mesh.get())); + REQUIRE(p_median_dual_mesh.use_count() == ref_counter - 1); + + // A new dual mesh is built + std::shared_ptr p_median_dual_mesh_rebuilt = DualMeshManager::instance().getMedianDualMesh(mesh); + REQUIRE(p_median_dual_mesh != p_median_dual_mesh_rebuilt); + REQUIRE(p_median_dual_mesh.get() != p_median_dual_mesh_rebuilt.get()); + + // Exactly two references to the dual mesh. One here and + // one in the manager. + REQUIRE(p_median_dual_mesh_rebuilt.use_count() == 2); + } + + SECTION("check multiple dual mesh using/freeing") + { + std::shared_ptr p_median_dual_mesh = DualMeshManager::instance().getMedianDualMesh(mesh); + std::shared_ptr p_diamond_dual_mesh = DualMeshManager::instance().getDiamondDualMesh(mesh); + + const auto median_ref_counter = p_median_dual_mesh.use_count(); + const auto diamond_ref_counter = p_diamond_dual_mesh.use_count(); + + REQUIRE(p_median_dual_mesh != p_diamond_dual_mesh); + + REQUIRE_NOTHROW(DualMeshManager::instance().deleteMesh(mesh.get())); + REQUIRE(p_median_dual_mesh.use_count() == median_ref_counter - 1); + REQUIRE(p_diamond_dual_mesh.use_count() == diamond_ref_counter - 1); + } +}