1 #include <ipmid/api.h>
2
3 #include <include/ipmid/api-types.hpp>
4 #include <ipmid/oemrouter.hpp>
5
6 #include <cstring>
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.
ipmi_register_callback(ipmi_netfn_t netfn,ipmi_cmd_t cmd,ipmi_context_t context,ipmid_callback_t cb,ipmi_cmd_privilege_t priv)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::cmdWildcard, 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 {
MakeRouter()35 void MakeRouter()
36 {
37 if (!singletonUnderTest)
38 {
39 singletonUnderTest = mutableRouter();
40 }
41 ASSERT_EQ(singletonUnderTest, mutableRouter());
42 }
43
ActivateRouter()44 void ActivateRouter()
45 {
46 MakeRouter();
47 singletonUnderTest->activate();
48 ASSERT_EQ(NETFUN_OEM_GROUP, lastNetFunction);
49 }
50
RegisterWithRouter(Number oen,ipmi_cmd_t cmd,Handler cb)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
RegisterTwoWays(ipmi_cmd_t * nextCmd)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::cmdWildcard;
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::cmdWildcard, g);
95 }
96 } // namespace
97
TEST(OemRouterTest,MakeRouterProducesConsistentSingleton)98 TEST(OemRouterTest, MakeRouterProducesConsistentSingleton)
99 {
100 MakeRouter();
101 }
102
TEST(OemRouterTest,ActivateRouterSetsLastNetToOEMGROUP)103 TEST(OemRouterTest, ActivateRouterSetsLastNetToOEMGROUP)
104 {
105 lastNetFunction = 0;
106 ActivateRouter();
107 }
108
TEST(OemRouterTest,VerifiesSpecificCommandMatches)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
TEST(OemRouterTest,WildCardMatchesTwoRandomCodes)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
TEST(OemRouterTest,CommandsAreRejectedIfInvalid)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