xref: /openbmc/phosphor-host-ipmid/test/message/unpack.cpp (revision 4c52102525fa7478fe288ca3a930f6728ce324e5)
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 {
23997952afSVernon Mauery     ipmi::SecureBuffer i = {0x04};
24997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 {
37997952afSVernon Mauery     ipmi::SecureBuffer i = {0x04, 0x86};
38997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 {
51997952afSVernon Mauery     ipmi::SecureBuffer i = {};
52997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 {
64997952afSVernon Mauery     ipmi::SecureBuffer i = {0x04, 0x86};
65997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 {
78997952afSVernon Mauery     ipmi::SecureBuffer i = {0x04, 0x86, 0x00};
79997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 {
92997952afSVernon Mauery     ipmi::SecureBuffer i = {0x04};
93997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 {
105997952afSVernon Mauery     ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02};
106997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 {
119997952afSVernon Mauery     ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02, 0x44};
120997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 {
133997952afSVernon Mauery     ipmi::SecureBuffer i = {0x04, 0x86, 0x00};
134997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 {
146997952afSVernon Mauery     ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02, 0x44, 0x33, 0x22, 0x11};
147997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 {
160997952afSVernon Mauery     ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02, 0x44,
161ebe8e906SVernon Mauery                             0x33, 0x22, 0x11, 0x55};
162997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 {
175997952afSVernon Mauery     ipmi::SecureBuffer i = {0x04, 0x86, 0x00, 0x02, 0x44, 0x33, 0x22};
176997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 {
188997952afSVernon Mauery     ipmi::SecureBuffer i = {0x58, 0x23, 0x11};
189997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 {
202997952afSVernon Mauery     ipmi::SecureBuffer i = {0x58, 0x23, 0x11, 0x00};
203997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 {
216997952afSVernon Mauery     ipmi::SecureBuffer i = {0x58, 0x23};
217997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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]
231997952afSVernon Mauery     ipmi::SecureBuffer i = {0xc9};
232997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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
249997952afSVernon Mauery     ipmi::SecureBuffer i = {0xc9};
250997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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
267997952afSVernon Mauery     ipmi::SecureBuffer i = {0xc9};
268997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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]
286997952afSVernon Mauery     ipmi::SecureBuffer i = {0xc9};
287997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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]
312997952afSVernon Mauery     ipmi::SecureBuffer i = {0xc9};
313997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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]
336997952afSVernon Mauery     ipmi::SecureBuffer i = {0xc9};
337997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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
362997952afSVernon Mauery     ipmi::SecureBuffer i = {0xc9};
363997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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
378997952afSVernon Mauery     ipmi::SecureBuffer i = {0xc9};
379997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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
394997952afSVernon Mauery     ipmi::SecureBuffer i = {0xc9};
395997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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]
410997952afSVernon Mauery     ipmi::SecureBuffer i = {0xc9};
411997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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
428997952afSVernon Mauery     ipmi::SecureBuffer i = {0xc9};
429997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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
446997952afSVernon Mauery     ipmi::SecureBuffer i = {0xc9};
447997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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]
466997952afSVernon Mauery     ipmi::SecureBuffer i = {0xb4, 0x86, 0x91, 0xc2};
467997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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
481997952afSVernon Mauery     ipmi::SecureBuffer i = {0xb4, 0x86, 0x91, 0xc2};
482997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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
496997952afSVernon Mauery     ipmi::SecureBuffer i = {0xb4, 0x86, 0x91, 0xc2};
497997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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
511997952afSVernon Mauery     ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04};
512997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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
527997952afSVernon Mauery     ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04, 0x22};
528997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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
543997952afSVernon Mauery     ipmi::SecureBuffer i = {0x02, 0x00, 0x86};
544997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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]
565997952afSVernon Mauery     ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
566ebe8e906SVernon Mauery                             0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34, 0x12};
567997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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]
588997952afSVernon Mauery     ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66,
589ebe8e906SVernon Mauery                             0x44, 0x22, 0x99, 0x77, 0x55, 0x33,
590ebe8e906SVernon Mauery                             0x78, 0x56, 0x34, 0x12, 0xaa};
591997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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]
612997952afSVernon Mauery     ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
613ebe8e906SVernon Mauery                             0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34};
614997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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]
634997952afSVernon Mauery     ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
635ebe8e906SVernon Mauery                             0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34, 0x12};
636997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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]
659997952afSVernon Mauery     ipmi::SecureBuffer i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
660ebe8e906SVernon Mauery                             0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34};
661997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
662ebe8e906SVernon Mauery     std::vector<uint32_t> v;
663caabc36bSVernon Mauery     // check that the vector unpacks successfully
664caabc36bSVernon 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
677997952afSVernon Mauery     ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04};
678997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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 
689caabc36bSVernon Mauery TEST(Vectors, VectorEmptyOk)
690caabc36bSVernon Mauery {
691caabc36bSVernon Mauery     // an empty input vector to show that unpacking elements is okay
692997952afSVernon Mauery     ipmi::SecureBuffer i{};
693997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
694caabc36bSVernon Mauery     std::vector<uint32_t> v;
695caabc36bSVernon Mauery     // check that the number of bytes matches
696caabc36bSVernon Mauery     ASSERT_EQ(p.unpack(v), 0);
697caabc36bSVernon Mauery     // check that the payload was fully unpacked
698caabc36bSVernon Mauery     ASSERT_TRUE(p.fullyUnpacked());
699caabc36bSVernon Mauery     std::vector<uint32_t> k{};
700caabc36bSVernon Mauery     // check that the unpacked vector is empty as expected
701caabc36bSVernon Mauery     ASSERT_EQ(v, k);
702caabc36bSVernon Mauery }
703caabc36bSVernon Mauery 
704caabc36bSVernon Mauery TEST(Vectors, VectorOfTuplesOk)
705caabc36bSVernon Mauery {
706caabc36bSVernon Mauery     // a vector of bytes will be unpacked verbatim, low-order element first
707997952afSVernon Mauery     ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04};
708997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
709caabc36bSVernon Mauery     std::vector<std::tuple<uint8_t, uint8_t>> v;
710caabc36bSVernon Mauery     // check that the number of bytes matches
711caabc36bSVernon Mauery     ASSERT_EQ(p.unpack(v), 0);
712caabc36bSVernon Mauery     // check that the payload was fully unpacked
713caabc36bSVernon Mauery     ASSERT_TRUE(p.fullyUnpacked());
714caabc36bSVernon Mauery     std::vector<std::tuple<uint8_t, uint8_t>> k = {{0x02, 0x00}, {0x86, 0x04}};
715caabc36bSVernon Mauery     // check that the bytes were correctly unpacked (in byte order)
716caabc36bSVernon Mauery     ASSERT_EQ(v, k);
717caabc36bSVernon Mauery }
718caabc36bSVernon Mauery 
719caabc36bSVernon Mauery TEST(Vectors, VectorOfTuplesInsufficientBytes)
720caabc36bSVernon Mauery {
721caabc36bSVernon Mauery     // a vector of bytes will be unpacked verbatim, low-order element first
722997952afSVernon Mauery     ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04, 0xb4};
723997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
724caabc36bSVernon Mauery     std::vector<std::tuple<uint8_t, uint8_t>> v;
725caabc36bSVernon Mauery     // check that the number of bytes matches
726caabc36bSVernon Mauery     ASSERT_EQ(p.unpack(v), 0);
727caabc36bSVernon Mauery     // check that the payload was not fully unpacked
728caabc36bSVernon Mauery     ASSERT_FALSE(p.fullyUnpacked());
729caabc36bSVernon Mauery     std::vector<std::tuple<uint8_t, uint8_t>> k = {{0x02, 0x00}, {0x86, 0x04}};
730caabc36bSVernon Mauery     // check that the bytes were correctly unpacked (in byte order)
731caabc36bSVernon Mauery     ASSERT_EQ(v, k);
732caabc36bSVernon Mauery }
733caabc36bSVernon 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
742997952afSVernon Mauery     ipmi::SecureBuffer i = {0xbe, 0x02, 0x00, 0x86, 0x04};
743997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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
757997952afSVernon Mauery     ipmi::SecureBuffer i = {0x02, 0x00, 0x86, 0x04};
758997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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());
764caabc36bSVernon 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]
776997952afSVernon Mauery     ipmi::SecureBuffer i = {0x02, 0x04, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55,
777ebe8e906SVernon Mauery                             0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
778997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(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]
805997952afSVernon Mauery     ipmi::SecureBuffer i = {0x02, 0x04, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55,
806ebe8e906SVernon Mauery                             0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
807997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
808*4c521025SWilliam A. Kennington III     std::tuple<uint8_t, uint16_t, uint32_t, uint64_t> v;
809ebe8e906SVernon Mauery     // check that the number of bytes matches
810ebe8e906SVernon Mauery     ASSERT_EQ(p.unpack(v), 0);
811ebe8e906SVernon Mauery     // check that the payload was fully unpacked
812ebe8e906SVernon Mauery     ASSERT_TRUE(p.fullyUnpacked());
813ebe8e906SVernon Mauery     uint8_t k1 = 0x02;
814ebe8e906SVernon Mauery     uint16_t k2 = 0x0604;
815ebe8e906SVernon Mauery     uint32_t k3 = 0x44332211;
816ebe8e906SVernon Mauery     uint64_t k4 = 0xccbbaa9988776655ull;
817ebe8e906SVernon Mauery     auto k = std::make_tuple(k1, k2, k3, k4);
818ebe8e906SVernon Mauery     // check that the bytes were correctly unpacked (LSB first)
819ebe8e906SVernon Mauery     ASSERT_EQ(v, k);
820ebe8e906SVernon Mauery }
821ebe8e906SVernon Mauery 
822ebe8e906SVernon Mauery TEST(UnpackAdvanced, BoolsnBitfieldsnFixedIntsOhMy)
823ebe8e906SVernon Mauery {
824ebe8e906SVernon Mauery     // each element will be unpacked, filling the low-order bits first
825ebe8e906SVernon Mauery     // with multi-byte values getting unpacked LSByte first
826ebe8e906SVernon Mauery     // v1 will use k[0][1:0]
827ebe8e906SVernon Mauery     // v2 will use k[0][2]
828ebe8e906SVernon Mauery     // v3[4:0] will use k[0][7:3], v3[6:5] will use k[1][1:0]
829ebe8e906SVernon Mauery     // v4 will use k[1][2]
830ebe8e906SVernon Mauery     // v5 will use k[1][7:3]
831997952afSVernon Mauery     ipmi::SecureBuffer i = {0x9e, 0xdb};
832997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
833ebe8e906SVernon Mauery     uint2_t v1;
834ebe8e906SVernon Mauery     bool v2;
835ebe8e906SVernon Mauery     std::bitset<7> v3;
836ebe8e906SVernon Mauery     bool v4;
837ebe8e906SVernon Mauery     uint5_t v5;
838ebe8e906SVernon Mauery     // check that the number of bytes matches
839ebe8e906SVernon Mauery     ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5), 0);
840ebe8e906SVernon Mauery     // check that the payload was fully unpacked
841ebe8e906SVernon Mauery     ASSERT_TRUE(p.fullyUnpacked());
842ebe8e906SVernon Mauery     uint2_t k1 = 2;          // binary 0b10
843ebe8e906SVernon Mauery     bool k2 = true;          // binary 0b1
844ebe8e906SVernon Mauery     std::bitset<7> k3(0x73); // binary 0b1110011
845ebe8e906SVernon Mauery     bool k4 = false;         // binary 0b0
846ebe8e906SVernon Mauery     uint5_t k5 = 27;         // binary 0b11011
847ebe8e906SVernon Mauery     // check that the bytes were correctly unpacked (LSB first)
848ebe8e906SVernon Mauery     ASSERT_EQ(v1, k1);
849ebe8e906SVernon Mauery     ASSERT_EQ(v2, k2);
850ebe8e906SVernon Mauery     ASSERT_EQ(v3, k3);
851ebe8e906SVernon Mauery     ASSERT_EQ(v4, k4);
852ebe8e906SVernon Mauery     ASSERT_EQ(v5, k5);
853ebe8e906SVernon Mauery }
854ebe8e906SVernon Mauery 
855ebe8e906SVernon Mauery TEST(UnpackAdvanced, UnalignedBitUnpacking)
856ebe8e906SVernon Mauery {
857ebe8e906SVernon Mauery     // unaligned multi-byte values will be unpacked the same as
858ebe8e906SVernon Mauery     // other bits, effectively reading from a large value, low-order
859ebe8e906SVernon Mauery     // bits first, then consuming the stream LSByte first
860ebe8e906SVernon Mauery     // v1 will use k[0][1:0]
861ebe8e906SVernon Mauery     // v2[5:0] will use k[0][7:2], v2[7:6] will use k[1][1:0]
862ebe8e906SVernon Mauery     // v3 will use k[1][2]
863ebe8e906SVernon Mauery     // v4[4:0] will use k[1][7:3] v4[12:5] will use k[2][7:0]
864ebe8e906SVernon Mauery     // v4[15:13] will use k[3][2:0]
865ebe8e906SVernon Mauery     // v5 will use k[3][3]
866ebe8e906SVernon Mauery     // v6[3:0] will use k[3][7:0] v6[11:4] will use k[4][7:0]
867ebe8e906SVernon Mauery     // v6[19:12] will use k[5][7:0] v6[27:20] will use k[6][7:0]
868ebe8e906SVernon Mauery     // v6[31:28] will use k[7][3:0]
869ebe8e906SVernon Mauery     // v7 will use k[7][7:4]
870997952afSVernon Mauery     ipmi::SecureBuffer i = {0x96, 0xd2, 0x2a, 0xcd, 0xd3, 0x3b, 0xbc, 0x9d};
871997952afSVernon Mauery     ipmi::message::Payload p(std::forward<ipmi::SecureBuffer>(i));
872ebe8e906SVernon Mauery     uint2_t v1;
873ebe8e906SVernon Mauery     uint8_t v2;
874ebe8e906SVernon Mauery     bool v3;
875ebe8e906SVernon Mauery     uint16_t v4;
876ebe8e906SVernon Mauery     bool v5;
877ebe8e906SVernon Mauery     uint32_t v6;
878ebe8e906SVernon Mauery     uint4_t v7;
879ebe8e906SVernon Mauery     // check that the number of bytes matches
880ebe8e906SVernon Mauery     ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5, v6, v7), 0);
881ebe8e906SVernon Mauery     // check that the payload was fully unpacked
882ebe8e906SVernon Mauery     ASSERT_TRUE(p.fullyUnpacked());
883ebe8e906SVernon Mauery     uint2_t k1 = 2;           // binary 0b10
884ebe8e906SVernon Mauery     uint8_t k2 = 0xa5;        // binary 0b10100101
885ebe8e906SVernon Mauery     bool k3 = false;          // binary 0b0
886ebe8e906SVernon Mauery     uint16_t k4 = 0xa55a;     // binary 0b1010010101011010
887ebe8e906SVernon Mauery     bool k5 = true;           // binary 0b1
888ebe8e906SVernon Mauery     uint32_t k6 = 0xdbc3bd3c; // binary 0b11011011110000111011110100111100
889ebe8e906SVernon Mauery     uint4_t k7 = 9;           // binary 0b1001
890ebe8e906SVernon Mauery     // check that the bytes were correctly unpacked (LSB first)
891ebe8e906SVernon Mauery     ASSERT_EQ(v1, k1);
892ebe8e906SVernon Mauery     ASSERT_EQ(v2, k2);
893ebe8e906SVernon Mauery     ASSERT_EQ(v3, k3);
894ebe8e906SVernon Mauery     ASSERT_EQ(v4, k4);
895ebe8e906SVernon Mauery     ASSERT_EQ(v5, k5);
896ebe8e906SVernon Mauery     ASSERT_EQ(v6, k6);
897ebe8e906SVernon Mauery     ASSERT_EQ(v7, k7);
898ebe8e906SVernon Mauery }
899