blob: 611a5feb77d50db77c8edcefe0b7b134ba18c002 [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 */
16#include <ipmid/api.hpp>
17#include <ipmid/message.hpp>
18
19#include <gtest/gtest.h>
20
21TEST(Uints, Uint8)
22{
23 std::vector<uint8_t> i = {0x04};
24 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
35TEST(Uints, Uint8TooManyBytes)
36{
37 std::vector<uint8_t> i = {0x04, 0x86};
38 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
49TEST(Uints, Uint8InsufficientBytes)
50{
51 std::vector<uint8_t> i = {};
52 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
62TEST(Uints, Uint16)
63{
64 std::vector<uint8_t> i = {0x04, 0x86};
65 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
76TEST(Uints, Uint16TooManyBytes)
77{
78 std::vector<uint8_t> i = {0x04, 0x86, 0x00};
79 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
90TEST(Uints, Uint16InsufficientBytes)
91{
92 std::vector<uint8_t> i = {0x04};
93 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
103TEST(Uints, Uint32)
104{
105 std::vector<uint8_t> i = {0x04, 0x86, 0x00, 0x02};
106 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
117TEST(Uints, Uint32TooManyBytes)
118{
119 std::vector<uint8_t> i = {0x04, 0x86, 0x00, 0x02, 0x44};
120 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
131TEST(Uints, Uint32InsufficientBytes)
132{
133 std::vector<uint8_t> i = {0x04, 0x86, 0x00};
134 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
144TEST(Uints, Uint64)
145{
146 std::vector<uint8_t> i = {0x04, 0x86, 0x00, 0x02, 0x44, 0x33, 0x22, 0x11};
147 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
158TEST(Uints, Uint64TooManyBytes)
159{
160 std::vector<uint8_t> i = {0x04, 0x86, 0x00, 0x02, 0x44,
161 0x33, 0x22, 0x11, 0x55};
162 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
173TEST(Uints, Uint64InsufficientBytes)
174{
175 std::vector<uint8_t> i = {0x04, 0x86, 0x00, 0x02, 0x44, 0x33, 0x22};
176 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
186TEST(Uints, Uint24)
187{
188 std::vector<uint8_t> i = {0x58, 0x23, 0x11};
189 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
200TEST(FixedInts, Uint24TooManyBytes)
201{
202 std::vector<uint8_t> i = {0x58, 0x23, 0x11, 0x00};
203 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
214TEST(FixedInts, Uint24InsufficientBytes)
215{
216 std::vector<uint8_t> i = {0x58, 0x23};
217 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
227TEST(FixedInts, Uint3Uint5)
228{
229 // individual bytes are unpacked low-order-bits first
230 // v1 will use [2:0], v2 will use [7:3]
231 std::vector<uint8_t> i = {0xc9};
232 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
246TEST(FixedInts, Uint3Uint4TooManyBits)
247{
248 // high order bit should not get unpacked
249 std::vector<uint8_t> i = {0xc9};
250 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
264TEST(FixedInts, Uint3Uint6InsufficientBits)
265{
266 // insufficient bits to unpack v2
267 std::vector<uint8_t> i = {0xc9};
268 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
282TEST(Bools, Boolx8)
283{
284 // individual bytes are unpacked low-order-bits first
285 // [v8, v7, v6, v5, v4, v3, v2, v1]
286 std::vector<uint8_t> i = {0xc9};
287 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
307TEST(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 std::vector<uint8_t> i = {0xc9};
313 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
332TEST(Bools, Boolx8InsufficientBits)
333{
334 // individual bytes are unpacked low-order-bits first
335 // [v8, v7, v6, v5, v4, v3, v2, v1]
336 std::vector<uint8_t> i = {0xc9};
337 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
358TEST(Bitsets, Bitset8)
359{
360 // individual bytes are unpacked low-order-bits first
361 // a bitset for 8 bits fills the full byte
362 std::vector<uint8_t> i = {0xc9};
363 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
374TEST(Bitsets, Bitset7TooManyBits)
375{
376 // individual bytes are unpacked low-order-bits first
377 // a bitset for 8 bits fills the full byte
378 std::vector<uint8_t> i = {0xc9};
379 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
390TEST(Bitsets, Bitset9InsufficientBits)
391{
392 // individual bytes are unpacked low-order-bits first
393 // a bitset for 8 bits fills the full byte
394 std::vector<uint8_t> i = {0xc9};
395 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
406TEST(Bitsets, Bitset3Bitset5)
407{
408 // individual bytes are unpacked low-order-bits first
409 // v1 will use [2:0], v2 will use [7:3]
410 std::vector<uint8_t> i = {0xc9};
411 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
425TEST(Bitsets, Bitset3Bitset4TooManyBits)
426{
427 // high order bit should not get unpacked
428 std::vector<uint8_t> i = {0xc9};
429 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
443TEST(Bitsets, Bitset3Bitset6InsufficientBits)
444{
445 // insufficient bits to unpack v2
446 std::vector<uint8_t> i = {0xc9};
447 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
461TEST(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 std::vector<uint8_t> i = {0xb4, 0x86, 0x91, 0xc2};
467 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
478TEST(Bitsets, Bitset31TooManyBits)
479{
480 // high order bit should not get unpacked
481 std::vector<uint8_t> i = {0xb4, 0x86, 0x91, 0xc2};
482 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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
493TEST(Bitsets, Bitset33InsufficientBits)
494{
495 // insufficient bits to unpack v2
496 std::vector<uint8_t> i = {0xb4, 0x86, 0x91, 0xc2};
497 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(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 std::bitset<33> k(0);
504 // check that v is zero
505 ASSERT_EQ(v, 0);
506}
507
508TEST(Arrays, Array4xUint8)
509{
510 // an array of bytes will be read verbatim, low-order element first
511 std::vector<uint8_t> i = {0x02, 0x00, 0x86, 0x04};
512 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
513 std::array<uint8_t, 4> v;
514 // check that the number of bytes matches
515 ASSERT_EQ(p.unpack(v), 0);
516 // check that the payload was fully unpacked
517 ASSERT_TRUE(p.fullyUnpacked());
518 std::array<uint8_t, 4> k = {{0x02, 0x00, 0x86, 0x04}};
519 // check that the bytes were correctly unpacked (in byte order)
520 ASSERT_EQ(v, k);
521}
522
523TEST(Arrays, Array4xUint8TooManyBytes)
524{
525 // last byte should not get unpacked
526 // an array of bytes will be read verbatim, low-order element first
527 std::vector<uint8_t> i = {0x02, 0x00, 0x86, 0x04, 0x22};
528 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
529 std::array<uint8_t, 4> v;
530 // check that the number of bytes matches
531 ASSERT_EQ(p.unpack(v), 0);
532 // check that the payload was not fully unpacked
533 ASSERT_FALSE(p.fullyUnpacked());
534 std::array<uint8_t, 4> k = {{0x02, 0x00, 0x86, 0x04}};
535 // check that the bytes were correctly unpacked (in byte order)
536 ASSERT_EQ(v, k);
537}
538
539TEST(Arrays, Array4xUint8InsufficientBytes)
540{
541 // last byte should not get unpacked
542 // an array of bytes will be read verbatim, low-order element first
543 std::vector<uint8_t> i = {0x02, 0x00, 0x86};
544 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
545 std::array<uint8_t, 4> v;
546 // check that the number of bytes matches
547 ASSERT_NE(p.unpack(v), 0);
548 // check that the payload was not fully unpacked
549 ASSERT_FALSE(p.fullyUnpacked());
550 // arrays of uint8_t will be unpacked all at once
551 // so nothing will get unpacked
552 std::array<uint8_t, 4> k = {{0, 0, 0, 0}};
553 // check that the bytes were correctly unpacked (in byte order)
554 ASSERT_EQ(v, k);
555}
556
557TEST(Arrays, Array4xUint32)
558{
559 // an array of multi-byte values will be unpacked in order low-order
560 // element first, each multi-byte element in LSByte order
561 // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
562 // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
563 // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
564 // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
565 std::vector<uint8_t> i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
566 0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34, 0x12};
567 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
568 std::array<uint32_t, 4> v;
569 // check that the number of bytes matches
570 ASSERT_EQ(p.unpack(v), 0);
571 // check that the payload was fully unpacked
572 ASSERT_TRUE(p.fullyUnpacked());
573 std::array<uint32_t, 4> k = {
574 {0x11223344, 0x22446688, 0x33557799, 0x12345678}};
575 // check that the bytes were correctly unpacked (in byte order)
576 ASSERT_EQ(v, k);
577}
578
579TEST(Arrays, Array4xUint32TooManyBytes)
580{
581 // last byte should not get unpacked
582 // an array of multi-byte values will be unpacked in order low-order
583 // element first, each multi-byte element in LSByte order
584 // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
585 // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
586 // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
587 // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
588 std::vector<uint8_t> i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66,
589 0x44, 0x22, 0x99, 0x77, 0x55, 0x33,
590 0x78, 0x56, 0x34, 0x12, 0xaa};
591 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
592 std::array<uint32_t, 4> v;
593 // check that the number of bytes matches
594 ASSERT_EQ(p.unpack(v), 0);
595 // check that the payload was not fully unpacked
596 ASSERT_FALSE(p.fullyUnpacked());
597 std::array<uint32_t, 4> k = {
598 {0x11223344, 0x22446688, 0x33557799, 0x12345678}};
599 // check that the bytes were correctly unpacked (in byte order)
600 ASSERT_EQ(v, k);
601}
602
603TEST(Arrays, Array4xUint32InsufficientBytes)
604{
605 // last value should not get unpacked
606 // an array of multi-byte values will be unpacked in order low-order
607 // element first, each multi-byte element in LSByte order
608 // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
609 // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
610 // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
611 // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
612 std::vector<uint8_t> i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
613 0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34};
614 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
615 std::array<uint32_t, 4> v;
616 // check that the number of bytes matches
617 ASSERT_NE(p.unpack(v), 0);
618 // check that the payload was not fully unpacked
619 ASSERT_FALSE(p.fullyUnpacked());
620 // arrays of uint32_t will be unpacked in a way that looks atomic
621 std::array<uint32_t, 4> k = {{0, 0, 0, 0}};
622 // check that the bytes were correctly unpacked (in byte order)
623 ASSERT_EQ(v, k);
624}
625
626TEST(Vectors, VectorUint32)
627{
628 // a vector of multi-byte values will be unpacked in order low-order
629 // element first, each multi-byte element in LSByte order
630 // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
631 // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
632 // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
633 // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
634 std::vector<uint8_t> i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
635 0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34, 0x12};
636 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
637 std::vector<uint32_t> v;
638 // check that the number of bytes matches
639 ASSERT_EQ(p.unpack(v), 0);
640 // check that the payload was fully unpacked
641 ASSERT_TRUE(p.fullyUnpacked());
642 std::vector<uint32_t> k = {0x11223344, 0x22446688, 0x33557799, 0x12345678};
643 // check that the bytes were correctly unpacked (in byte order)
644 ASSERT_EQ(v, k);
645}
646
647// combination of TooManyBytes and InsufficientBytes because
648// vectors will attempt to unpack full <T>s until the end of the input
649TEST(Vectors, VectorUint32NonIntegralBytes)
650{
651 // last value should not get unpacked
652 // a vector of multi-byte values will be unpacked in order low-order
653 // element first, each multi-byte element in LSByte order,
654 // and will attempt to consume all bytes remaining
655 // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
656 // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
657 // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
658 // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
659 std::vector<uint8_t> i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
660 0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34};
661 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
662 std::vector<uint32_t> v;
663 // check that the number of bytes matches
664 ASSERT_NE(p.unpack(v), 0);
665 // check that the payload was not fully unpacked
666 ASSERT_FALSE(p.fullyUnpacked());
667 // arrays of uint32_t will be unpacked one at a time, so the
668 // last entry should not get unpacked properly
669 std::vector<uint32_t> k = {0x11223344, 0x22446688, 0x33557799};
670 // check that the bytes were correctly unpacked (in byte order)
671 ASSERT_EQ(v, k);
672}
673
674TEST(Vectors, VectorUint8)
675{
676 // a vector of bytes will be unpacked verbatim, low-order element first
677 std::vector<uint8_t> i = {0x02, 0x00, 0x86, 0x04};
678 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
679 std::vector<uint8_t> v;
680 // check that the number of bytes matches
681 ASSERT_EQ(p.unpack(v), 0);
682 // check that the payload was fully unpacked
683 ASSERT_TRUE(p.fullyUnpacked());
684 std::vector<uint8_t> k = {0x02, 0x00, 0x86, 0x04};
685 // check that the bytes were correctly unpacked (in byte order)
686 ASSERT_EQ(v, k);
687}
688
689// Cannot test TooManyBytes or InsufficientBytes for vector<uint8_t>
690// because it will always unpack whatever bytes are remaining
691// TEST(Vectors, VectorUint8TooManyBytes) {}
692// TEST(Vectors, VectorUint8InsufficientBytes) {}
693
694TEST(UnpackAdvanced, OptionalOk)
695{
696 // a vector of bytes will be unpacked verbatim, low-order element first
697 std::vector<uint8_t> i = {0xbe, 0x02, 0x00, 0x86, 0x04};
698 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
699 std::optional<std::tuple<uint8_t, uint32_t>> v;
700 // check that the number of bytes matches
701 ASSERT_EQ(p.unpack(v), 0);
702 // check that the payload was fully unpacked
703 ASSERT_TRUE(p.fullyUnpacked());
704 std::optional<std::tuple<uint8_t, uint32_t>> k{{0xbe, 0x04860002}};
705 // check that the bytes were correctly unpacked (in byte order)
706 ASSERT_EQ(v, k);
707}
708
709TEST(UnpackAdvanced, OptionalInsufficientBytes)
710{
711 // a vector of bytes will be unpacked verbatim, low-order element first
712 std::vector<uint8_t> i = {0x02, 0x00, 0x86, 0x04};
713 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
714 std::optional<std::tuple<uint8_t, uint32_t>> v;
715 // check that the number of bytes matches
716 ASSERT_EQ(p.unpack(v), 0);
717 // check that the payload was fully unpacked
718 ASSERT_FALSE(p.fullyUnpacked());
719 std::optional<std::tuple<uint8_t, uint32_t>> k = {{0, 0}};
720 // check that the bytes were correctly unpacked (in byte order)
721 ASSERT_EQ(v, k);
722}
723
724TEST(UnpackAdvanced, Uints)
725{
726 // all elements will be unpacked in order, with each multi-byte
727 // element being processed LSByte first
728 // v1[7:0] v2[7:0] v2[15:8] v3[7:0] v3[15:8] v3[23:16] v3[31:24]
729 // v4[7:0] v4[15:8] v4[23:16] v4[31:24]
730 // v4[39:25] v4[47:40] v4[55:48] v4[63:56]
731 std::vector<uint8_t> i = {0x02, 0x04, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55,
732 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
733 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
734 uint8_t v1;
735 uint16_t v2;
736 uint32_t v3;
737 uint64_t v4;
738 // check that the number of bytes matches
739 ASSERT_EQ(p.unpack(v1, v2, v3, v4), 0);
740 // check that the payload was fully unpacked
741 ASSERT_TRUE(p.fullyUnpacked());
742 uint8_t k1 = 0x02;
743 uint16_t k2 = 0x0604;
744 uint32_t k3 = 0x44332211;
745 uint64_t k4 = 0xccbbaa9988776655ull;
746 // check that the bytes were correctly unpacked (LSB first)
747 ASSERT_EQ(v1, k1);
748 ASSERT_EQ(v2, k2);
749 ASSERT_EQ(v3, k3);
750 ASSERT_EQ(v4, k4);
751}
752
753TEST(UnpackAdvanced, TupleInts)
754{
755 // all elements will be unpacked in order, with each multi-byte
756 // element being processed LSByte first
757 // v1[7:0] v2[7:0] v2[15:8] v3[7:0] v3[15:8] v3[23:16] v3[31:24]
758 // v4[7:0] v4[15:8] v4[23:16] v4[31:24]
759 // v4[39:25] v4[47:40] v4[55:48] v4[63:56]
760 std::vector<uint8_t> i = {0x02, 0x04, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55,
761 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
762 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
763 uint8_t v1;
764 uint16_t v2;
765 uint32_t v3;
766 uint64_t v4;
767 auto v = std::make_tuple(v1, v2, v3, v4);
768 // check that the number of bytes matches
769 ASSERT_EQ(p.unpack(v), 0);
770 // check that the payload was fully unpacked
771 ASSERT_TRUE(p.fullyUnpacked());
772 uint8_t k1 = 0x02;
773 uint16_t k2 = 0x0604;
774 uint32_t k3 = 0x44332211;
775 uint64_t k4 = 0xccbbaa9988776655ull;
776 auto k = std::make_tuple(k1, k2, k3, k4);
777 // check that the bytes were correctly unpacked (LSB first)
778 ASSERT_EQ(v, k);
779}
780
781TEST(UnpackAdvanced, BoolsnBitfieldsnFixedIntsOhMy)
782{
783 // each element will be unpacked, filling the low-order bits first
784 // with multi-byte values getting unpacked LSByte first
785 // v1 will use k[0][1:0]
786 // v2 will use k[0][2]
787 // v3[4:0] will use k[0][7:3], v3[6:5] will use k[1][1:0]
788 // v4 will use k[1][2]
789 // v5 will use k[1][7:3]
790 std::vector<uint8_t> i = {0x9e, 0xdb};
791 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
792 uint2_t v1;
793 bool v2;
794 std::bitset<7> v3;
795 bool v4;
796 uint5_t v5;
797 // check that the number of bytes matches
798 ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5), 0);
799 // check that the payload was fully unpacked
800 ASSERT_TRUE(p.fullyUnpacked());
801 uint2_t k1 = 2; // binary 0b10
802 bool k2 = true; // binary 0b1
803 std::bitset<7> k3(0x73); // binary 0b1110011
804 bool k4 = false; // binary 0b0
805 uint5_t k5 = 27; // binary 0b11011
806 // check that the bytes were correctly unpacked (LSB first)
807 ASSERT_EQ(v1, k1);
808 ASSERT_EQ(v2, k2);
809 ASSERT_EQ(v3, k3);
810 ASSERT_EQ(v4, k4);
811 ASSERT_EQ(v5, k5);
812}
813
814TEST(UnpackAdvanced, UnalignedBitUnpacking)
815{
816 // unaligned multi-byte values will be unpacked the same as
817 // other bits, effectively reading from a large value, low-order
818 // bits first, then consuming the stream LSByte first
819 // v1 will use k[0][1:0]
820 // v2[5:0] will use k[0][7:2], v2[7:6] will use k[1][1:0]
821 // v3 will use k[1][2]
822 // v4[4:0] will use k[1][7:3] v4[12:5] will use k[2][7:0]
823 // v4[15:13] will use k[3][2:0]
824 // v5 will use k[3][3]
825 // v6[3:0] will use k[3][7:0] v6[11:4] will use k[4][7:0]
826 // v6[19:12] will use k[5][7:0] v6[27:20] will use k[6][7:0]
827 // v6[31:28] will use k[7][3:0]
828 // v7 will use k[7][7:4]
829 std::vector<uint8_t> i = {0x96, 0xd2, 0x2a, 0xcd, 0xd3, 0x3b, 0xbc, 0x9d};
830 ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
831 uint2_t v1;
832 uint8_t v2;
833 bool v3;
834 uint16_t v4;
835 bool v5;
836 uint32_t v6;
837 uint4_t v7;
838 // check that the number of bytes matches
839 ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5, v6, v7), 0);
840 // check that the payload was fully unpacked
841 ASSERT_TRUE(p.fullyUnpacked());
842 uint2_t k1 = 2; // binary 0b10
843 uint8_t k2 = 0xa5; // binary 0b10100101
844 bool k3 = false; // binary 0b0
845 uint16_t k4 = 0xa55a; // binary 0b1010010101011010
846 bool k5 = true; // binary 0b1
847 uint32_t k6 = 0xdbc3bd3c; // binary 0b11011011110000111011110100111100
848 uint4_t k7 = 9; // binary 0b1001
849 // check that the bytes were correctly unpacked (LSB first)
850 ASSERT_EQ(v1, k1);
851 ASSERT_EQ(v2, k2);
852 ASSERT_EQ(v3, k3);
853 ASSERT_EQ(v4, k4);
854 ASSERT_EQ(v5, k5);
855 ASSERT_EQ(v6, k6);
856 ASSERT_EQ(v7, k7);
857}