1 #include <ipmid/api.h> 2 3 #include <cstring> 4 #include <ipmid/oemrouter.hpp> 5 6 #include "sample.h" 7 8 #include <gtest/gtest.h> 9 10 // Watch for correct singleton behavior. 11 static oem::Router* singletonUnderTest; 12 13 static ipmid_callback_t wildHandler; 14 15 static ipmi_netfn_t lastNetFunction; 16 17 // Fake ipmi_register_callback() for this test. 18 void ipmi_register_callback(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 19 ipmi_context_t context, ipmid_callback_t cb, 20 ipmi_cmd_privilege_t priv) 21 { 22 EXPECT_EQ(NETFUN_OEM_GROUP, netfn); 23 EXPECT_EQ(IPMI_CMD_WILDCARD, cmd); 24 EXPECT_EQ(reinterpret_cast<void*>(singletonUnderTest), context); 25 EXPECT_EQ(PRIVILEGE_OEM, priv); 26 lastNetFunction = netfn; 27 wildHandler = cb; 28 } 29 30 namespace oem 31 { 32 33 namespace 34 { 35 void MakeRouter() 36 { 37 if (!singletonUnderTest) 38 { 39 singletonUnderTest = mutableRouter(); 40 } 41 ASSERT_EQ(singletonUnderTest, mutableRouter()); 42 } 43 44 void ActivateRouter() 45 { 46 MakeRouter(); 47 singletonUnderTest->activate(); 48 ASSERT_EQ(NETFUN_OEM_GROUP, lastNetFunction); 49 } 50 51 void RegisterWithRouter(Number oen, ipmi_cmd_t cmd, Handler cb) 52 { 53 ActivateRouter(); 54 singletonUnderTest->registerHandler(oen, cmd, cb); 55 } 56 57 uint8_t msgPlain[] = {0x56, 0x34, 0x12}; 58 uint8_t replyPlain[] = {0x56, 0x34, 0x12, 0x31, 0x41}; 59 uint8_t msgPlus2[] = {0x67, 0x45, 0x23, 0x10, 0x20}; 60 uint8_t msgBadOen[] = {0x57, 0x34, 0x12}; 61 62 void RegisterTwoWays(ipmi_cmd_t* nextCmd) 63 { 64 Handler f = [](ipmi_cmd_t cmd, const uint8_t* reqBuf, uint8_t* replyBuf, 65 size_t* dataLen) { 66 // Check inputs 67 EXPECT_EQ(0x78, cmd); 68 EXPECT_EQ(0, *dataLen); // Excludes OEN 69 70 // Generate reply. 71 *dataLen = 2; 72 std::memcpy(replyBuf, replyPlain + 3, *dataLen); 73 return 0; 74 }; 75 RegisterWithRouter(0x123456, 0x78, f); 76 77 *nextCmd = IPMI_CMD_WILDCARD; 78 Handler g = [nextCmd](ipmi_cmd_t cmd, const uint8_t* reqBuf, 79 uint8_t* replyBuf, size_t* dataLen) { 80 // Check inputs 81 EXPECT_EQ(*nextCmd, cmd); 82 EXPECT_EQ(2, *dataLen); // Excludes OEN 83 if (2 != *dataLen) 84 { 85 return 0xE0; 86 } 87 EXPECT_EQ(msgPlus2[3], reqBuf[0]); 88 EXPECT_EQ(msgPlus2[4], reqBuf[1]); 89 90 // Generate reply. 91 *dataLen = 0; 92 return 0; 93 }; 94 RegisterWithRouter(0x234567, IPMI_CMD_WILDCARD, g); 95 } 96 } // namespace 97 98 TEST(OemRouterTest, MakeRouterProducesConsistentSingleton) 99 { 100 MakeRouter(); 101 } 102 103 TEST(OemRouterTest, ActivateRouterSetsLastNetToOEMGROUP) 104 { 105 lastNetFunction = 0; 106 ActivateRouter(); 107 } 108 109 TEST(OemRouterTest, VerifiesSpecificCommandMatches) 110 { 111 ipmi_cmd_t cmd; 112 uint8_t reply[256]; 113 size_t dataLen; 114 115 RegisterTwoWays(&cmd); 116 117 dataLen = 3; 118 EXPECT_EQ(0, wildHandler(NETFUN_OEM_GROUP, 0x78, msgPlain, reply, &dataLen, 119 nullptr)); 120 EXPECT_EQ(5, dataLen); 121 EXPECT_EQ(replyPlain[0], reply[0]); 122 EXPECT_EQ(replyPlain[1], reply[1]); 123 EXPECT_EQ(replyPlain[2], reply[2]); 124 EXPECT_EQ(replyPlain[3], reply[3]); 125 EXPECT_EQ(replyPlain[4], reply[4]); 126 } 127 128 TEST(OemRouterTest, WildCardMatchesTwoRandomCodes) 129 { 130 ipmi_cmd_t cmd; 131 uint8_t reply[256]; 132 size_t dataLen; 133 134 RegisterTwoWays(&cmd); 135 136 // Check two random command codes. 137 dataLen = 5; 138 cmd = 0x89; 139 EXPECT_EQ(0, wildHandler(NETFUN_OEM_GROUP, cmd, msgPlus2, reply, &dataLen, 140 nullptr)); 141 EXPECT_EQ(3, dataLen); 142 143 dataLen = 5; 144 cmd = 0x67; 145 EXPECT_EQ(0, wildHandler(NETFUN_OEM_GROUP, cmd, msgPlus2, reply, &dataLen, 146 nullptr)); 147 EXPECT_EQ(3, dataLen); 148 } 149 150 TEST(OemRouterTest, CommandsAreRejectedIfInvalid) 151 { 152 ipmi_cmd_t cmd; 153 uint8_t reply[256]; 154 size_t dataLen; 155 156 RegisterTwoWays(&cmd); 157 158 // Message too short to include whole OEN? 159 dataLen = 2; 160 EXPECT_EQ(IPMI_CC_REQ_DATA_LEN_INVALID, 161 wildHandler(NETFUN_OEM_GROUP, 0x78, msgPlain, reply, &dataLen, 162 nullptr)); 163 164 // Wrong specific command? 165 dataLen = 3; 166 EXPECT_EQ(IPMI_CC_INVALID, wildHandler(NETFUN_OEM_GROUP, 0x89, msgPlain, 167 reply, &dataLen, nullptr)); 168 169 // Wrong OEN? 170 dataLen = 3; 171 EXPECT_EQ(IPMI_CC_INVALID, wildHandler(NETFUN_OEM_GROUP, 0x78, msgBadOen, 172 reply, &dataLen, nullptr)); 173 } 174 175 } // namespace oem 176