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.
ipmi_register_callback(ipmi_netfn_t netfn,ipmi_cmd_t cmd,ipmi_context_t context,ipmid_callback_t cb,ipmi_cmd_privilege_t priv)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 {
MakeRouter()36 void MakeRouter()
37 {
38 if (!singletonUnderTest)
39 {
40 singletonUnderTest = mutableRouter();
41 }
42 ASSERT_EQ(singletonUnderTest, mutableRouter());
43 }
44
ActivateRouter()45 void ActivateRouter()
46 {
47 MakeRouter();
48 singletonUnderTest->activate();
49 ASSERT_EQ(NETFUN_OEM_GROUP, lastNetFunction);
50 }
51
RegisterWithRouter(Number oen,ipmi_cmd_t cmd,Handler cb)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
RegisterTwoWays(ipmi_cmd_t * nextCmd)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
TEST(OemRouterTest,MakeRouterProducesConsistentSingleton)99 TEST(OemRouterTest, MakeRouterProducesConsistentSingleton)
100 {
101 MakeRouter();
102 }
103
TEST(OemRouterTest,ActivateRouterSetsLastNetToOEMGROUP)104 TEST(OemRouterTest, ActivateRouterSetsLastNetToOEMGROUP)
105 {
106 lastNetFunction = 0;
107 ActivateRouter();
108 }
109
TEST(OemRouterTest,VerifiesSpecificCommandMatches)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
TEST(OemRouterTest,WildCardMatchesTwoRandomCodes)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
TEST(OemRouterTest,CommandsAreRejectedIfInvalid)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