1 /**
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 */
16 #include <ipmid/api.hpp>
17 #include <ipmid/message.hpp>
18
19 #include <gtest/gtest.h>
20
TEST(Uints,Uint8)21 TEST(Uints, Uint8)
22 {
23 ipmi::SecureBuffer i = {0x04};
24 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
25 uint8_t v;
26 // check that the number of bytes matches
27 ASSERT_EQ(p.unpack(v), 0);
28 // check that the payload was fully unpacked
29 ASSERT_TRUE(p.fullyUnpacked());
30 uint8_t k = 0x04;
31 // check that the bytes were correctly unpacked (LSB first)
32 ASSERT_EQ(v, k);
33 }
34
TEST(Uints,Uint8TooManyBytes)35 TEST(Uints, Uint8TooManyBytes)
36 {
37 ipmi::SecureBuffer i = {0x04, 0x86};
38 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
39 uint8_t v;
40 // check that the number of bytes matches
41 ASSERT_EQ(p.unpack(v), 0);
42 // check that the payload was not fully unpacked
43 ASSERT_FALSE(p.fullyUnpacked());
44 uint8_t k = 0x04;
45 // check that the bytes were correctly unpacked (LSB first)
46 ASSERT_EQ(v, k);
47 }
48
TEST(Uints,Uint8InsufficientBytes)49 TEST(Uints, Uint8InsufficientBytes)
50 {
51 ipmi::SecureBuffer i = {};
52 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
53 uint8_t v = 0;
54 // check that the number of bytes matches
55 ASSERT_NE(p.unpack(v), 0);
56 // check that the payload was not fully unpacked (comprehends unpack errors)
57 ASSERT_FALSE(p.fullyUnpacked());
58 // check that v is zero
59 ASSERT_EQ(v, 0);
60 }
61
TEST(Uints,Uint16)62 TEST(Uints, Uint16)
63 {
64 ipmi::SecureBuffer i = {0x04, 0x86};
65 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
66 uint16_t v;
67 // check that the number of bytes matches
68 ASSERT_EQ(p.unpack(v), 0);
69 // check that the payload was fully unpacked
70 ASSERT_TRUE(p.fullyUnpacked());
71 uint16_t k = 0x8604;
72 // check that the bytes were correctly unpacked (LSB first)
73 ASSERT_EQ(v, k);
74 }
75
TEST(Uints,Uint16TooManyBytes)76 TEST(Uints, Uint16TooManyBytes)
77 {
78 ipmi::SecureBuffer i = {0x04, 0x86, 0x00};
79 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
80 uint16_t v;
81 // check that the number of bytes matches
82 ASSERT_EQ(p.unpack(v), 0);
83 // check that the payload was not fully unpacked
84 ASSERT_FALSE(p.fullyUnpacked());
85 uint16_t k = 0x8604;
86 // check that the bytes were correctly unpacked (LSB first)
87 ASSERT_EQ(v, k);
88 }
89
TEST(Uints,Uint16InsufficientBytes)90 TEST(Uints, Uint16InsufficientBytes)
91 {
92 ipmi::SecureBuffer i = {0x04};
93 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
94 uint16_t v = 0;
95 // check that the number of bytes matches
96 ASSERT_NE(p.unpack(v), 0);
97 // check that the payload was not fully unpacked (comprehends unpack errors)
98 ASSERT_FALSE(p.fullyUnpacked());
99 // check that v is zero
100 ASSERT_EQ(v, 0);
101 }
102
TEST(Uints,Uint32)103 TEST(Uints, Uint32)
104 {
105 ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02};
106 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
107 uint32_t v;
108 // check that the number of bytes matches
109 ASSERT_EQ(p.unpack(v), 0);
110 // check that the payload was fully unpacked
111 ASSERT_TRUE(p.fullyUnpacked());
112 uint32_t k = 0x02008604;
113 // check that the bytes were correctly unpacked (LSB first)
114 ASSERT_EQ(v, k);
115 }
116
TEST(Uints,Uint32TooManyBytes)117 TEST(Uints, Uint32TooManyBytes)
118 {
119 ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02, 0x44};
120 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
121 uint32_t v;
122 // check that the number of bytes matches
123 ASSERT_EQ(p.unpack(v), 0);
124 // check that the payload was not fully unpacked
125 ASSERT_FALSE(p.fullyUnpacked());
126 uint32_t k = 0x02008604;
127 // check that the bytes were correctly unpacked (LSB first)
128 ASSERT_EQ(v, k);
129 }
130
TEST(Uints,Uint32InsufficientBytes)131 TEST(Uints, Uint32InsufficientBytes)
132 {
133 ipmi::SecureBuffer i = {0x04, 0x86, 0x00};
134 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
135 uint32_t v = 0;
136 // check that the number of bytes matches
137 ASSERT_NE(p.unpack(v), 0);
138 // check that the payload was not fully unpacked (comprehends unpack errors)
139 ASSERT_FALSE(p.fullyUnpacked());
140 // check that v is zero
141 ASSERT_EQ(v, 0);
142 }
143
TEST(Uints,Uint64)144 TEST(Uints, Uint64)
145 {
146 ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02, 0x44, 0x33, 0x22, 0x11};
147 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
148 uint64_t v;
149 // check that the number of bytes matches
150 ASSERT_EQ(p.unpack(v), 0);
151 // check that the payload was fully unpacked
152 ASSERT_TRUE(p.fullyUnpacked());
153 uint64_t k = 0x1122334402008604ull;
154 // check that the bytes were correctly unpacked (LSB first)
155 ASSERT_EQ(v, k);
156 }
157
TEST(Uints,Uint64TooManyBytes)158 TEST(Uints, Uint64TooManyBytes)
159 {
160 ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02, 0x44,
161 0x33, 0x22, 0x11, 0x55};
162 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
163 uint64_t v;
164 // check that the number of bytes matches
165 ASSERT_EQ(p.unpack(v), 0);
166 // check that the payload was not fully unpacked
167 ASSERT_FALSE(p.fullyUnpacked());
168 uint64_t k = 0x1122334402008604ull;
169 // check that the bytes were correctly unpacked (LSB first)
170 ASSERT_EQ(v, k);
171 }
172
TEST(Uints,Uint64InsufficientBytes)173 TEST(Uints, Uint64InsufficientBytes)
174 {
175 ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02, 0x44, 0x33, 0x22};
176 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
177 uint64_t v = 0;
178 // check that the number of bytes matches
179 ASSERT_NE(p.unpack(v), 0);
180 // check that the payload was not fully unpacked (comprehends unpack errors)
181 ASSERT_FALSE(p.fullyUnpacked());
182 // check that v is zero
183 ASSERT_EQ(v, 0);
184 }
185
TEST(Uints,Uint24)186 TEST(Uints, Uint24)
187 {
188 ipmi::SecureBuffer i = {0x58, 0x23, 0x11};
189 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
190 uint24_t v;
191 // check that the number of bytes matches
192 ASSERT_EQ(p.unpack(v), 0);
193 // check that the payload was fully unpacked
194 ASSERT_TRUE(p.fullyUnpacked());
195 uint24_t k = 0x112358;
196 // check that the bytes were correctly unpacked (LSB first)
197 ASSERT_EQ(v, k);
198 }
199
TEST(FixedInts,Uint24TooManyBytes)200 TEST(FixedInts, Uint24TooManyBytes)
201 {
202 ipmi::SecureBuffer i = {0x58, 0x23, 0x11, 0x00};
203 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
204 uint24_t v;
205 // check that the number of bytes matches
206 ASSERT_EQ(p.unpack(v), 0);
207 // check that the payload was not fully unpacked
208 ASSERT_FALSE(p.fullyUnpacked());
209 uint24_t k = 0x112358;
210 // check that the bytes were correctly unpacked (LSB first)
211 ASSERT_EQ(v, k);
212 }
213
TEST(FixedInts,Uint24InsufficientBytes)214 TEST(FixedInts, Uint24InsufficientBytes)
215 {
216 ipmi::SecureBuffer i = {0x58, 0x23};
217 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
218 uint24_t v = 0;
219 // check that the number of bytes matches
220 ASSERT_NE(p.unpack(v), 0);
221 // check that the payload was not fully unpacked (comprehends unpack errors)
222 ASSERT_FALSE(p.fullyUnpacked());
223 // check that v is zero
224 ASSERT_EQ(v, 0);
225 }
226
TEST(FixedInts,Uint3Uint5)227 TEST(FixedInts, Uint3Uint5)
228 {
229 // individual bytes are unpacked low-order-bits first
230 // v1 will use [2:0], v2 will use [7:3]
231 ipmi::SecureBuffer i = {0xc9};
232 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
233 uint3_t v1;
234 uint5_t v2;
235 // check that the number of bytes matches
236 ASSERT_EQ(p.unpack(v1, v2), 0);
237 // check that the payload was fully unpacked
238 ASSERT_TRUE(p.fullyUnpacked());
239 uint3_t k1 = 0x1;
240 uint5_t k2 = 0x19;
241 // check that the bytes were correctly unpacked (LSB first)
242 ASSERT_EQ(v1, k1);
243 ASSERT_EQ(v2, k2);
244 }
245
TEST(FixedInts,Uint3Uint4TooManyBits)246 TEST(FixedInts, Uint3Uint4TooManyBits)
247 {
248 // high order bit should not get unpacked
249 ipmi::SecureBuffer i = {0xc9};
250 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
251 uint3_t v1;
252 uint4_t v2;
253 // check that the number of bytes matches
254 ASSERT_EQ(p.unpack(v1, v2), 0);
255 // check that the payload was not fully unpacked
256 ASSERT_FALSE(p.fullyUnpacked());
257 uint3_t k1 = 0x1;
258 uint4_t k2 = 0x9;
259 // check that the bytes were correctly unpacked (LSB first)
260 ASSERT_EQ(v1, k1);
261 ASSERT_EQ(v2, k2);
262 }
263
TEST(FixedInts,Uint3Uint6InsufficientBits)264 TEST(FixedInts, Uint3Uint6InsufficientBits)
265 {
266 // insufficient bits to unpack v2
267 ipmi::SecureBuffer i = {0xc9};
268 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
269 uint3_t v1;
270 uint6_t v2;
271 // check that the number of bytes matches
272 ASSERT_NE(p.unpack(v1, v2), 0);
273 // check that the payload was not fully unpacked (comprehends unpack errors)
274 ASSERT_FALSE(p.fullyUnpacked());
275 uint3_t k1 = 0x1;
276 // check that the bytes were correctly unpacked (LSB first)
277 ASSERT_EQ(v1, k1);
278 // check that v2 is zero
279 ASSERT_EQ(v2, 0);
280 }
281
TEST(Bools,Boolx8)282 TEST(Bools, Boolx8)
283 {
284 // individual bytes are unpacked low-order-bits first
285 // [v8, v7, v6, v5, v4, v3, v2, v1]
286 ipmi::SecureBuffer i = {0xc9};
287 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
288 bool v8, v7, v6, v5;
289 bool v4, v3, v2, v1;
290 // check that the number of bytes matches
291 ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5, v6, v7, v8), 0);
292 // check that the payload was fully unpacked
293 ASSERT_TRUE(p.fullyUnpacked());
294 // check that the bytes were correctly unpacked (LSB first)
295 bool k8 = true, k7 = true, k6 = false, k5 = false;
296 bool k4 = true, k3 = false, k2 = false, k1 = true;
297 ASSERT_EQ(v1, k1);
298 ASSERT_EQ(v2, k2);
299 ASSERT_EQ(v3, k3);
300 ASSERT_EQ(v4, k4);
301 ASSERT_EQ(v5, k5);
302 ASSERT_EQ(v6, k6);
303 ASSERT_EQ(v7, k7);
304 ASSERT_EQ(v8, k8);
305 }
306
TEST(Bools,Boolx8TooManyBits)307 TEST(Bools, Boolx8TooManyBits)
308 {
309 // high order bit should not get unpacked
310 // individual bytes are unpacked low-order-bits first
311 // [v7, v6, v5, v4, v3, v2, v1]
312 ipmi::SecureBuffer i = {0xc9};
313 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
314 bool v7, v6, v5;
315 bool v4, v3, v2, v1;
316 // check that the number of bytes matches
317 ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5, v6, v7), 0);
318 // check that the payload was not fully unpacked
319 ASSERT_FALSE(p.fullyUnpacked());
320 // check that the bytes were correctly unpacked (LSB first)
321 bool k7 = true, k6 = false, k5 = false;
322 bool k4 = true, k3 = false, k2 = false, k1 = true;
323 ASSERT_EQ(v1, k1);
324 ASSERT_EQ(v2, k2);
325 ASSERT_EQ(v3, k3);
326 ASSERT_EQ(v4, k4);
327 ASSERT_EQ(v5, k5);
328 ASSERT_EQ(v6, k6);
329 ASSERT_EQ(v7, k7);
330 }
331
TEST(Bools,Boolx8InsufficientBits)332 TEST(Bools, Boolx8InsufficientBits)
333 {
334 // individual bytes are unpacked low-order-bits first
335 // [v8, v7, v6, v5, v4, v3, v2, v1]
336 ipmi::SecureBuffer i = {0xc9};
337 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
338 bool v9;
339 bool v8, v7, v6, v5;
340 bool v4, v3, v2, v1;
341 // check that the number of bytes matches
342 ASSERT_NE(p.unpack(v1, v2, v3, v4, v5, v6, v7, v8, v9), 0);
343 // check that the payload was not fully unpacked (comprehends unpack errors)
344 ASSERT_FALSE(p.fullyUnpacked());
345 // check that the bytes were correctly unpacked (LSB first)
346 bool k8 = true, k7 = true, k6 = false, k5 = false;
347 bool k4 = true, k3 = false, k2 = false, k1 = true;
348 ASSERT_EQ(v1, k1);
349 ASSERT_EQ(v2, k2);
350 ASSERT_EQ(v3, k3);
351 ASSERT_EQ(v4, k4);
352 ASSERT_EQ(v5, k5);
353 ASSERT_EQ(v6, k6);
354 ASSERT_EQ(v7, k7);
355 ASSERT_EQ(v8, k8);
356 }
357
TEST(Bitsets,Bitset8)358 TEST(Bitsets, Bitset8)
359 {
360 // individual bytes are unpacked low-order-bits first
361 // a bitset for 8 bits fills the full byte
362 ipmi::SecureBuffer i = {0xc9};
363 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
364 std::bitset<8> v;
365 // check that the number of bytes matches
366 ASSERT_EQ(p.unpack(v), 0);
367 // check that the payload was fully unpacked
368 ASSERT_TRUE(p.fullyUnpacked());
369 std::bitset<8> k(0xc9);
370 // check that the bytes were correctly unpacked (LSB first)
371 ASSERT_EQ(v, k);
372 }
373
TEST(Bitsets,Bitset7TooManyBits)374 TEST(Bitsets, Bitset7TooManyBits)
375 {
376 // individual bytes are unpacked low-order-bits first
377 // a bitset for 8 bits fills the full byte
378 ipmi::SecureBuffer i = {0xc9};
379 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
380 std::bitset<7> v;
381 // check that the number of bytes matches
382 ASSERT_EQ(p.unpack(v), 0);
383 // check that the payload was not fully unpacked
384 ASSERT_FALSE(p.fullyUnpacked());
385 std::bitset<7> k(0x49);
386 // check that the bytes were correctly unpacked (LSB first)
387 ASSERT_EQ(v, k);
388 }
389
TEST(Bitsets,Bitset9InsufficientBits)390 TEST(Bitsets, Bitset9InsufficientBits)
391 {
392 // individual bytes are unpacked low-order-bits first
393 // a bitset for 8 bits fills the full byte
394 ipmi::SecureBuffer i = {0xc9};
395 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
396 std::bitset<9> v;
397 // check that the number of bytes matches
398 ASSERT_NE(p.unpack(v), 0);
399 // check that the payload was not fully unpacked (comprehends unpack errors)
400 ASSERT_FALSE(p.fullyUnpacked());
401 std::bitset<9> k(0);
402 // check that the bytes were correctly unpacked (LSB first)
403 ASSERT_EQ(v, k);
404 }
405
TEST(Bitsets,Bitset3Bitset5)406 TEST(Bitsets, Bitset3Bitset5)
407 {
408 // individual bytes are unpacked low-order-bits first
409 // v1 will use [2:0], v2 will use [7:3]
410 ipmi::SecureBuffer i = {0xc9};
411 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
412 std::bitset<3> v1;
413 std::bitset<5> v2;
414 // check that the number of bytes matches
415 ASSERT_EQ(p.unpack(v1, v2), 0);
416 // check that the payload was fully unpacked
417 ASSERT_TRUE(p.fullyUnpacked());
418 std::bitset<3> k1(0x1);
419 std::bitset<5> k2(0x19);
420 // check that the bytes were correctly unpacked (LSB first)
421 ASSERT_EQ(v1, k1);
422 ASSERT_EQ(v2, k2);
423 }
424
TEST(Bitsets,Bitset3Bitset4TooManyBits)425 TEST(Bitsets, Bitset3Bitset4TooManyBits)
426 {
427 // high order bit should not get unpacked
428 ipmi::SecureBuffer i = {0xc9};
429 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
430 std::bitset<3> v1;
431 std::bitset<4> v2;
432 // check that the number of bytes matches
433 ASSERT_EQ(p.unpack(v1, v2), 0);
434 // check that the payload was not fully unpacked
435 ASSERT_FALSE(p.fullyUnpacked());
436 std::bitset<3> k1 = 0x1;
437 std::bitset<4> k2 = 0x9;
438 // check that the bytes were correctly unpacked (LSB first)
439 ASSERT_EQ(v1, k1);
440 ASSERT_EQ(v2, k2);
441 }
442
TEST(Bitsets,Bitset3Bitset6InsufficientBits)443 TEST(Bitsets, Bitset3Bitset6InsufficientBits)
444 {
445 // insufficient bits to unpack v2
446 ipmi::SecureBuffer i = {0xc9};
447 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
448 std::bitset<3> v1;
449 std::bitset<6> v2;
450 // check that the number of bytes matches
451 ASSERT_NE(p.unpack(v1, v2), 0);
452 // check that the payload was not fully unpacked (comprehends unpack errors)
453 ASSERT_FALSE(p.fullyUnpacked());
454 std::bitset<3> k1 = 0x1;
455 // check that the bytes were correctly unpacked (LSB first)
456 ASSERT_EQ(v1, k1);
457 // check that v2 is zero
458 ASSERT_EQ(v2, 0);
459 }
460
TEST(Bitsets,Bitset32)461 TEST(Bitsets, Bitset32)
462 {
463 // individual bytes are unpacked low-order-bits first
464 // v1 will use 4 bytes, but in LSByte first order
465 // v1[7:0] v1[15:9] v1[23:16] v1[31:24]
466 ipmi::SecureBuffer i = {0xb4, 0x86, 0x91, 0xc2};
467 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
468 std::bitset<32> v;
469 // check that the number of bytes matches
470 ASSERT_EQ(p.unpack(v), 0);
471 // check that the payload was fully unpacked
472 ASSERT_TRUE(p.fullyUnpacked());
473 std::bitset<32> k(0xc29186b4);
474 // check that the bytes were correctly unpacked (LSB first)
475 ASSERT_EQ(v, k);
476 }
477
TEST(Bitsets,Bitset31TooManyBits)478 TEST(Bitsets, Bitset31TooManyBits)
479 {
480 // high order bit should not get unpacked
481 ipmi::SecureBuffer i = {0xb4, 0x86, 0x91, 0xc2};
482 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
483 std::bitset<31> v;
484 // check that the number of bytes matches
485 ASSERT_EQ(p.unpack(v), 0);
486 // check that the payload was not fully unpacked
487 ASSERT_FALSE(p.fullyUnpacked());
488 std::bitset<31> k(0x429186b4);
489 // check that the bytes were correctly unpacked (LSB first)
490 ASSERT_EQ(v, k);
491 }
492
TEST(Bitsets,Bitset33InsufficientBits)493 TEST(Bitsets, Bitset33InsufficientBits)
494 {
495 // insufficient bits to unpack v2
496 ipmi::SecureBuffer i = {0xb4, 0x86, 0x91, 0xc2};
497 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
498 std::bitset<33> v;
499 // check that the number of bytes matches
500 ASSERT_NE(p.unpack(v), 0);
501 // check that the payload was not fully unpacked (comprehends unpack errors)
502 ASSERT_FALSE(p.fullyUnpacked());
503 // check that v is zero
504 ASSERT_EQ(v, 0);
505 }
506
TEST(Arrays,Array4xUint8)507 TEST(Arrays, Array4xUint8)
508 {
509 // an array of bytes will be read verbatim, low-order element first
510 ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04};
511 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
512 std::array<uint8_t, 4> v;
513 // check that the number of bytes matches
514 ASSERT_EQ(p.unpack(v), 0);
515 // check that the payload was fully unpacked
516 ASSERT_TRUE(p.fullyUnpacked());
517 std::array<uint8_t, 4> k = {{0x02, 0x00, 0x86, 0x04}};
518 // check that the bytes were correctly unpacked (in byte order)
519 ASSERT_EQ(v, k);
520 }
521
TEST(Arrays,Array4xUint8TooManyBytes)522 TEST(Arrays, Array4xUint8TooManyBytes)
523 {
524 // last byte should not get unpacked
525 // an array of bytes will be read verbatim, low-order element first
526 ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04, 0x22};
527 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
528 std::array<uint8_t, 4> v;
529 // check that the number of bytes matches
530 ASSERT_EQ(p.unpack(v), 0);
531 // check that the payload was not fully unpacked
532 ASSERT_FALSE(p.fullyUnpacked());
533 std::array<uint8_t, 4> k = {{0x02, 0x00, 0x86, 0x04}};
534 // check that the bytes were correctly unpacked (in byte order)
535 ASSERT_EQ(v, k);
536 }
537
TEST(Arrays,Array4xUint8InsufficientBytes)538 TEST(Arrays, Array4xUint8InsufficientBytes)
539 {
540 // last byte should not get unpacked
541 // an array of bytes will be read verbatim, low-order element first
542 ipmi::SecureBuffer i = {0x02, 0x00, 0x86};
543 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
544 std::array<uint8_t, 4> v;
545 // check that the number of bytes matches
546 ASSERT_NE(p.unpack(v), 0);
547 // check that the payload was not fully unpacked
548 ASSERT_FALSE(p.fullyUnpacked());
549 // arrays of uint8_t will be unpacked all at once
550 // so nothing will get unpacked
551 std::array<uint8_t, 4> k = {{0, 0, 0, 0}};
552 // check that the bytes were correctly unpacked (in byte order)
553 ASSERT_EQ(v, k);
554 }
555
TEST(Arrays,Array4xUint32)556 TEST(Arrays, Array4xUint32)
557 {
558 // an array of multi-byte values will be unpacked in order low-order
559 // element first, each multi-byte element in LSByte order
560 // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
561 // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
562 // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
563 // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
564 ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
565 0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34, 0x12};
566 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
567 std::array<uint32_t, 4> v;
568 // check that the number of bytes matches
569 ASSERT_EQ(p.unpack(v), 0);
570 // check that the payload was fully unpacked
571 ASSERT_TRUE(p.fullyUnpacked());
572 std::array<uint32_t, 4> k = {
573 {0x11223344, 0x22446688, 0x33557799, 0x12345678}};
574 // check that the bytes were correctly unpacked (in byte order)
575 ASSERT_EQ(v, k);
576 }
577
TEST(Arrays,Array4xUint32TooManyBytes)578 TEST(Arrays, Array4xUint32TooManyBytes)
579 {
580 // last byte should not get unpacked
581 // an array of multi-byte values will be unpacked in order low-order
582 // element first, each multi-byte element in LSByte order
583 // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
584 // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
585 // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
586 // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
587 ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66,
588 0x44, 0x22, 0x99, 0x77, 0x55, 0x33,
589 0x78, 0x56, 0x34, 0x12, 0xaa};
590 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
591 std::array<uint32_t, 4> v;
592 // check that the number of bytes matches
593 ASSERT_EQ(p.unpack(v), 0);
594 // check that the payload was not fully unpacked
595 ASSERT_FALSE(p.fullyUnpacked());
596 std::array<uint32_t, 4> k = {
597 {0x11223344, 0x22446688, 0x33557799, 0x12345678}};
598 // check that the bytes were correctly unpacked (in byte order)
599 ASSERT_EQ(v, k);
600 }
601
TEST(Arrays,Array4xUint32InsufficientBytes)602 TEST(Arrays, Array4xUint32InsufficientBytes)
603 {
604 // last value should not get unpacked
605 // an array of multi-byte values will be unpacked in order low-order
606 // element first, each multi-byte element in LSByte order
607 // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
608 // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
609 // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
610 // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
611 ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
612 0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34};
613 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
614 std::array<uint32_t, 4> v;
615 // check that the number of bytes matches
616 ASSERT_NE(p.unpack(v), 0);
617 // check that the payload was not fully unpacked
618 ASSERT_FALSE(p.fullyUnpacked());
619 // arrays of uint32_t will be unpacked in a way that looks atomic
620 std::array<uint32_t, 4> k = {{0, 0, 0, 0}};
621 // check that the bytes were correctly unpacked (in byte order)
622 ASSERT_EQ(v, k);
623 }
624
TEST(Vectors,VectorUint32)625 TEST(Vectors, VectorUint32)
626 {
627 // a vector of multi-byte values will be unpacked in order low-order
628 // element first, each multi-byte element in LSByte order
629 // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
630 // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
631 // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
632 // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
633 ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
634 0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34, 0x12};
635 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
636 std::vector<uint32_t> v;
637 // check that the number of bytes matches
638 ASSERT_EQ(p.unpack(v), 0);
639 // check that the payload was fully unpacked
640 ASSERT_TRUE(p.fullyUnpacked());
641 std::vector<uint32_t> k = {0x11223344, 0x22446688, 0x33557799, 0x12345678};
642 // check that the bytes were correctly unpacked (in byte order)
643 ASSERT_EQ(v, k);
644 }
645
646 // combination of TooManyBytes and InsufficientBytes because
647 // vectors will attempt to unpack full <T>s until the end of the input
TEST(Vectors,VectorUint32NonIntegralBytes)648 TEST(Vectors, VectorUint32NonIntegralBytes)
649 {
650 // last value should not get unpacked
651 // a vector of multi-byte values will be unpacked in order low-order
652 // element first, each multi-byte element in LSByte order,
653 // and will attempt to consume all bytes remaining
654 // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
655 // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
656 // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
657 // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
658 ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
659 0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34};
660 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
661 std::vector<uint32_t> v;
662 // check that the vector unpacks successfully
663 ASSERT_EQ(p.unpack(v), 0);
664 // check that the payload was not fully unpacked
665 ASSERT_FALSE(p.fullyUnpacked());
666 // arrays of uint32_t will be unpacked one at a time, so the
667 // last entry should not get unpacked properly
668 std::vector<uint32_t> k = {0x11223344, 0x22446688, 0x33557799};
669 // check that the bytes were correctly unpacked (in byte order)
670 ASSERT_EQ(v, k);
671 }
672
TEST(Vectors,VectorUint8)673 TEST(Vectors, VectorUint8)
674 {
675 // a vector of bytes will be unpacked verbatim, low-order element first
676 ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04};
677 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
678 std::vector<uint8_t> v;
679 // check that the number of bytes matches
680 ASSERT_EQ(p.unpack(v), 0);
681 // check that the payload was fully unpacked
682 ASSERT_TRUE(p.fullyUnpacked());
683 std::vector<uint8_t> k = {0x02, 0x00, 0x86, 0x04};
684 // check that the bytes were correctly unpacked (in byte order)
685 ASSERT_EQ(v, k);
686 }
687
TEST(Vectors,VectorEmptyOk)688 TEST(Vectors, VectorEmptyOk)
689 {
690 // an empty input vector to show that unpacking elements is okay
691 ipmi::SecureBuffer i{};
692 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
693 std::vector<uint32_t> v;
694 // check that the number of bytes matches
695 ASSERT_EQ(p.unpack(v), 0);
696 // check that the payload was fully unpacked
697 ASSERT_TRUE(p.fullyUnpacked());
698 std::vector<uint32_t> k{};
699 // check that the unpacked vector is empty as expected
700 ASSERT_EQ(v, k);
701 }
702
TEST(Vectors,VectorOfTuplesOk)703 TEST(Vectors, VectorOfTuplesOk)
704 {
705 // a vector of bytes will be unpacked verbatim, low-order element first
706 ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04};
707 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
708 std::vector<std::tuple<uint8_t, uint8_t>> v;
709 // check that the number of bytes matches
710 ASSERT_EQ(p.unpack(v), 0);
711 // check that the payload was fully unpacked
712 ASSERT_TRUE(p.fullyUnpacked());
713 std::vector<std::tuple<uint8_t, uint8_t>> k = {{0x02, 0x00}, {0x86, 0x04}};
714 // check that the bytes were correctly unpacked (in byte order)
715 ASSERT_EQ(v, k);
716 }
717
TEST(Vectors,VectorOfTuplesInsufficientBytes)718 TEST(Vectors, VectorOfTuplesInsufficientBytes)
719 {
720 // a vector of bytes will be unpacked verbatim, low-order element first
721 ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04, 0xb4};
722 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
723 std::vector<std::tuple<uint8_t, uint8_t>> v;
724 // check that the number of bytes matches
725 ASSERT_EQ(p.unpack(v), 0);
726 // check that the payload was not fully unpacked
727 ASSERT_FALSE(p.fullyUnpacked());
728 std::vector<std::tuple<uint8_t, uint8_t>> k = {{0x02, 0x00}, {0x86, 0x04}};
729 // check that the bytes were correctly unpacked (in byte order)
730 ASSERT_EQ(v, k);
731 }
732
733 // Cannot test TooManyBytes or InsufficientBytes for vector<uint8_t>
734 // because it will always unpack whatever bytes are remaining
735 // TEST(Vectors, VectorUint8TooManyBytes) {}
736 // TEST(Vectors, VectorUint8InsufficientBytes) {}
737
TEST(UnpackAdvanced,OptionalOk)738 TEST(UnpackAdvanced, OptionalOk)
739 {
740 // a vector of bytes will be unpacked verbatim, low-order element first
741 ipmi::SecureBuffer i = {0xbe, 0x02, 0x00, 0x86, 0x04};
742 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
743 std::optional<std::tuple<uint8_t, uint32_t>> v;
744 // check that the number of bytes matches
745 ASSERT_EQ(p.unpack(v), 0);
746 // check that the payload was fully unpacked
747 ASSERT_TRUE(p.fullyUnpacked());
748 std::optional<std::tuple<uint8_t, uint32_t>> k{{0xbe, 0x04860002}};
749 // check that the bytes were correctly unpacked (in byte order)
750 ASSERT_EQ(v, k);
751 }
752
TEST(UnpackAdvanced,OptionalInsufficientBytes)753 TEST(UnpackAdvanced, OptionalInsufficientBytes)
754 {
755 // a vector of bytes will be unpacked verbatim, low-order element first
756 ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04};
757 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
758 std::optional<std::tuple<uint8_t, uint32_t>> v;
759 // check that the number of bytes matches
760 ASSERT_EQ(p.unpack(v), 0);
761 // check that the payload was fully unpacked
762 ASSERT_FALSE(p.fullyUnpacked());
763 std::optional<std::tuple<uint8_t, uint32_t>> k;
764 // check that the bytes were correctly unpacked (in byte order)
765 ASSERT_EQ(v, k);
766 }
767
TEST(UnpackAdvanced,Uints)768 TEST(UnpackAdvanced, Uints)
769 {
770 // all elements will be unpacked in order, with each multi-byte
771 // element being processed LSByte first
772 // v1[7:0] v2[7:0] v2[15:8] v3[7:0] v3[15:8] v3[23:16] v3[31:24]
773 // v4[7:0] v4[15:8] v4[23:16] v4[31:24]
774 // v4[39:25] v4[47:40] v4[55:48] v4[63:56]
775 ipmi::SecureBuffer i = {0x02, 0x04, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55,
776 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
777 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
778 uint8_t v1;
779 uint16_t v2;
780 uint32_t v3;
781 uint64_t v4;
782 // check that the number of bytes matches
783 ASSERT_EQ(p.unpack(v1, v2, v3, v4), 0);
784 // check that the payload was fully unpacked
785 ASSERT_TRUE(p.fullyUnpacked());
786 uint8_t k1 = 0x02;
787 uint16_t k2 = 0x0604;
788 uint32_t k3 = 0x44332211;
789 uint64_t k4 = 0xccbbaa9988776655ull;
790 // check that the bytes were correctly unpacked (LSB first)
791 ASSERT_EQ(v1, k1);
792 ASSERT_EQ(v2, k2);
793 ASSERT_EQ(v3, k3);
794 ASSERT_EQ(v4, k4);
795 }
796
TEST(UnpackAdvanced,TupleInts)797 TEST(UnpackAdvanced, TupleInts)
798 {
799 // all elements will be unpacked in order, with each multi-byte
800 // element being processed LSByte first
801 // v1[7:0] v2[7:0] v2[15:8] v3[7:0] v3[15:8] v3[23:16] v3[31:24]
802 // v4[7:0] v4[15:8] v4[23:16] v4[31:24]
803 // v4[39:25] v4[47:40] v4[55:48] v4[63:56]
804 ipmi::SecureBuffer i = {0x02, 0x04, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55,
805 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
806 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
807 std::tuple<uint8_t, uint16_t, uint32_t, uint64_t> v;
808 // check that the number of bytes matches
809 ASSERT_EQ(p.unpack(v), 0);
810 // check that the payload was fully unpacked
811 ASSERT_TRUE(p.fullyUnpacked());
812 uint8_t k1 = 0x02;
813 uint16_t k2 = 0x0604;
814 uint32_t k3 = 0x44332211;
815 uint64_t k4 = 0xccbbaa9988776655ull;
816 auto k = std::make_tuple(k1, k2, k3, k4);
817 // check that the bytes were correctly unpacked (LSB first)
818 ASSERT_EQ(v, k);
819 }
820
TEST(UnpackAdvanced,BoolsnBitfieldsnFixedIntsOhMy)821 TEST(UnpackAdvanced, BoolsnBitfieldsnFixedIntsOhMy)
822 {
823 // each element will be unpacked, filling the low-order bits first
824 // with multi-byte values getting unpacked LSByte first
825 // v1 will use k[0][1:0]
826 // v2 will use k[0][2]
827 // v3[4:0] will use k[0][7:3], v3[6:5] will use k[1][1:0]
828 // v4 will use k[1][2]
829 // v5 will use k[1][7:3]
830 ipmi::SecureBuffer i = {0x9e, 0xdb};
831 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
832 uint2_t v1;
833 bool v2;
834 std::bitset<7> v3;
835 bool v4;
836 uint5_t v5;
837 // check that the number of bytes matches
838 ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5), 0);
839 // check that the payload was fully unpacked
840 ASSERT_TRUE(p.fullyUnpacked());
841 uint2_t k1 = 2; // binary 0b10
842 bool k2 = true; // binary 0b1
843 std::bitset<7> k3(0x73); // binary 0b1110011
844 bool k4 = false; // binary 0b0
845 uint5_t k5 = 27; // binary 0b11011
846 // check that the bytes were correctly unpacked (LSB first)
847 ASSERT_EQ(v1, k1);
848 ASSERT_EQ(v2, k2);
849 ASSERT_EQ(v3, k3);
850 ASSERT_EQ(v4, k4);
851 ASSERT_EQ(v5, k5);
852 }
853
TEST(UnpackAdvanced,UnalignedBitUnpacking)854 TEST(UnpackAdvanced, UnalignedBitUnpacking)
855 {
856 // unaligned multi-byte values will be unpacked the same as
857 // other bits, effectively reading from a large value, low-order
858 // bits first, then consuming the stream LSByte first
859 // v1 will use k[0][1:0]
860 // v2[5:0] will use k[0][7:2], v2[7:6] will use k[1][1:0]
861 // v3 will use k[1][2]
862 // v4[4:0] will use k[1][7:3] v4[12:5] will use k[2][7:0]
863 // v4[15:13] will use k[3][2:0]
864 // v5 will use k[3][3]
865 // v6[3:0] will use k[3][7:0] v6[11:4] will use k[4][7:0]
866 // v6[19:12] will use k[5][7:0] v6[27:20] will use k[6][7:0]
867 // v6[31:28] will use k[7][3:0]
868 // v7 will use k[7][7:4]
869 ipmi::SecureBuffer i = {0x96, 0xd2, 0x2a, 0xcd, 0xd3, 0x3b, 0xbc, 0x9d};
870 ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
871 uint2_t v1;
872 uint8_t v2;
873 bool v3;
874 uint16_t v4;
875 bool v5;
876 uint32_t v6;
877 uint4_t v7;
878 // check that the number of bytes matches
879 ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5, v6, v7), 0);
880 // check that the payload was fully unpacked
881 ASSERT_TRUE(p.fullyUnpacked());
882 uint2_t k1 = 2; // binary 0b10
883 uint8_t k2 = 0xa5; // binary 0b10100101
884 bool k3 = false; // binary 0b0
885 uint16_t k4 = 0xa55a; // binary 0b1010010101011010
886 bool k5 = true; // binary 0b1
887 uint32_t k6 = 0xdbc3bd3c; // binary 0b11011011110000111011110100111100
888 uint4_t k7 = 9; // binary 0b1001
889 // check that the bytes were correctly unpacked (LSB first)
890 ASSERT_EQ(v1, k1);
891 ASSERT_EQ(v2, k2);
892 ASSERT_EQ(v3, k3);
893 ASSERT_EQ(v4, k4);
894 ASSERT_EQ(v5, k5);
895 ASSERT_EQ(v6, k6);
896 ASSERT_EQ(v7, k7);
897 }
898