blob: 163b602918c74737998c7a47ab80c56a7423cf68 [file] [log] [blame]
Steve Foreman4f0d1de2021-09-20 14:06:32 -07001// Copyright 2022 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "commands.hpp"
16#include "errors.hpp"
17#include "google_accel_oob.hpp"
18#include "handler_mock.hpp"
19
20#include <ipmid/api.h>
21
22#include <gtest/gtest.h>
23
24namespace google
25{
26namespace ipmi
27{
28
29using ::testing::Return;
30
31TEST(GoogleAccelOobTest, DeviceCount_Success)
32{
33 ::testing::StrictMock<HandlerMock> h;
34
35 uint8_t reqBuf[1]; // Could be 0, but zero-length arrays are an extension
36
37 struct Reply
38 {
39 uint32_t count;
40 } __attribute__((packed));
41
42 constexpr uint32_t kTestDeviceCount = 2;
43
44 EXPECT_CALL(h, accelOobDeviceCount()).WillOnce(Return(kTestDeviceCount));
45
46 Resp r = accelOobDeviceCount(reqBuf, &h);
47
48 const auto response = std::get<0>(r);
49 EXPECT_EQ(response, IPMI_CC_OK);
50
51 const auto payload = std::get<1>(r);
52 ASSERT_EQ(payload.has_value(), true);
53 const auto payload_tuple = payload.value();
54 const auto reply_cmd = std::get<0>(payload_tuple);
55 EXPECT_EQ(reply_cmd, SysAccelOobDeviceCount);
56 const auto reply_buff = std::get<1>(payload_tuple);
57 ASSERT_EQ(reply_buff.size(), sizeof(Reply));
58
59 auto* reply = reinterpret_cast<const Reply*>(reply_buff.data());
60 EXPECT_EQ(reply->count, kTestDeviceCount);
61}
62
63TEST(GoogleAccelOobTest, DeviceName_Success)
64{
65 ::testing::StrictMock<HandlerMock> h;
66
67 struct Request
68 {
69 uint32_t index;
70 } __attribute__((packed));
71
72 struct Reply
73 {
74 uint32_t index;
75 uint8_t length;
76 char name[1];
77 } __attribute__((packed));
78
79 constexpr uint32_t kTestDeviceIndex = 0;
80 const std::string kTestDeviceName("testDeviceName");
81
82 EXPECT_CALL(h, accelOobDeviceName(kTestDeviceIndex))
83 .WillOnce(Return(kTestDeviceName));
84
85 Request reqBuf{kTestDeviceIndex};
86 Resp r = accelOobDeviceName(
87 std::span(reinterpret_cast<const uint8_t*>(&reqBuf), sizeof(Request)),
88 &h);
89
90 const auto response = std::get<0>(r);
91 EXPECT_EQ(response, IPMI_CC_OK);
92
93 const auto payload = std::get<1>(r);
94 ASSERT_EQ(payload.has_value(), true);
95 const auto payload_tuple = payload.value();
96 const auto reply_cmd = std::get<0>(payload_tuple);
97 EXPECT_EQ(reply_cmd, SysAccelOobDeviceName);
98 const auto reply_buff = std::get<1>(payload_tuple);
99 ASSERT_GE(reply_buff.size(), sizeof(Reply));
100
101 auto* reply = reinterpret_cast<const Reply*>(reply_buff.data());
102 EXPECT_EQ(reply->index, kTestDeviceIndex);
103 EXPECT_EQ(reply->length, kTestDeviceName.length());
104 EXPECT_STREQ(reply->name, kTestDeviceName.c_str());
105}
106
107TEST(GoogleAccelOobTest, Read_Success)
108{
109 ::testing::StrictMock<HandlerMock> h;
110
111 constexpr char kTestDeviceName[] = "testDeviceName";
112 constexpr uint8_t kTestDeviceNameLength =
113 (sizeof(kTestDeviceName) / sizeof(*kTestDeviceName)) - 1;
114 constexpr uint8_t kTestToken = 0xAB;
115 constexpr uint64_t kTestAddress = 0;
116 constexpr uint8_t kTestReadSize = 8;
117 constexpr uint64_t kTestData = 0x12345678;
118
119 struct Request
120 {
121 uint8_t nameLength;
122 char name[kTestDeviceNameLength];
123 uint8_t token;
124 uint64_t address;
125 uint8_t num_bytes;
126 } __attribute__((packed));
127
128 struct Reply
129 {
130 uint8_t nameLength;
131 char name[kTestDeviceNameLength];
132 uint8_t token;
133 uint64_t address;
134 uint8_t num_bytes;
135 uint64_t data;
136 } __attribute__((packed));
137
138 const std::string_view kTestDeviceNameStr(kTestDeviceName,
139 kTestDeviceNameLength);
140 EXPECT_CALL(h,
141 accelOobRead(kTestDeviceNameStr, kTestAddress, kTestReadSize))
142 .WillOnce(Return(kTestData));
143
144 Request reqBuf{kTestDeviceNameLength, "", kTestToken, kTestAddress,
145 kTestReadSize};
146 memcpy(reqBuf.name, kTestDeviceName, kTestDeviceNameLength);
147 Resp r = accelOobRead(
148 std::span(reinterpret_cast<const uint8_t*>(&reqBuf), sizeof(Request)),
149 &h);
150
151 const auto response = std::get<0>(r);
152 EXPECT_EQ(response, IPMI_CC_OK);
153
154 const auto payload = std::get<1>(r);
155 ASSERT_EQ(payload.has_value(), true);
156 const auto payload_tuple = payload.value();
157 const auto reply_cmd = std::get<0>(payload_tuple);
158 EXPECT_EQ(reply_cmd, SysAccelOobRead);
159 const auto reply_buff = std::get<1>(payload_tuple);
160 ASSERT_GE(reply_buff.size(), sizeof(Reply));
161
162 auto* reply = reinterpret_cast<const Reply*>(reply_buff.data());
163 EXPECT_EQ(reply->nameLength, kTestDeviceNameLength);
164 EXPECT_EQ(std::string_view(reply->name, reply->nameLength),
165 kTestDeviceNameStr);
166 EXPECT_EQ(reply->token, kTestToken);
167 EXPECT_EQ(reply->address, kTestAddress);
168 EXPECT_EQ(reply->num_bytes, kTestReadSize);
169 EXPECT_EQ(reply->data, kTestData);
170}
171
172TEST(GoogleAccelOobTest, Write_Success)
173{
174 ::testing::StrictMock<HandlerMock> h;
175
176 constexpr char kTestDeviceName[] = "testDeviceName";
177 constexpr uint8_t kTestDeviceNameLength =
178 (sizeof(kTestDeviceName) / sizeof(*kTestDeviceName)) - 1;
179 constexpr uint8_t kTestToken = 0xAB;
180 constexpr uint64_t kTestAddress = 0;
181 constexpr uint8_t kTestWriteSize = 8;
182 constexpr uint64_t kTestData = 0x12345678;
183
184 struct Request
185 {
186 uint8_t nameLength;
187 char name[kTestDeviceNameLength];
188 uint8_t token;
189 uint64_t address;
190 uint8_t num_bytes;
191 uint64_t data;
192 } __attribute__((packed));
193
194 struct Reply
195 {
196 uint8_t nameLength;
197 char name[kTestDeviceNameLength];
198 uint8_t token;
199 uint64_t address;
200 uint8_t num_bytes;
201 uint64_t data;
202 } __attribute__((packed));
203
204 const std::string_view kTestDeviceNameStr(kTestDeviceName,
205 kTestDeviceNameLength);
206 EXPECT_CALL(h, accelOobWrite(kTestDeviceNameStr, kTestAddress,
207 kTestWriteSize, kTestData))
208 .WillOnce(Return());
209
210 Request reqBuf{kTestDeviceNameLength, "", kTestToken, kTestAddress,
211 kTestWriteSize, kTestData};
212 memcpy(reqBuf.name, kTestDeviceName, kTestDeviceNameLength);
213 Resp r = accelOobWrite(
214 std::span(reinterpret_cast<const uint8_t*>(&reqBuf), sizeof(Request)),
215 &h);
216
217 const auto response = std::get<0>(r);
218 EXPECT_EQ(response, IPMI_CC_OK);
219
220 const auto payload = std::get<1>(r);
221 ASSERT_EQ(payload.has_value(), true);
222 const auto payload_tuple = payload.value();
223 const auto reply_cmd = std::get<0>(payload_tuple);
224 EXPECT_EQ(reply_cmd, SysAccelOobWrite);
225 const auto reply_buff = std::get<1>(payload_tuple);
226 ASSERT_GE(reply_buff.size(), sizeof(Reply));
227
228 auto* reply = reinterpret_cast<const Reply*>(reply_buff.data());
229 EXPECT_EQ(reply->nameLength, kTestDeviceNameLength);
230 EXPECT_EQ(std::string_view(reply->name, reply->nameLength),
231 kTestDeviceNameStr);
232 EXPECT_EQ(reply->token, kTestToken);
233 EXPECT_EQ(reply->address, kTestAddress);
234 EXPECT_EQ(reply->num_bytes, kTestWriteSize);
235 EXPECT_EQ(reply->data, kTestData);
236}
237
238} // namespace ipmi
239} // namespace google