diff --git a/src/mesh/DualConnectivityManager.cpp b/src/mesh/DualConnectivityManager.cpp index 8145d4112182d775d2737f88c26991b34704a07d..87c154dc93c48d81ad6e05a49f65fe295e69e316 100644 --- a/src/mesh/DualConnectivityManager.cpp +++ b/src/mesh/DualConnectivityManager.cpp @@ -24,6 +24,7 @@ DualConnectivityManager::destroy() { Assert(m_instance != nullptr, "DualConnectivityManager was not created!"); + // LCOV_EXCL_START if (m_instance->m_connectivity_to_dual_connectivity_info_map.size() > 0) { std::stringstream error; error << ": some connectivities are still registered\n"; @@ -33,6 +34,7 @@ DualConnectivityManager::destroy() << rang::style::reset << '\n'; } throw UnexpectedError(error.str()); + // LCOV_EXCL_STOP } delete m_instance; m_instance = nullptr; @@ -82,9 +84,11 @@ DualConnectivityManager::_getDualConnectivityInfo(const DualMeshType& type, cons case DualMeshType::Diamond: { return this->_buildDualConnectivity<DiamondDualConnectivityBuilder>(key, connectivity); } + // LCOV_EXCL_START default: { throw UnexpectedError("invalid dual mesh type"); } + // LCOV_EXCL_STOP } } } @@ -109,7 +113,9 @@ DualConnectivityManager::getConnectivityToDiamondDualConnectivityDataMapper(cons if (diamond_data_mapper.use_count() > 0) { return diamond_data_mapper; } else { + // LCOV_EXCL_START throw UnexpectedError("invalid connectivity data mapper type"); + // LCOV_EXCL_STOP } } @@ -133,7 +139,9 @@ DualConnectivityManager::getConnectivityToMedianDualConnectivityDataMapper(const if (data_mapper.use_count() > 0) { return data_mapper; } else { + // LCOV_EXCL_START throw UnexpectedError("invalid connectivity data mapper type"); + // LCOV_EXCL_STOP } } diff --git a/src/mesh/DualConnectivityManager.hpp b/src/mesh/DualConnectivityManager.hpp index 2da7e26a317dbb4ccc81954396091433e9987482..5601e431d712d22712096b0ad5accad33a172ed7 100644 --- a/src/mesh/DualConnectivityManager.hpp +++ b/src/mesh/DualConnectivityManager.hpp @@ -42,11 +42,11 @@ class DualConnectivityManager } DualConnectivityInfo& operator=(const DualConnectivityInfo&) = default; - DualConnectivityInfo& operator=(DualConnectivityInfo&&) = default; + DualConnectivityInfo& operator=(DualConnectivityInfo&&) = delete; DualConnectivityInfo() = default; DualConnectivityInfo(const DualConnectivityInfo&) = default; - DualConnectivityInfo(DualConnectivityInfo&&) = default; + DualConnectivityInfo(DualConnectivityInfo&&) = delete; DualConnectivityInfo(const std::shared_ptr<const IConnectivity>& dual_connectivity, const std::shared_ptr<const IConnectivityToDualConnectivityDataMapper>& diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f825a2cfdfcd2f869037039d10eb041aced9980c..ecc4880c2a86b48f73ad73eec93578eeb06188ac 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -65,6 +65,7 @@ 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 diff --git a/tests/test_DualConnectivityManager.cpp b/tests/test_DualConnectivityManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1c5b26cd4330731392ba46757dcad3bc2566e5e7 --- /dev/null +++ b/tests/test_DualConnectivityManager.cpp @@ -0,0 +1,136 @@ +#include <catch2/catch_test_macros.hpp> +#include <catch2/matchers/catch_matchers_all.hpp> + +#include <MeshDataBaseForTests.hpp> +#include <mesh/DualConnectivityManager.hpp> + +#include <mesh/Connectivity.hpp> +#include <mesh/Mesh.hpp> + +// clazy:excludeall=non-pod-global-static + +TEST_CASE("DualConnectivityManager", "[mesh]") +{ + using ConnectivityType = Connectivity<2>; + using MeshType = Mesh<ConnectivityType>; + + std::shared_ptr<const MeshType> mesh = MeshDataBaseForTests::get().hybrid2DMesh(); + const ConnectivityType& connectivity = mesh->connectivity(); + + SECTION("diamond dual connectivity access") + { + std::shared_ptr p_diamond_dual_connectivity = + DualConnectivityManager::instance().getDiamondDualConnectivity(connectivity); + + std::shared_ptr p_diamond_dual_connectivity_mapper = + DualConnectivityManager::instance().getConnectivityToDiamondDualConnectivityDataMapper(connectivity); + + const auto ref_counter = p_diamond_dual_connectivity.use_count(); + const auto ref_counter_mapper = p_diamond_dual_connectivity_mapper.use_count(); + + { + std::shared_ptr p_diamond_dual_connectivity2 = + DualConnectivityManager::instance().getDiamondDualConnectivity(connectivity); + std::shared_ptr p_diamond_dual_connectivity_mapper2 = + DualConnectivityManager::instance().getConnectivityToDiamondDualConnectivityDataMapper(connectivity); + + REQUIRE(p_diamond_dual_connectivity == p_diamond_dual_connectivity2); + REQUIRE(p_diamond_dual_connectivity.use_count() == ref_counter + 1); + REQUIRE(p_diamond_dual_connectivity_mapper == p_diamond_dual_connectivity_mapper2); + REQUIRE(p_diamond_dual_connectivity_mapper.use_count() == ref_counter_mapper + 1); + } + + REQUIRE(p_diamond_dual_connectivity.use_count() == ref_counter); + + DualConnectivityManager::instance().deleteConnectivity(&connectivity); + REQUIRE(p_diamond_dual_connectivity.use_count() == ref_counter - 1); + + // Can delete connectivity from the list again. This means that no + // dual connectivity associated with it is managed. + REQUIRE_NOTHROW(DualConnectivityManager::instance().deleteConnectivity(&connectivity)); + REQUIRE(p_diamond_dual_connectivity.use_count() == ref_counter - 1); + + // A new dual connectivity is built + std::shared_ptr p_diamond_dual_connectivity_rebuilt = + DualConnectivityManager::instance().getDiamondDualConnectivity(connectivity); + REQUIRE(p_diamond_dual_connectivity != p_diamond_dual_connectivity_rebuilt); + REQUIRE(p_diamond_dual_connectivity.get() != p_diamond_dual_connectivity_rebuilt.get()); + + // Exactly two references to the dual connectivity. One here and + // one in the manager. + REQUIRE(p_diamond_dual_connectivity_rebuilt.use_count() == 2); + } + + SECTION("median dual connectivity access") + { + std::shared_ptr p_median_dual_connectivity = + DualConnectivityManager::instance().getMedianDualConnectivity(connectivity); + + std::shared_ptr p_median_dual_connectivity_mapper = + DualConnectivityManager::instance().getConnectivityToMedianDualConnectivityDataMapper(connectivity); + + const auto ref_counter = p_median_dual_connectivity.use_count(); + const auto ref_counter_mapper = p_median_dual_connectivity_mapper.use_count(); + + { + std::shared_ptr p_median_dual_connectivity2 = + DualConnectivityManager::instance().getMedianDualConnectivity(connectivity); + + std::shared_ptr p_median_dual_connectivity_mapper2 = + DualConnectivityManager::instance().getConnectivityToMedianDualConnectivityDataMapper(connectivity); + + REQUIRE(p_median_dual_connectivity == p_median_dual_connectivity2); + REQUIRE(p_median_dual_connectivity.use_count() == ref_counter + 1); + REQUIRE(p_median_dual_connectivity_mapper == p_median_dual_connectivity_mapper2); + REQUIRE(p_median_dual_connectivity_mapper.use_count() == ref_counter_mapper + 1); + } + + REQUIRE(p_median_dual_connectivity.use_count() == ref_counter); + + DualConnectivityManager::instance().deleteConnectivity(&connectivity); + REQUIRE(p_median_dual_connectivity.use_count() == ref_counter - 1); + + // Can delete connectivity from the list again. This means that no + // dual connectivity associated with it is managed. + REQUIRE_NOTHROW(DualConnectivityManager::instance().deleteConnectivity(&connectivity)); + REQUIRE(p_median_dual_connectivity.use_count() == ref_counter - 1); + + // A new dual connectivity is built + std::shared_ptr p_median_dual_connectivity_rebuilt = + DualConnectivityManager::instance().getMedianDualConnectivity(connectivity); + REQUIRE(p_median_dual_connectivity != p_median_dual_connectivity_rebuilt); + REQUIRE(p_median_dual_connectivity.get() != p_median_dual_connectivity_rebuilt.get()); + + // Exactly two references to the dual connectivity. One here and + // one in the manager. + REQUIRE(p_median_dual_connectivity_rebuilt.use_count() == 2); + } + + SECTION("check multiple dual connectivities using/freeing") + { + std::shared_ptr p_median_dual_connectivity = + DualConnectivityManager::instance().getMedianDualConnectivity(connectivity); + std::shared_ptr p_diamond_dual_connectivity = + DualConnectivityManager::instance().getDiamondDualConnectivity(connectivity); + + std::shared_ptr p_median_dual_connectivity_mapper = + DualConnectivityManager::instance().getConnectivityToMedianDualConnectivityDataMapper(connectivity); + std::shared_ptr p_diamond_dual_connectivity_mapper = + DualConnectivityManager::instance().getConnectivityToDiamondDualConnectivityDataMapper(connectivity); + + const auto median_ref_counter = p_median_dual_connectivity.use_count(); + const auto diamond_ref_counter = p_diamond_dual_connectivity.use_count(); + + const auto median_mapper_ref_counter = p_median_dual_connectivity_mapper.use_count(); + const auto diamond_mapper_ref_counter = p_diamond_dual_connectivity_mapper.use_count(); + + REQUIRE(p_median_dual_connectivity != p_diamond_dual_connectivity); + REQUIRE(size_t(p_median_dual_connectivity_mapper.get()) != size_t(p_diamond_dual_connectivity_mapper.get())); + + REQUIRE_NOTHROW(DualConnectivityManager::instance().deleteConnectivity(&connectivity)); + REQUIRE(p_median_dual_connectivity.use_count() == median_ref_counter - 1); + REQUIRE(p_diamond_dual_connectivity.use_count() == diamond_ref_counter - 1); + REQUIRE(p_median_dual_connectivity_mapper.use_count() == median_mapper_ref_counter - 1); + REQUIRE(p_diamond_dual_connectivity_mapper.use_count() == diamond_mapper_ref_counter - 1); + } +}