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