/* * This file is part of ArmarX. * * ArmarX is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * ArmarX is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * @package RobotAPI::ArmarXObjects::armem * @author Simon Ottenhaus ( simon dot ottenhaus at kit dot edu ) * @date 2020 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt * GNU General Public License */ #define BOOST_TEST_MODULE RobotAPI::ArmarXLibraries::armem #define ARMARX_BOOST_TEST #include <RobotAPI/Test.h> #include <RobotAPI/libraries/armem/core/workingmemory/Memory.h> #include <RobotAPI/libraries/armem/core/longtermmemory/Memory.h> #include <RobotAPI/libraries/armem/core/diskmemory/Memory.h> #include <RobotAPI/libraries/armem/core/error.h> #include <iostream> #include <SimoxUtility/meta/type_name.h> #include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h> namespace armem = armarx::armem; namespace aron = armarx::aron; BOOST_AUTO_TEST_CASE(test_time_to_string) { // 111111: seconds, 345: milliseconds, 789: microseconds armem::Time time = armem::Time::microSeconds(111111345789); BOOST_CHECK_EQUAL(armem::toStringMilliSeconds(time), "111111345.789 ms"); BOOST_CHECK_EQUAL(armem::toStringMilliSeconds(time, 0), "111111345 ms"); BOOST_CHECK_EQUAL(armem::toStringMilliSeconds(time, 1), "111111345.7 ms"); BOOST_CHECK_EQUAL(armem::toStringMilliSeconds(time, 2), "111111345.78 ms"); BOOST_CHECK_EQUAL(armem::toStringMilliSeconds(time, 3), "111111345.789 ms"); BOOST_CHECK_EQUAL(armem::toStringMicroSeconds(time), "111111345789 " "\u03BC" "s"); BOOST_CHECK_EQUAL(armem::toDateTimeMilliSeconds(time), "1970-01-02 07:51:51.345789"); BOOST_CHECK_EQUAL(armem::toDateTimeMilliSeconds(time, 0), "1970-01-02 07:51:51"); BOOST_CHECK_EQUAL(armem::toDateTimeMilliSeconds(time, 3), "1970-01-02 07:51:51.345"); BOOST_CHECK_EQUAL(armem::toDateTimeMilliSeconds(time, 6), "1970-01-02 07:51:51.345789"); // 111111: seconds, 000: milliseconds, 789: microseconds time = armem::Time::microSeconds(111111000789); BOOST_CHECK_EQUAL(armem::toStringMilliSeconds(time), "111111000.789 ms"); BOOST_CHECK_EQUAL(armem::toStringMicroSeconds(time), "111111000789 " "\u03BC" "s"); BOOST_CHECK_EQUAL(armem::toDateTimeMilliSeconds(time), "1970-01-02 07:51:51.000789"); BOOST_CHECK_EQUAL(armem::toDateTimeMilliSeconds(time, 0), "1970-01-02 07:51:51"); BOOST_CHECK_EQUAL(armem::toDateTimeMilliSeconds(time, 3), "1970-01-02 07:51:51.000"); BOOST_CHECK_EQUAL(armem::toDateTimeMilliSeconds(time, 6), "1970-01-02 07:51:51.000789"); // 111111: seconds, 345: milliseconds, 000: microseconds time = armem::Time::microSeconds(111111345000); BOOST_CHECK_EQUAL(armem::toStringMilliSeconds(time), "111111345.000 ms"); BOOST_CHECK_EQUAL(armem::toStringMicroSeconds(time), "111111345000 " "\u03BC" "s"); BOOST_CHECK_EQUAL(armem::toDateTimeMilliSeconds(time), "1970-01-02 07:51:51.345000"); BOOST_CHECK_EQUAL(armem::toDateTimeMilliSeconds(time, 0), "1970-01-02 07:51:51"); BOOST_CHECK_EQUAL(armem::toDateTimeMilliSeconds(time, 3), "1970-01-02 07:51:51.345"); BOOST_CHECK_EQUAL(armem::toDateTimeMilliSeconds(time, 6), "1970-01-02 07:51:51.345000"); } namespace ArMemMemoryTest { struct TestMemoryItem : public armem::base::detail::MemoryItem { using MemoryItem::MemoryItem; using MemoryItem::operator=; std::string getKeyString() const override { return ""; } std::string getLevelName() const override { return ""; } }; struct MemoryItemCtorOpTestFixture { const armem::MemoryID id {"A/B/C/123/1"}; const armem::MemoryID moved {"////1"}; // int is not moved TestMemoryItem item { id }; MemoryItemCtorOpTestFixture() { BOOST_CHECK_EQUAL(item.id(), id); } }; } BOOST_FIXTURE_TEST_SUITE(MemoryItemTest, ArMemMemoryTest::MemoryItemCtorOpTestFixture) BOOST_AUTO_TEST_CASE(test_copy_ctor) { const ArMemMemoryTest::TestMemoryItem out(item); BOOST_CHECK_EQUAL(item.id(), id); BOOST_CHECK_EQUAL(out.id(), id); } BOOST_AUTO_TEST_CASE(test_copy_op) { ArMemMemoryTest::TestMemoryItem out; out = item; BOOST_CHECK_EQUAL(item.id(), id); BOOST_CHECK_EQUAL(out.id(), id); } BOOST_AUTO_TEST_CASE(test_move_ctor) { ArMemMemoryTest::TestMemoryItem in = item; const ArMemMemoryTest::TestMemoryItem out(std::move(in)); BOOST_CHECK_EQUAL(in.id(), moved); BOOST_CHECK_EQUAL(out.id(), id); } BOOST_AUTO_TEST_CASE(test_move_op) { ArMemMemoryTest::TestMemoryItem in = item; ArMemMemoryTest::TestMemoryItem out; out = std::move(in); BOOST_CHECK_EQUAL(in.id(), moved); BOOST_CHECK_EQUAL(out.id(), id); } BOOST_AUTO_TEST_SUITE_END() namespace ArMemMemoryTest { struct TestMemoryContainer : public armem::base::detail::MemoryContainerBase<std::vector<int>, TestMemoryContainer> { using MemoryContainerBase::MemoryContainerBase; using MemoryContainerBase::operator=; std::string getKeyString() const override { return ""; } std::string getLevelName() const override { return ""; } }; struct MemoryContainerCtorOpTestFixture { const armem::MemoryID id {"A/B/C/123/1"}; const armem::MemoryID moved {"////1"}; // int is not moved TestMemoryContainer cont {id}; MemoryContainerCtorOpTestFixture() { cont.container() = std::vector<int>{ -1, 2, -3 }; BOOST_CHECK_EQUAL(cont.id(), id); BOOST_CHECK_EQUAL(cont.size(), 3); } }; } BOOST_FIXTURE_TEST_SUITE(MemoryContainerTest, ArMemMemoryTest::MemoryContainerCtorOpTestFixture) BOOST_AUTO_TEST_CASE(test_copy_ctor) { const ArMemMemoryTest::TestMemoryContainer out(cont); BOOST_CHECK_EQUAL(cont.id(), id); BOOST_CHECK_EQUAL(cont.size(), 3); BOOST_CHECK_EQUAL(out.id(), id); BOOST_CHECK_EQUAL(out.size(), 3); } BOOST_AUTO_TEST_CASE(test_copy_op) { ArMemMemoryTest::TestMemoryContainer out; out = cont; BOOST_CHECK_EQUAL(cont.id(), id); BOOST_CHECK_EQUAL(cont.size(), 3); BOOST_CHECK_EQUAL(out.id(), id); BOOST_CHECK_EQUAL(out.size(), 3); } BOOST_AUTO_TEST_CASE(test_move_ctor) { ArMemMemoryTest::TestMemoryContainer in = cont; const ArMemMemoryTest::TestMemoryContainer out(std::move(in)); BOOST_CHECK_EQUAL(in.id(), moved); BOOST_CHECK_EQUAL(in.size(), 0); BOOST_CHECK_EQUAL(out.id(), id); BOOST_CHECK_EQUAL(out.size(), 3); } BOOST_AUTO_TEST_CASE(test_move_op) { ArMemMemoryTest::TestMemoryContainer in = cont; ArMemMemoryTest::TestMemoryContainer out; out = std::move(in); BOOST_CHECK_EQUAL(in.id(), moved); BOOST_CHECK_EQUAL(in.size(), 0); BOOST_CHECK_EQUAL(out.id(), id); BOOST_CHECK_EQUAL(out.size(), 3); } BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_CASE(test_key_ctors) { armem::wm::EntityInstance instance(10); BOOST_CHECK_EQUAL(instance.index(), 10); armem::wm::EntitySnapshot snapshot(armem::Time::milliSeconds(100)); BOOST_CHECK_EQUAL(snapshot.time(), armem::Time::milliSeconds(100)); armem::wm::Entity entity("entity"); BOOST_CHECK_EQUAL(entity.name(), "entity"); armem::wm::ProviderSegment provSeg("provSeg"); BOOST_CHECK_EQUAL(provSeg.name(), "provSeg"); armem::wm::CoreSegment coreSeg("coreSeg"); BOOST_CHECK_EQUAL(coreSeg.name(), "coreSeg"); armem::wm::Memory memory("memory"); BOOST_CHECK_EQUAL(memory.name(), "memory"); } template <class ...Args> auto add_element(std::vector<Args...>& vector) { return vector.emplace_back(); } template <class ...Args> auto add_element(std::map<Args...>& map) { return map.emplace(); } template <class T> struct CustomChecks { static void checkEqual(const T& lhs, const T& rhs) { (void) lhs, (void) rhs; } static void checkMoved(const T& moved) { (void) moved; } }; template <class T> void checkEqual_d_ltm(const T& lhs, const T& rhs) { BOOST_CHECK_EQUAL(lhs.path, rhs.path); } template <class T> void checkMoved_d_ltm(const T& moved) { BOOST_CHECK_EQUAL(moved.path, nullptr); } template <> struct CustomChecks<armem::wm::EntityInstance> { static void checkEqual(const armem::wm::EntityInstance& lhs, const armem::wm::EntityInstance& rhs) { BOOST_CHECK_EQUAL(lhs.metadata(), rhs.metadata()); BOOST_CHECK_EQUAL(lhs.data(), rhs.data()); } static void checkMoved(const armem::wm::EntityInstance& moved) { BOOST_CHECK_EQUAL(moved.data(), nullptr); } }; template <> struct CustomChecks<armem::d_ltm::EntityInstance> { static void checkEqual(const armem::d_ltm::EntityInstance& lhs, const armem::d_ltm::EntityInstance& rhs) { checkEqual_d_ltm(lhs, rhs); } static void checkMoved(const armem::d_ltm::EntityInstance& moved) { checkMoved_d_ltm(moved); } }; template <> struct CustomChecks<armem::d_ltm::EntitySnapshot> { static void checkEqual(const armem::d_ltm::EntitySnapshot& lhs, const armem::d_ltm::EntitySnapshot& rhs) { checkEqual_d_ltm(lhs, rhs); } static void checkMoved(const armem::d_ltm::EntitySnapshot& moved) { checkMoved_d_ltm(moved); } }; template <> struct CustomChecks<armem::d_ltm::Entity> { static void checkEqual(const armem::d_ltm::Entity& lhs, const armem::d_ltm::Entity& rhs) { checkEqual_d_ltm(lhs, rhs); } static void checkMoved(const armem::d_ltm::Entity& moved) { checkMoved_d_ltm(moved); } }; template <> struct CustomChecks<armem::d_ltm::ProviderSegment> { static void checkEqual(const armem::d_ltm::ProviderSegment& lhs, const armem::d_ltm::ProviderSegment& rhs) { checkEqual_d_ltm(lhs, rhs); } static void checkMoved(const armem::d_ltm::ProviderSegment& moved) { checkMoved_d_ltm(moved); } }; template <> struct CustomChecks<armem::d_ltm::CoreSegment> { static void checkEqual(const armem::d_ltm::CoreSegment& lhs, const armem::d_ltm::CoreSegment& rhs) { checkEqual_d_ltm(lhs, rhs); } static void checkMoved(const armem::d_ltm::CoreSegment& moved) { checkMoved_d_ltm(moved); } }; template <> struct CustomChecks<armem::d_ltm::Memory> { static void checkEqual(const armem::d_ltm::Memory& lhs, const armem::d_ltm::Memory& rhs) { checkEqual_d_ltm(lhs, rhs); } static void checkMoved(const armem::d_ltm::Memory& moved) { checkMoved_d_ltm(moved); } }; struct CopyMoveCtorsOpsTestBase { const armem::MemoryID id {"A/B/C/123000"}; // int index would not be moved const armem::MemoryID idMoved; std::string typeName; CopyMoveCtorsOpsTestBase(const std::string& typeName) : typeName(typeName) { } virtual ~CopyMoveCtorsOpsTestBase() { } void test() { BOOST_TEST_CONTEXT("Type " << typeName) { reset(); BOOST_TEST_CONTEXT("copy ctor") { testCopyCtor(); } reset(); BOOST_TEST_CONTEXT("copy op") { testCopyOp(); } reset(); BOOST_TEST_CONTEXT("move ctor") { testMoveCtor(); } reset(); BOOST_TEST_CONTEXT("move op") { testMoveOp(); } } } virtual void reset() { } virtual void testCopyCtor() = 0; virtual void testCopyOp() = 0; virtual void testMoveCtor() = 0; virtual void testMoveOp() = 0; }; template <class T> struct InstanceCopyMoveCtorsOpsTest : public CopyMoveCtorsOpsTestBase { T in; InstanceCopyMoveCtorsOpsTest() : CopyMoveCtorsOpsTestBase(simox::meta::get_type_name<T>()) { } virtual ~InstanceCopyMoveCtorsOpsTest() override = default; void reset() override { in = T {id}; BOOST_CHECK_EQUAL(in.id(), id); } void testCopyCtor() override { T out { in }; BOOST_CHECK_EQUAL(out.id(), id); CustomChecks<T>::checkEqual(out, in); } void testCopyOp() override { T out; out = in; BOOST_CHECK_EQUAL(out.id(), id); CustomChecks<T>::checkEqual(out, in); } void testMoveCtor() override { T out { std::move(in) }; BOOST_CHECK_EQUAL(in.id(), idMoved); BOOST_CHECK_EQUAL(out.id(), id); CustomChecks<T>::checkMoved(in); } void testMoveOp() override { T out; out = std::move(in); BOOST_CHECK_EQUAL(in.id(), idMoved); BOOST_CHECK_EQUAL(out.id(), id); CustomChecks<T>::checkMoved(in); } }; template <class T> struct CopyMoveCtorsOpsTest : public CopyMoveCtorsOpsTestBase { T in; CopyMoveCtorsOpsTest() : CopyMoveCtorsOpsTestBase(simox::meta::get_type_name<T>()) { } virtual ~CopyMoveCtorsOpsTest() override = default; void reset() override { in = T {id}; add_element(in.container()); BOOST_CHECK_EQUAL(in.id(), id); BOOST_CHECK_EQUAL(in.size(), 1); } void testCopyCtor() override { T out { in }; BOOST_CHECK_EQUAL(in.id(), id); BOOST_CHECK_EQUAL(in.size(), 1); BOOST_CHECK_EQUAL(out.id(), id); BOOST_CHECK_EQUAL(out.size(), 1); CustomChecks<T>::checkEqual(out, in); } void testCopyOp() override { T out; out = in; BOOST_CHECK_EQUAL(in.id(), id); BOOST_CHECK_EQUAL(in.size(), 1); BOOST_CHECK_EQUAL(out.id(), id); BOOST_CHECK_EQUAL(out.size(), 1); CustomChecks<T>::checkEqual(out, in); } void testMoveCtor() override { T out { std::move(in) }; BOOST_CHECK_EQUAL(in.id(), idMoved); BOOST_CHECK_EQUAL(in.size(), 0); BOOST_CHECK_EQUAL(out.id(), id); BOOST_CHECK_EQUAL(out.size(), 1); CustomChecks<T>::checkMoved(in); } void testMoveOp() override { T out; out = std::move(in); BOOST_CHECK_EQUAL(in.id(), idMoved); BOOST_CHECK_EQUAL(in.size(), 0); BOOST_CHECK_EQUAL(out.id(), id); BOOST_CHECK_EQUAL(out.size(), 1); CustomChecks<T>::checkMoved(in); } }; BOOST_AUTO_TEST_CASE(test_copy_move_ctors_ops) { { InstanceCopyMoveCtorsOpsTest<armem::wm::EntityInstance>().test(); CopyMoveCtorsOpsTest<armem::wm::EntitySnapshot>().test(); CopyMoveCtorsOpsTest<armem::wm::Entity>().test(); CopyMoveCtorsOpsTest<armem::wm::ProviderSegment>().test(); CopyMoveCtorsOpsTest<armem::wm::CoreSegment>().test(); CopyMoveCtorsOpsTest<armem::wm::Memory>().test(); } { InstanceCopyMoveCtorsOpsTest<armem::ltm::EntityInstance>().test(); CopyMoveCtorsOpsTest<armem::ltm::EntitySnapshot>().test(); CopyMoveCtorsOpsTest<armem::ltm::Entity>().test(); CopyMoveCtorsOpsTest<armem::ltm::ProviderSegment>().test(); CopyMoveCtorsOpsTest<armem::ltm::CoreSegment>().test(); CopyMoveCtorsOpsTest<armem::ltm::Memory>().test(); } { InstanceCopyMoveCtorsOpsTest<armem::d_ltm::EntityInstance>().test(); CopyMoveCtorsOpsTest<armem::d_ltm::EntitySnapshot>().test(); CopyMoveCtorsOpsTest<armem::d_ltm::Entity>().test(); CopyMoveCtorsOpsTest<armem::d_ltm::ProviderSegment>().test(); CopyMoveCtorsOpsTest<armem::d_ltm::CoreSegment>().test(); CopyMoveCtorsOpsTest<armem::d_ltm::Memory>().test(); } } BOOST_AUTO_TEST_CASE(test_segment_setup) { armem::EntityUpdate update; armem::wm::Memory memory("Memory"); BOOST_CHECK_EQUAL(memory.name(), "Memory"); { update.entityID = armem::MemoryID::fromString("OtherMemory/SomeSegment"); BOOST_CHECK_THROW(memory.update(update), armem::error::ContainerNameMismatch); update.entityID = armem::MemoryID::fromString("Memory/MissingSegment"); BOOST_CHECK_THROW(memory.update(update), armem::error::MissingEntry); } armem::wm::CoreSegment& coreSegment = memory.addCoreSegment("ImageRGB"); BOOST_CHECK_EQUAL(coreSegment.name(), "ImageRGB"); BOOST_CHECK(memory.hasCoreSegment(coreSegment.name())); { update.entityID = armem::MemoryID::fromString("Memory/OtherCoreSegment"); BOOST_CHECK_THROW(coreSegment.update(update), armem::error::ContainerNameMismatch); update.entityID = armem::MemoryID::fromString("Memory/ImageRGB/MissingProvider"); BOOST_CHECK_THROW(coreSegment.update(update), armem::error::MissingEntry); } armem::wm::ProviderSegment& providerSegment = coreSegment.addProviderSegment("SomeRGBImageProvider"); BOOST_CHECK_EQUAL(providerSegment.name(), "SomeRGBImageProvider"); BOOST_CHECK(coreSegment.hasProviderSegment(providerSegment.name())); { update.entityID = armem::MemoryID::fromString("Memory/ImageRGB/OtherRGBImageProvider"); BOOST_CHECK_THROW(providerSegment.update(update), armem::error::ContainerNameMismatch); } // A successful update. update.entityID = armem::MemoryID::fromString("Memory/ImageRGB/SomeRGBImageProvider/image"); update.instancesData = { std::make_shared<aron::datanavigator::DictNavigator>(), std::make_shared<aron::datanavigator::DictNavigator>() }; update.timeCreated = armem::Time::milliSeconds(1000); BOOST_CHECK_NO_THROW(providerSegment.update(update)); BOOST_CHECK_EQUAL(providerSegment.entities().size(), 1); BOOST_CHECK(providerSegment.hasEntity("image")); BOOST_CHECK(!providerSegment.hasEntity("other_image")); armem::wm::Entity& entity = providerSegment.getEntity("image"); BOOST_CHECK_EQUAL(entity.name(), "image"); BOOST_CHECK_EQUAL(entity.history().size(), 1); BOOST_CHECK_EQUAL(entity.history().count(update.timeCreated), 1); armem::wm::EntitySnapshot& entitySnapshot = entity.history().at(update.timeCreated); BOOST_CHECK_EQUAL(entitySnapshot.instances().size(), update.instancesData.size()); // Another update (on memory). update.instancesData = { std::make_shared<aron::datanavigator::DictNavigator>() }; update.timeCreated = armem::Time::milliSeconds(2000); memory.update(update); BOOST_CHECK_EQUAL(entity.history().size(), 2); BOOST_CHECK_EQUAL(entity.history().count(update.timeCreated), 1); BOOST_CHECK_EQUAL(entity.history().at(update.timeCreated).instances().size(), update.instancesData.size()); // A third update (on entity). update.instancesData = { std::make_shared<aron::datanavigator::DictNavigator>() }; update.timeCreated = armem::Time::milliSeconds(3000); entity.update(update); BOOST_CHECK_EQUAL(entity.history().size(), 3); } BOOST_AUTO_TEST_CASE(test_history_size_in_entity) { armem::wm::Entity entity("entity"); armem::EntityUpdate update; update.entityID.entityName = entity.name(); // With unlimited history. update.timeCreated = armem::Time::milliSeconds(1000); entity.update(update); update.timeCreated = armem::Time::milliSeconds(2000); entity.update(update); update.timeCreated = armem::Time::milliSeconds(3000); entity.update(update); BOOST_CHECK_EQUAL(entity.history().size(), 3); // Now with maximum history size. entity.setMaxHistorySize(2); BOOST_CHECK_EQUAL(entity.history().size(), 2); BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(1000)), 0); BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(2000)), 1); BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(3000)), 1); update.timeCreated = armem::Time::milliSeconds(4000); entity.update(update); BOOST_CHECK_EQUAL(entity.history().size(), 2); BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(2000)), 0); BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(3000)), 1); BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(4000)), 1); // Disable maximum history size. entity.setMaxHistorySize(-1); update.timeCreated = armem::Time::milliSeconds(5000); entity.update(update); BOOST_CHECK_EQUAL(entity.history().size(), 3); BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(3000)), 1); BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(4000)), 1); BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(5000)), 1); } BOOST_AUTO_TEST_CASE(test_history_size_in_provider_segment) { armem::wm::ProviderSegment providerSegment("SomeRGBImageProvider"); armem::EntityUpdate update; update.entityID.providerSegmentName = providerSegment.name(); std::vector<std::string> entityNames = { "A", "B" }; // Fill entities and histories with unlimited size. for (const auto& name : entityNames) { update.entityID.entityName = name; update.timeCreated = armem::Time::milliSeconds(1000); providerSegment.update(update); update.timeCreated = armem::Time::milliSeconds(2000); providerSegment.update(update); update.timeCreated = armem::Time::milliSeconds(3000); providerSegment.update(update); } update.entityID.entityName = entityNames.back(); update.timeCreated = armem::Time::milliSeconds(4000); providerSegment.update(update); BOOST_CHECK_EQUAL(providerSegment.getEntity("A").history().size(), 3); BOOST_CHECK_EQUAL(providerSegment.getEntity("B").history().size(), 4); // Employ maximum history size. providerSegment.setMaxHistorySize(3); BOOST_CHECK_EQUAL(providerSegment.getEntity("A").history().size(), 3); BOOST_CHECK_EQUAL(providerSegment.getEntity("B").history().size(), 3); providerSegment.setMaxHistorySize(2); BOOST_CHECK_EQUAL(providerSegment.getEntity("A").history().size(), 2); BOOST_CHECK_EQUAL(providerSegment.getEntity("B").history().size(), 2); providerSegment.setMaxHistorySize(3); BOOST_CHECK_EQUAL(providerSegment.getEntity("A").history().size(), 2); BOOST_CHECK_EQUAL(providerSegment.getEntity("B").history().size(), 2); // Add new entity. providerSegment.setMaxHistorySize(2); update.entityID.entityName = "C"; update.timeCreated = armem::Time::milliSeconds(1000); providerSegment.update(update); update.timeCreated = armem::Time::milliSeconds(2000); providerSegment.update(update); update.timeCreated = armem::Time::milliSeconds(3000); providerSegment.update(update); // Check correctly inherited history size. BOOST_CHECK_EQUAL(providerSegment.getEntity("C").getMaxHistorySize(), 2); // Check actual history size. BOOST_CHECK_EQUAL(providerSegment.getEntity("C").history().size(), 2); // Remove maximum. providerSegment.setMaxHistorySize(-1); entityNames.push_back("C"); for (const auto& name : entityNames) { update.entityID.entityName = name; update.timeCreated = armem::Time::milliSeconds(5000); providerSegment.update(update); BOOST_CHECK_EQUAL(providerSegment.getEntity(name).history().size(), 3); } } template <class T> struct CopyTest { CopyTest() { } void test() { // At least check whether they can be called. T t; T t2 = t.copy(); if constexpr (std::is_base_of_v<armem::base::EntityInstanceBase<T>, T>) { t2 = t.copyEmpty(); } } }; BOOST_AUTO_TEST_CASE(test_copy) { { CopyTest<armem::wm::EntityInstance>().test(); CopyTest<armem::wm::EntitySnapshot>().test(); CopyTest<armem::wm::Entity>().test(); CopyTest<armem::wm::ProviderSegment>().test(); CopyTest<armem::wm::CoreSegment>().test(); CopyTest<armem::wm::Memory>().test(); } { CopyTest<armem::ltm::EntityInstance>().test(); CopyTest<armem::ltm::EntitySnapshot>().test(); CopyTest<armem::ltm::Entity>().test(); CopyTest<armem::ltm::ProviderSegment>().test(); CopyTest<armem::ltm::CoreSegment>().test(); CopyTest<armem::ltm::Memory>().test(); } { CopyTest<armem::d_ltm::EntityInstance>().test(); CopyTest<armem::d_ltm::EntitySnapshot>().test(); CopyTest<armem::d_ltm::Entity>().test(); CopyTest<armem::d_ltm::ProviderSegment>().test(); CopyTest<armem::d_ltm::CoreSegment>().test(); CopyTest<armem::d_ltm::Memory>().test(); } }