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