IVGCVSW-3425 Create the Command Handler Functor base class

Change-Id: I59ac9b32ac594161bdc5e1de2cdee02d79fc1992
Signed-off-by: Francis Murtagh <francis.murtagh@arm.com>
diff --git a/src/profiling/test/ProfilingTests.cpp b/src/profiling/test/ProfilingTests.cpp
index 1ea8ab9..26cbfd7 100644
--- a/src/profiling/test/ProfilingTests.cpp
+++ b/src/profiling/test/ProfilingTests.cpp
@@ -4,11 +4,13 @@
 //
 
 #include "../CommandHandlerKey.hpp"
+#include "../CommandHandlerFunctor.hpp"
 #include "../Packet.hpp"
 
 #include <cstdint>
 #include <cstring>
 #include <boost/test/unit_test.hpp>
+#include <map>
 
 BOOST_AUTO_TEST_SUITE(ExternalProfiling)
 
@@ -78,4 +80,80 @@
     BOOST_CHECK(packetTest1.GetPacketClass() == 5);
 }
 
+BOOST_AUTO_TEST_CASE(CheckCommandHandlerFunctor)
+{
+    // Create Derived Classes
+    class TestFunctorA : public CommandHandlerFunctor
+    {
+    public:
+        using CommandHandlerFunctor::CommandHandlerFunctor;
+
+        int GetCount() { return m_Count; }
+
+        void operator()(const Packet& packet) override
+        {
+            m_Count++;
+        }
+
+    private:
+        int m_Count = 0;
+    };
+
+    class TestFunctorB : public TestFunctorA
+    {
+        using TestFunctorA::TestFunctorA;
+    };
+
+    class TestFunctorC : public TestFunctorA
+    {
+        using TestFunctorA::TestFunctorA;
+    };
+
+    // Hard code the version as it will be the same during a single profiling session
+    uint32_t version = 1;
+
+    TestFunctorA testFunctorA(461, version);
+    TestFunctorB testFunctorB(963, version);
+    TestFunctorC testFunctorC(983, version);
+
+    CommandHandlerKey keyA(testFunctorA.GetPacketId(), testFunctorA.GetVersion());
+    CommandHandlerKey keyB(testFunctorB.GetPacketId(), testFunctorB.GetVersion());
+    CommandHandlerKey keyC(testFunctorC.GetPacketId(), testFunctorC.GetVersion());
+
+    // Create the unwrapped map to simulate the Command Handler Registry
+    std::map<CommandHandlerKey, CommandHandlerFunctor*> registry;
+
+    registry.insert(std::make_pair(keyB, &testFunctorB));
+    registry.insert(std::make_pair(keyA, &testFunctorA));
+    registry.insert(std::make_pair(keyC, &testFunctorC));
+
+    // Check the order of the map is correct
+    auto it = registry.begin();
+    BOOST_CHECK(it->first==keyA);
+    it++;
+    BOOST_CHECK(it->first==keyB);
+    it++;
+    BOOST_CHECK(it->first==keyC);
+
+    Packet packetA(500000000, 0, nullptr);
+    Packet packetB(600000000, 0, nullptr);
+    Packet packetC(400000000, 0, nullptr);
+
+    // Check the correct operator of derived class is called
+    registry.at(CommandHandlerKey(packetA.GetPacketId(), version))->operator()(packetA);
+    BOOST_CHECK(testFunctorA.GetCount() == 1);
+    BOOST_CHECK(testFunctorB.GetCount() == 0);
+    BOOST_CHECK(testFunctorC.GetCount() == 0);
+
+    registry.at(CommandHandlerKey(packetB.GetPacketId(), version))->operator()(packetB);
+    BOOST_CHECK(testFunctorA.GetCount() == 1);
+    BOOST_CHECK(testFunctorB.GetCount() == 1);
+    BOOST_CHECK(testFunctorC.GetCount() == 0);
+
+    registry.at(CommandHandlerKey(packetC.GetPacketId(), version))->operator()(packetC);
+    BOOST_CHECK(testFunctorA.GetCount() == 1);
+    BOOST_CHECK(testFunctorB.GetCount() == 1);
+    BOOST_CHECK(testFunctorC.GetCount() == 1);
+}
+
 BOOST_AUTO_TEST_SUITE_END()