blob: 0114e111c4d6511440e73e6292887eb41fa9c2b7 [file] [log] [blame]
Vernon Maueryebe8e902018-12-12 09:39:22 -08001/**
2 * Copyright © 2018 Intel Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
William A. Kennington III51694c22019-04-24 01:44:44 -070016#define SD_JOURNAL_SUPPRESS_LOCATION
17
18#include <systemd/sd-journal.h>
19
Vernon Maueryebe8e902018-12-12 09:39:22 -080020#include <ipmid/api.hpp>
21#include <ipmid/message.hpp>
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050022
William A. Kennington IIIf2fd17a2019-04-24 01:53:52 -070023#include <stdexcept>
Vernon Maueryebe8e902018-12-12 09:39:22 -080024
25#include <gtest/gtest.h>
26
27TEST(Payload, InputSize)
28{
Vernon Mauery997952a2021-07-30 14:06:14 -070029 ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
Vernon Maueryebe8e902018-12-12 09:39:22 -080030 size_t input_size = i.size();
Vernon Mauery997952a2021-07-30 14:06:14 -070031 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
Vernon Maueryebe8e902018-12-12 09:39:22 -080032 ASSERT_EQ(input_size, p.size());
33}
34
35TEST(Payload, OutputSize)
36{
37 ipmi::message::Payload p;
38 ASSERT_EQ(0, p.size());
Vernon Mauery997952a2021-07-30 14:06:14 -070039 ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
Vernon Maueryebe8e902018-12-12 09:39:22 -080040 p.pack(i);
41 ASSERT_EQ(i.size(), p.size());
42 p.pack(i);
43 p.pack(i);
44 ASSERT_EQ(3 * i.size(), p.size());
45}
46
47TEST(Payload, Resize)
48{
Vernon Mauery997952a2021-07-30 14:06:14 -070049 ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
Vernon Maueryebe8e902018-12-12 09:39:22 -080050 ipmi::message::Payload p;
51 p.pack(i);
52 p.resize(16);
53 ASSERT_EQ(p.size(), 16);
54}
55
56TEST(Payload, Data)
57{
Vernon Mauery997952a2021-07-30 14:06:14 -070058 ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
Vernon Maueryebe8e902018-12-12 09:39:22 -080059 ipmi::message::Payload p;
60 p.pack(i);
61 ASSERT_NE(nullptr, p.data());
62}
63
64TEST(PayloadResponse, Append)
65{
66 std::string s("0123456789abcdef");
67 ipmi::message::Payload p;
68 p.append(s.data(), s.data() + s.size());
69 ASSERT_EQ(s.size(), p.size());
70}
71
72TEST(PayloadResponse, AppendDrain)
73{
74 std::string s("0123456789abcdef");
75 ipmi::message::Payload p;
76 bool b = true;
77 // first pack a lone bit
78 p.pack(b);
79 p.append(s.data(), s.data() + s.size());
80 // append will 'drain' first, padding the lone bit into a full byte
81 ASSERT_EQ(s.size() + 1, p.size());
82}
83
84TEST(PayloadResponse, AppendBits)
85{
86 ipmi::message::Payload p;
87 p.appendBits(3, 0b101);
88 ASSERT_EQ(p.bitStream, 0b101);
89 p.appendBits(4, 0b1100);
90 ASSERT_EQ(p.bitStream, 0b1100101);
91 p.appendBits(1, 0b1);
92 ASSERT_EQ(p.bitStream, 0);
93 ASSERT_EQ(p.bitCount, 0);
94 // appended 8 bits, should be one byte
95 ASSERT_EQ(p.size(), 1);
Vernon Mauery997952a2021-07-30 14:06:14 -070096 ipmi::SecureBuffer k1 = {0b11100101};
Vernon Maueryebe8e902018-12-12 09:39:22 -080097 ASSERT_EQ(p.raw, k1);
98 p.appendBits(7, 0b1110111);
99 // appended 7 more bits, should still be one byte
100 ASSERT_EQ(p.size(), 1);
101 p.drain();
102 // drain forces padding; should be two bytes now
103 ASSERT_EQ(p.size(), 2);
Vernon Mauery997952a2021-07-30 14:06:14 -0700104 ipmi::SecureBuffer k2 = {0b11100101, 0b01110111};
Vernon Maueryebe8e902018-12-12 09:39:22 -0800105 ASSERT_EQ(p.raw, k2);
106}
107
108TEST(PayloadResponse, Drain16Bits)
109{
110 ipmi::message::Payload p;
111 p.bitStream = 0b1011010011001111;
112 p.bitCount = 16;
113 p.drain();
114 ASSERT_EQ(p.size(), 2);
115 ASSERT_EQ(p.bitCount, 0);
116 ASSERT_EQ(p.bitStream, 0);
Vernon Mauery997952a2021-07-30 14:06:14 -0700117 ipmi::SecureBuffer k1 = {0b11001111, 0b10110100};
Vernon Maueryebe8e902018-12-12 09:39:22 -0800118 ASSERT_EQ(p.raw, k1);
119}
120
121TEST(PayloadResponse, Drain15Bits)
122{
123 ipmi::message::Payload p;
124 p.bitStream = 0b101101001100111;
125 p.bitCount = 15;
126 p.drain();
127 ASSERT_EQ(p.size(), 2);
128 ASSERT_EQ(p.bitCount, 0);
129 ASSERT_EQ(p.bitStream, 0);
Vernon Mauery997952a2021-07-30 14:06:14 -0700130 ipmi::SecureBuffer k1 = {0b1100111, 0b1011010};
Vernon Maueryebe8e902018-12-12 09:39:22 -0800131 ASSERT_EQ(p.raw, k1);
132}
133
134TEST(PayloadResponse, Drain15BitsWholeBytesOnly)
135{
136 ipmi::message::Payload p;
137 p.bitStream = 0b101101001100111;
138 p.bitCount = 15;
139 p.drain(true);
140 // only the first whole byte should have been 'drained' into p.raw
141 ASSERT_EQ(p.size(), 1);
142 ASSERT_EQ(p.bitCount, 7);
143 ASSERT_EQ(p.bitStream, 0b1011010);
Vernon Mauery997952a2021-07-30 14:06:14 -0700144 ipmi::SecureBuffer k1 = {0b1100111};
Vernon Maueryebe8e902018-12-12 09:39:22 -0800145 ASSERT_EQ(p.raw, k1);
146}
147
148TEST(PayloadRequest, Pop)
149{
Vernon Mauery997952a2021-07-30 14:06:14 -0700150 ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
151 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
Vernon Maueryebe8e902018-12-12 09:39:22 -0800152 const auto& [vb, ve] = p.pop<uint8_t>(4);
153 std::vector<uint8_t> v(vb, ve);
154 std::vector<uint8_t> k = {0xbf, 0x04, 0x86, 0x00};
155 ASSERT_EQ(v, k);
156}
157
158TEST(PayloadRequest, FillBits)
159{
Vernon Mauery997952a2021-07-30 14:06:14 -0700160 ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
161 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
Vernon Maueryebe8e902018-12-12 09:39:22 -0800162 p.fillBits(5);
163 ASSERT_FALSE(p.unpackError);
164 ASSERT_EQ(p.bitStream, 0xbf);
165 ASSERT_EQ(p.bitCount, 8);
166 // should still have 5 bits available, no change
167 p.fillBits(5);
168 ASSERT_FALSE(p.unpackError);
169 ASSERT_EQ(p.bitStream, 0xbf);
170 ASSERT_EQ(p.bitCount, 8);
171 // discard 5 bits (low order)
172 p.popBits(5);
173 // should add another byte into the stream (high order)
174 p.fillBits(5);
175 ASSERT_FALSE(p.unpackError);
176 ASSERT_EQ(p.bitStream, 0x25);
177 ASSERT_EQ(p.bitCount, 11);
178}
179
180TEST(PayloadRequest, FillBitsTooManyBits)
181{
Vernon Mauery997952a2021-07-30 14:06:14 -0700182 ipmi::SecureBuffer i = {1, 2, 3, 4, 5, 6, 7, 8, 9};
183 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
Vernon Maueryebe8e902018-12-12 09:39:22 -0800184 p.fillBits(72);
185 ASSERT_TRUE(p.unpackError);
186}
187
188TEST(PayloadRequest, FillBitsNotEnoughBytes)
189{
Vernon Mauery997952a2021-07-30 14:06:14 -0700190 ipmi::SecureBuffer i = {1, 2, 3, 4};
191 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
Vernon Maueryebe8e902018-12-12 09:39:22 -0800192 p.fillBits(48);
193 ASSERT_TRUE(p.unpackError);
194}
195
196TEST(PayloadRequest, PopBits)
197{
Vernon Mauery997952a2021-07-30 14:06:14 -0700198 ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
199 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
Vernon Maueryebe8e902018-12-12 09:39:22 -0800200 p.fillBits(4);
201 uint8_t v = p.popBits(4);
202 ASSERT_FALSE(p.unpackError);
203 ASSERT_EQ(p.bitStream, 0x0b);
204 ASSERT_EQ(p.bitCount, 4);
205 ASSERT_EQ(v, 0x0f);
206}
207
208TEST(PayloadRequest, PopBitsNoFillBits)
209{
Vernon Mauery997952a2021-07-30 14:06:14 -0700210 ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
211 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
Vernon Maueryebe8e902018-12-12 09:39:22 -0800212 p.popBits(4);
213 ASSERT_TRUE(p.unpackError);
214}
215
216TEST(PayloadRequest, DiscardBits)
217{
Vernon Mauery997952a2021-07-30 14:06:14 -0700218 ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
219 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
Vernon Maueryebe8e902018-12-12 09:39:22 -0800220 p.fillBits(5);
221 ASSERT_FALSE(p.unpackError);
222 ASSERT_EQ(p.bitStream, 0xbf);
223 ASSERT_EQ(p.bitCount, 8);
224 p.discardBits();
225 ASSERT_FALSE(p.unpackError);
226 ASSERT_EQ(p.bitStream, 0);
227 ASSERT_EQ(p.bitCount, 0);
228}
229
230TEST(PayloadRequest, FullyUnpacked)
231{
Vernon Mauery997952a2021-07-30 14:06:14 -0700232 ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
233 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
Vernon Maueryebe8e902018-12-12 09:39:22 -0800234 uint32_t v1;
235 p.unpack(v1);
236 // still one remaining byte
237 ASSERT_FALSE(p.fullyUnpacked());
238 p.fillBits(3);
239 p.popBits(3);
240 // still five remaining bits
241 ASSERT_FALSE(p.fullyUnpacked());
242 p.fillBits(5);
243 p.popBits(5);
244 // fully unpacked, should be no errors
245 ASSERT_TRUE(p.fullyUnpacked());
246 p.fillBits(4);
247 // fullyUnpacked fails because an attempt to unpack too many bytes
248 ASSERT_FALSE(p.fullyUnpacked());
249}
250
251TEST(PayloadRequest, ResetInternal)
252{
Vernon Mauery997952a2021-07-30 14:06:14 -0700253 ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
254 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
Vernon Maueryebe8e902018-12-12 09:39:22 -0800255 p.fillBits(4);
256 p.unpackError = true;
257 p.reset();
258 ASSERT_EQ(p.rawIndex, 0);
259 ASSERT_EQ(p.bitStream, 0);
260 ASSERT_EQ(p.bitCount, 0);
261 ASSERT_FALSE(p.unpackError);
262}
263
264TEST(PayloadRequest, ResetUsage)
265{
266 // Payload.reset is used to rewind the unpacking to the initial
267 // state. This is needed so that OEM commands can unpack the group
268 // number or the IANA to determine which handler needs to be called
Vernon Mauery997952a2021-07-30 14:06:14 -0700269 ipmi::SecureBuffer i = {0x04, 0x86};
270 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
Vernon Maueryebe8e902018-12-12 09:39:22 -0800271 uint8_t v1;
272 // check that the number of bytes matches
273 ASSERT_EQ(p.unpack(v1), 0);
274 // check that the payload was not fully unpacked
275 ASSERT_FALSE(p.fullyUnpacked());
276 uint8_t k1 = 0x04;
277 // check that the bytes were correctly unpacked (LSB first)
278 ASSERT_EQ(v1, k1);
279 // do a reset on the payload
280 p.reset();
281 // unpack a uint16
282 uint16_t v2;
283 // check that the number of bytes matches
284 ASSERT_EQ(p.unpack(v2), 0);
285 // check that the payload was fully unpacked
286 ASSERT_TRUE(p.fullyUnpacked());
287 uint16_t k2 = 0x8604;
288 // check that the bytes were correctly unpacked (LSB first)
289 ASSERT_EQ(v2, k2);
290}
291
292TEST(PayloadRequest, PartialPayload)
293{
Vernon Mauery997952a2021-07-30 14:06:14 -0700294 ipmi::SecureBuffer i = {0xbf, 0x04, 0x86, 0x00, 0x02};
295 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
Vernon Maueryebe8e902018-12-12 09:39:22 -0800296 uint8_t v1;
297 ipmi::message::Payload localPayload;
298 // check that the number of bytes matches
299 ASSERT_EQ(p.unpack(v1, localPayload), 0);
300 // check that the payload was partially unpacked and not in error
301 ASSERT_FALSE(p.fullyUnpacked());
302 ASSERT_FALSE(p.unpackError);
303 // check that the 'extracted' payload is not fully unpacked
304 ASSERT_FALSE(localPayload.fullyUnpacked());
305 uint8_t k1 = 0xbf;
306 // check that the bytes were correctly unpacked (LSB first)
307 ASSERT_EQ(v1, k1);
308 uint32_t v2;
309 // unpack using the 'extracted' payload
310 ASSERT_EQ(localPayload.unpack(v2), 0);
311 ASSERT_TRUE(localPayload.fullyUnpacked());
312 uint32_t k2 = 0x02008604;
313 ASSERT_EQ(v2, k2);
314}
William A. Kennington III51694c22019-04-24 01:44:44 -0700315
316std::vector<std::string> logs;
317
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500318extern "C"
William A. Kennington III51694c22019-04-24 01:44:44 -0700319{
Patrick Williams369824e2023-10-20 11:18:23 -0500320int sd_journal_send(const char* format, ...)
321{
322 logs.push_back(format);
323 return 0;
324}
William A. Kennington III51694c22019-04-24 01:44:44 -0700325
Patrick Williams369824e2023-10-20 11:18:23 -0500326int sd_journal_send_with_location(const char* /*file*/, const char* /*line*/,
327 const char* /*func*/, const char* format, ...)
328{
329 logs.push_back(format);
330 return 0;
331}
William A. Kennington III51694c22019-04-24 01:44:44 -0700332}
333
334class PayloadLogging : public testing::Test
335{
336 public:
337 void SetUp()
338 {
339 logs.clear();
340 }
341};
342
343TEST_F(PayloadLogging, TrailingOk)
344{
345 {
346 ipmi::message::Payload p({1, 2});
347 }
348 EXPECT_EQ(logs.size(), 0);
349}
350
351TEST_F(PayloadLogging, EnforcingUnchecked)
352{
353 {
354 ipmi::message::Payload p({1, 2});
355 p.trailingOk = false;
356 }
357 EXPECT_EQ(logs.size(), 1);
358}
359
360TEST_F(PayloadLogging, EnforcingUncheckedUnpacked)
361{
362 {
363 ipmi::message::Payload p({1, 2});
364 p.trailingOk = false;
365 uint8_t out;
366 p.unpack(out, out);
367 }
368 EXPECT_EQ(logs.size(), 1);
369}
370
371TEST_F(PayloadLogging, EnforcingUncheckedError)
372{
373 {
374 ipmi::message::Payload p({1, 2});
375 p.trailingOk = false;
376 uint32_t out;
377 p.unpack(out);
378 }
379 EXPECT_EQ(logs.size(), 0);
380}
381
382TEST_F(PayloadLogging, EnforcingChecked)
383{
384 {
385 ipmi::message::Payload p({1, 2});
386 p.trailingOk = false;
387 EXPECT_FALSE(p.fullyUnpacked());
388 }
389 EXPECT_EQ(logs.size(), 0);
390}
391
392TEST_F(PayloadLogging, EnforcingCheckedUnpacked)
393{
394 {
395 ipmi::message::Payload p({1, 2});
396 p.trailingOk = false;
397 uint8_t out;
398 p.unpack(out, out);
399 EXPECT_TRUE(p.fullyUnpacked());
400 }
401 EXPECT_EQ(logs.size(), 0);
402}
403
404TEST_F(PayloadLogging, EnforcingUnpackPayload)
405{
406 {
407 ipmi::message::Payload p;
408 {
409 ipmi::message::Payload q({1, 2});
410 q.trailingOk = false;
411 q.unpack(p);
412 }
413 EXPECT_EQ(logs.size(), 0);
414 }
415 EXPECT_EQ(logs.size(), 1);
416}
417
418TEST_F(PayloadLogging, EnforcingMove)
419{
420 {
421 ipmi::message::Payload p;
422 {
423 ipmi::message::Payload q({1, 2});
424 q.trailingOk = false;
425 p = std::move(q);
426 }
427 EXPECT_EQ(logs.size(), 0);
428 }
429 EXPECT_EQ(logs.size(), 1);
430}
William A. Kennington IIIf2fd17a2019-04-24 01:53:52 -0700431
432TEST_F(PayloadLogging, EnforcingException)
433{
434 try
435 {
436 ipmi::message::Payload p({1, 2});
437 p.trailingOk = false;
438 throw std::runtime_error("test");
439 }
440 catch (...)
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500441 {}
William A. Kennington IIIf2fd17a2019-04-24 01:53:52 -0700442 EXPECT_EQ(logs.size(), 0);
443}