From 4a58985ce0cfb24bc0eb8678a4aa9a0ac42ba524 Mon Sep 17 00:00:00 2001 From: Peter Hanson Date: Wed, 7 Jun 2017 17:40:45 -0700 Subject: 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 Signed-off-by: Patrick Venture --- test/oemrouter_unittest.cpp | 175 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 test/oemrouter_unittest.cpp (limited to 'test/oemrouter_unittest.cpp') 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 +#include + +// 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(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 -- cgit v1.2.1