summaryrefslogtreecommitdiffstats
path: root/test/oemrouter_unittest.cpp
diff options
context:
space:
mode:
authorPeter Hanson <peterh@google.com>2017-06-07 17:40:45 -0700
committerVernon Mauery <vernon.mauery@linux.intel.com>2018-07-25 17:31:48 +0000
commit4a58985ce0cfb24bc0eb8678a4aa9a0ac42ba524 (patch)
treec267c333630f61e249a1f9fcc4144d8438241d75 /test/oemrouter_unittest.cpp
parent15309efc2c1cebadbabdb0ef5f74a38fb8b78cfd (diff)
downloadphosphor-host-ipmid-4a58985ce0cfb24bc0eb8678a4aa9a0ac42ba524.tar.gz
phosphor-host-ipmid-4a58985ce0cfb24bc0eb8678a4aa9a0ac42ba524.zip
Add OemRouter facility.
OemRouter adds a facility to register OEM Group Message handlers, then dispatch matching messages to the registered handler. Added as a core source so that any dynamic provider can register its messages without requiring any specific load order. Includes code fixes for x86 portability. Change-Id: I47b8fe7873e3c7fdf35a00d3c8a7e17d30c398c4 Signed-off-by: Peter Hanson <peterh@google.com> Signed-off-by: Patrick Venture <venture@google.com>
Diffstat (limited to 'test/oemrouter_unittest.cpp')
-rw-r--r--test/oemrouter_unittest.cpp175
1 files changed, 175 insertions, 0 deletions
diff --git a/test/oemrouter_unittest.cpp b/test/oemrouter_unittest.cpp
new file mode 100644
index 0000000..a5a79dd
--- /dev/null
+++ b/test/oemrouter_unittest.cpp
@@ -0,0 +1,175 @@
+#include "host-ipmid/ipmid-api.h"
+#include "host-ipmid/oemrouter.hpp"
+#include "sample.h"
+
+#include <cstring>
+#include <gtest/gtest.h>
+
+// Watch for correct singleton behavior.
+static oem::Router* singletonUnderTest;
+
+static ipmid_callback_t wildHandler;
+
+static ipmi_netfn_t lastNetFunction;
+
+// Fake ipmi_register_callback() for this test.
+void ipmi_register_callback(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ ipmi_context_t context, ipmid_callback_t cb,
+ ipmi_cmd_privilege_t priv)
+{
+ EXPECT_EQ(NETFUN_OEM_GROUP, netfn);
+ EXPECT_EQ(IPMI_CMD_WILDCARD, cmd);
+ EXPECT_EQ(reinterpret_cast<void*>(singletonUnderTest), context);
+ EXPECT_EQ(PRIVILEGE_OEM, priv);
+ lastNetFunction = netfn;
+ wildHandler = cb;
+}
+
+namespace oem
+{
+
+namespace
+{
+void MakeRouter()
+{
+ if (!singletonUnderTest)
+ {
+ singletonUnderTest = mutableRouter();
+ }
+ ASSERT_EQ(singletonUnderTest, mutableRouter());
+}
+
+void ActivateRouter()
+{
+ MakeRouter();
+ singletonUnderTest->activate();
+ ASSERT_EQ(NETFUN_OEM_GROUP, lastNetFunction);
+}
+
+void RegisterWithRouter(Number oen, ipmi_cmd_t cmd, Handler cb)
+{
+ ActivateRouter();
+ singletonUnderTest->registerHandler(oen, cmd, cb);
+}
+
+uint8_t msgPlain[] = { 0x56, 0x34, 0x12 };
+uint8_t replyPlain[] = { 0x56, 0x34, 0x12, 0x31, 0x41 };
+uint8_t msgPlus2[] = { 0x67, 0x45, 0x23, 0x10, 0x20 };
+uint8_t msgBadOen[] = { 0x57, 0x34, 0x12 };
+
+void RegisterTwoWays(ipmi_cmd_t *nextCmd)
+{
+ Handler f = [](ipmi_cmd_t cmd, const uint8_t* reqBuf,
+ uint8_t* replyBuf, size_t* dataLen)
+ {
+ // Check inputs
+ EXPECT_EQ(0x78, cmd);
+ EXPECT_EQ(0, *dataLen); // Excludes OEN
+
+ // Generate reply.
+ *dataLen = 2;
+ std::memcpy(replyBuf, replyPlain + 3, *dataLen);
+ return 0;
+ };
+ RegisterWithRouter(0x123456, 0x78, f);
+
+ *nextCmd = IPMI_CMD_WILDCARD;
+ Handler g = [nextCmd](ipmi_cmd_t cmd, const uint8_t* reqBuf,
+ uint8_t* replyBuf, size_t* dataLen)
+ {
+ // Check inputs
+ EXPECT_EQ(*nextCmd, cmd);
+ EXPECT_EQ(2, *dataLen); // Excludes OEN
+ if (2 != *dataLen)
+ {
+ return 0xE0;
+ }
+ EXPECT_EQ(msgPlus2[3], reqBuf[0]);
+ EXPECT_EQ(msgPlus2[4], reqBuf[1]);
+
+ // Generate reply.
+ *dataLen = 0;
+ return 0;
+ };
+ RegisterWithRouter(0x234567, IPMI_CMD_WILDCARD, g);
+}
+} // namespace
+
+TEST(OemRouterTest, MakeRouterProducesConsistentSingleton) {
+ MakeRouter();
+}
+
+TEST(OemRouterTest, ActivateRouterSetsLastNetToOEMGROUP) {
+ lastNetFunction = 0;
+ ActivateRouter();
+}
+
+TEST(OemRouterTest, VerifiesSpecificCommandMatches) {
+ ipmi_cmd_t cmd;
+ uint8_t reply[256];
+ size_t dataLen;
+
+ RegisterTwoWays(&cmd);
+
+ dataLen = 3;
+ EXPECT_EQ(0,
+ wildHandler(NETFUN_OEM_GROUP, 0x78, msgPlain, reply,
+ &dataLen, nullptr));
+ EXPECT_EQ(5, dataLen);
+ EXPECT_EQ(replyPlain[0], reply[0]);
+ EXPECT_EQ(replyPlain[1], reply[1]);
+ EXPECT_EQ(replyPlain[2], reply[2]);
+ EXPECT_EQ(replyPlain[3], reply[3]);
+ EXPECT_EQ(replyPlain[4], reply[4]);
+}
+
+TEST(OemRouterTest, WildCardMatchesTwoRandomCodes) {
+ ipmi_cmd_t cmd;
+ uint8_t reply[256];
+ size_t dataLen;
+
+ RegisterTwoWays(&cmd);
+
+ // Check two random command codes.
+ dataLen = 5;
+ cmd = 0x89;
+ EXPECT_EQ(0,
+ wildHandler(NETFUN_OEM_GROUP, cmd, msgPlus2, reply,
+ &dataLen, nullptr));
+ EXPECT_EQ(3, dataLen);
+
+ dataLen = 5;
+ cmd = 0x67;
+ EXPECT_EQ(0,
+ wildHandler(NETFUN_OEM_GROUP, cmd, msgPlus2, reply,
+ &dataLen, nullptr));
+ EXPECT_EQ(3, dataLen);
+}
+
+TEST(OemRouterTest, CommandsAreRejectedIfInvalid) {
+ ipmi_cmd_t cmd;
+ uint8_t reply[256];
+ size_t dataLen;
+
+ RegisterTwoWays(&cmd);
+
+ // Message too short to include whole OEN?
+ dataLen = 2;
+ EXPECT_EQ(IPMI_CC_REQ_DATA_LEN_INVALID,
+ wildHandler(NETFUN_OEM_GROUP, 0x78, msgPlain, reply,
+ &dataLen, nullptr));
+
+ // Wrong specific command?
+ dataLen = 3;
+ EXPECT_EQ(IPMI_CC_INVALID,
+ wildHandler(NETFUN_OEM_GROUP, 0x89, msgPlain, reply,
+ &dataLen, nullptr));
+
+ // Wrong OEN?
+ dataLen = 3;
+ EXPECT_EQ(IPMI_CC_INVALID,
+ wildHandler(NETFUN_OEM_GROUP, 0x78, msgBadOen, reply,
+ &dataLen, nullptr));
+}
+
+} // namespace oem
OpenPOWER on IntegriCloud