xref: /openbmc/libpldm/tests/msgbuf.cpp (revision 36af84cd)
1 #include <endian.h>
2 
3 #include <cfloat>
4 
5 #include <gtest/gtest.h>
6 
7 /* We're exercising the implementation so disable the asserts for now */
8 #ifndef NDEBUG
9 #define NDEBUG 1
10 #endif
11 
12 /*
13  * Fix up C11's _Static_assert() vs C++'s static_assert().
14  *
15  * Can we please have nice things for once.
16  */
17 #ifdef __cplusplus
18 // NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
19 #define _Static_assert(...) static_assert(__VA_ARGS__)
20 #endif
21 
22 #include "msgbuf.h"
23 
24 TEST(msgbuf, init_bad_ctx)
25 {
26     EXPECT_NE(pldm_msgbuf_init(NULL, 0, NULL, 0), PLDM_SUCCESS);
27 }
28 
29 TEST(msgbuf, init_bad_minsize)
30 {
31     struct pldm_msgbuf _ctx;
32     struct pldm_msgbuf* ctx = &_ctx;
33     uint8_t buf[1] = {};
34 
35     EXPECT_NE(pldm_msgbuf_init(ctx, sizeof(buf) + 1U, buf, sizeof(buf)),
36               PLDM_SUCCESS);
37 }
38 
39 TEST(msgbuf, init_bad_buf)
40 {
41     struct pldm_msgbuf _ctx;
42     struct pldm_msgbuf* ctx = &_ctx;
43 
44     EXPECT_NE(pldm_msgbuf_init(ctx, 0, NULL, 0), PLDM_SUCCESS);
45 }
46 
47 TEST(msgbuf, init_bad_len)
48 {
49     struct pldm_msgbuf _ctx;
50     struct pldm_msgbuf* ctx = &_ctx;
51     uint8_t buf[1] = {};
52 
53     EXPECT_NE(pldm_msgbuf_init(ctx, sizeof(buf), buf, SIZE_MAX), PLDM_SUCCESS);
54 }
55 
56 TEST(msgbuf, init_overflow)
57 {
58     struct pldm_msgbuf _ctx;
59     struct pldm_msgbuf* ctx = &_ctx;
60     // This is an intrinsic part of the test.
61     // NOLINTNEXTLINE(performance-no-int-to-ptr)
62     uint8_t* buf = (uint8_t*)SIZE_MAX;
63 
64     EXPECT_NE(pldm_msgbuf_init(ctx, 0, buf, 2), PLDM_SUCCESS);
65 }
66 
67 TEST(msgbuf, init_success)
68 {
69     struct pldm_msgbuf _ctx;
70     struct pldm_msgbuf* ctx = &_ctx;
71     uint8_t buf[1] = {};
72 
73     EXPECT_EQ(pldm_msgbuf_init(ctx, sizeof(buf), buf, sizeof(buf)),
74               PLDM_SUCCESS);
75 }
76 
77 TEST(msgbuf, destroy_none)
78 {
79     struct pldm_msgbuf _ctx;
80     struct pldm_msgbuf* ctx = &_ctx;
81     uint8_t buf[1] = {};
82 
83     ASSERT_EQ(pldm_msgbuf_init(ctx, sizeof(buf), buf, sizeof(buf)),
84               PLDM_SUCCESS);
85     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
86 }
87 
88 TEST(msgbuf, destroy_exact)
89 {
90     struct pldm_msgbuf _ctx;
91     struct pldm_msgbuf* ctx = &_ctx;
92     uint8_t buf[1] = {0xa5};
93     uint8_t val;
94 
95     ASSERT_EQ(pldm_msgbuf_init(ctx, sizeof(buf), buf, sizeof(buf)),
96               PLDM_SUCCESS);
97     EXPECT_EQ(pldm_msgbuf_extract_uint8(ctx, &val), PLDM_SUCCESS);
98     EXPECT_EQ(val, 0xa5);
99     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
100 }
101 
102 TEST(msgbuf, destroy_over)
103 {
104     struct pldm_msgbuf _ctx;
105     struct pldm_msgbuf* ctx = &_ctx;
106     uint8_t buf[1] = {0xa5};
107     uint8_t val;
108 
109     ASSERT_EQ(pldm_msgbuf_init(ctx, sizeof(buf), buf, sizeof(buf)),
110               PLDM_SUCCESS);
111     ASSERT_EQ(pldm_msgbuf_extract_uint8(ctx, &val), PLDM_SUCCESS);
112     ASSERT_EQ(val, 0xa5);
113     EXPECT_NE(pldm_msgbuf_extract_uint8(ctx, &val), PLDM_SUCCESS);
114     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_ERROR_INVALID_LENGTH);
115 }
116 
117 TEST(msgbuf, destroy_under)
118 {
119     struct pldm_msgbuf _ctx;
120     struct pldm_msgbuf* ctx = &_ctx;
121     uint8_t buf[2] = {0x5a, 0xa5};
122     uint8_t val;
123 
124     ASSERT_EQ(pldm_msgbuf_init(ctx, sizeof(buf), buf, sizeof(buf)),
125               PLDM_SUCCESS);
126     EXPECT_EQ(pldm_msgbuf_extract_uint8(ctx, &val), PLDM_SUCCESS);
127     EXPECT_EQ(val, 0x5a);
128     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
129 }
130 
131 TEST(msgbuf, extract_one_uint8)
132 {
133     struct pldm_msgbuf _ctx;
134     struct pldm_msgbuf* ctx = &_ctx;
135     uint8_t buf[1] = {0xa5};
136     uint8_t val;
137 
138     ASSERT_EQ(pldm_msgbuf_init(ctx, sizeof(buf), buf, sizeof(buf)),
139               PLDM_SUCCESS);
140     EXPECT_EQ(pldm_msgbuf_extract_uint8(ctx, &val), PLDM_SUCCESS);
141     EXPECT_EQ(val, 0xa5);
142     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
143 }
144 
145 TEST(msgbuf, extract_over_uint8)
146 {
147     struct pldm_msgbuf _ctx;
148     struct pldm_msgbuf* ctx = &_ctx;
149     uint8_t buf[1] = {};
150     uint8_t val;
151 
152     ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, 0), PLDM_SUCCESS);
153     EXPECT_NE(pldm_msgbuf_extract_uint8(ctx, &val), PLDM_SUCCESS);
154     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_ERROR_INVALID_LENGTH);
155 }
156 
157 TEST(msgbuf, extract_one_int8)
158 {
159     struct pldm_msgbuf _ctx;
160     struct pldm_msgbuf* ctx = &_ctx;
161     int8_t buf[1] = {-1};
162     int8_t val;
163 
164     ASSERT_EQ(pldm_msgbuf_init(ctx, sizeof(buf), buf, sizeof(buf)),
165               PLDM_SUCCESS);
166     EXPECT_EQ(pldm_msgbuf_extract_int8(ctx, &val), PLDM_SUCCESS);
167     EXPECT_EQ(val, -1);
168     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
169 }
170 
171 TEST(msgbuf, extract_over_int8)
172 {
173     struct pldm_msgbuf _ctx;
174     struct pldm_msgbuf* ctx = &_ctx;
175     int8_t buf[1] = {};
176     int8_t val;
177 
178     ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, 0), PLDM_SUCCESS);
179     EXPECT_NE(pldm_msgbuf_extract_int8(ctx, &val), PLDM_SUCCESS);
180     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_ERROR_INVALID_LENGTH);
181 }
182 
183 TEST(msgbuf, extract_one_uint16)
184 {
185     struct pldm_msgbuf _ctx;
186     struct pldm_msgbuf* ctx = &_ctx;
187     uint16_t buf[1] = {htole16(0x5aa5)};
188     uint16_t val = {};
189 
190     ASSERT_EQ(pldm_msgbuf_init(ctx, sizeof(buf), buf, sizeof(buf)),
191               PLDM_SUCCESS);
192     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctx, &val), PLDM_SUCCESS);
193     EXPECT_EQ(val, 0x5aa5);
194     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
195 }
196 
197 TEST(msgbuf, extract_over_uint16)
198 {
199     struct pldm_msgbuf _ctx;
200     struct pldm_msgbuf* ctx = &_ctx;
201     uint16_t buf[1] = {};
202     uint16_t val;
203 
204     ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, 0), PLDM_SUCCESS);
205     EXPECT_NE(pldm_msgbuf_extract_uint16(ctx, &val), PLDM_SUCCESS);
206     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_ERROR_INVALID_LENGTH);
207 }
208 
209 TEST(msgbuf, extract_one_int16)
210 {
211     struct pldm_msgbuf _ctx;
212     struct pldm_msgbuf* ctx = &_ctx;
213     int16_t buf[1] = {(int16_t)(htole16((uint16_t)INT16_MIN))};
214     int16_t val;
215 
216     ASSERT_EQ(pldm_msgbuf_init(ctx, sizeof(buf), buf, sizeof(buf)),
217               PLDM_SUCCESS);
218     EXPECT_EQ(pldm_msgbuf_extract_int16(ctx, &val), PLDM_SUCCESS);
219     EXPECT_EQ(val, INT16_MIN);
220     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
221 }
222 
223 TEST(msgbuf, extract_over_int16)
224 {
225     struct pldm_msgbuf _ctx;
226     struct pldm_msgbuf* ctx = &_ctx;
227     int16_t buf[1] = {};
228     int16_t val;
229 
230     ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, 0), PLDM_SUCCESS);
231     EXPECT_NE(pldm_msgbuf_extract_int16(ctx, &val), PLDM_SUCCESS);
232     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_ERROR_INVALID_LENGTH);
233 }
234 
235 TEST(msgbuf, extract_one_uint32)
236 {
237     struct pldm_msgbuf _ctx;
238     struct pldm_msgbuf* ctx = &_ctx;
239     uint32_t buf[1] = {htole32(0x5a00ffa5)};
240     uint32_t val;
241 
242     ASSERT_EQ(pldm_msgbuf_init(ctx, sizeof(buf), buf, sizeof(buf)),
243               PLDM_SUCCESS);
244     EXPECT_EQ(pldm_msgbuf_extract_uint32(ctx, &val), PLDM_SUCCESS);
245     EXPECT_EQ(val, 0x5a00ffa5);
246     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
247 }
248 
249 TEST(msgbuf, extract_over_uint32)
250 {
251     struct pldm_msgbuf _ctx;
252     struct pldm_msgbuf* ctx = &_ctx;
253     uint32_t buf[1] = {};
254     uint32_t val;
255 
256     ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, 0), PLDM_SUCCESS);
257     EXPECT_NE(pldm_msgbuf_extract_uint32(ctx, &val), PLDM_SUCCESS);
258     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_ERROR_INVALID_LENGTH);
259 }
260 
261 TEST(msgbuf, extract_one_int32)
262 {
263     struct pldm_msgbuf _ctx;
264     struct pldm_msgbuf* ctx = &_ctx;
265     int32_t buf[1] = {(int32_t)(htole32((uint32_t)(INT32_MIN)))};
266     int32_t val;
267 
268     ASSERT_EQ(pldm_msgbuf_init(ctx, sizeof(buf), buf, sizeof(buf)),
269               PLDM_SUCCESS);
270     EXPECT_EQ(pldm_msgbuf_extract_int32(ctx, &val), PLDM_SUCCESS);
271     EXPECT_EQ(val, INT32_MIN);
272     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
273 }
274 
275 TEST(msgbuf, extract_over_int32)
276 {
277     struct pldm_msgbuf _ctx;
278     struct pldm_msgbuf* ctx = &_ctx;
279     int32_t buf[1] = {};
280     int32_t val;
281 
282     ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, 0), PLDM_SUCCESS);
283     EXPECT_NE(pldm_msgbuf_extract_int32(ctx, &val), PLDM_SUCCESS);
284     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_ERROR_INVALID_LENGTH);
285 }
286 
287 TEST(msgbuf, extract_one_real32)
288 {
289     struct pldm_msgbuf _ctx;
290     struct pldm_msgbuf* ctx = &_ctx;
291     uint32_t buf[1] = {};
292     uint32_t xform;
293     real32_t val;
294 
295     val = FLT_MAX;
296     memcpy(&xform, &val, sizeof(val));
297     buf[0] = htole32(xform);
298     val = 0;
299 
300     ASSERT_EQ(pldm_msgbuf_init(ctx, sizeof(buf), buf, sizeof(buf)),
301               PLDM_SUCCESS);
302     EXPECT_EQ(pldm_msgbuf_extract_real32(ctx, &val), PLDM_SUCCESS);
303     EXPECT_EQ(val, FLT_MAX);
304     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
305 }
306 
307 TEST(msgbuf, extract_over_real32)
308 {
309     struct pldm_msgbuf _ctx;
310     struct pldm_msgbuf* ctx = &_ctx;
311     real32_t buf[1] = {};
312     real32_t val;
313 
314     ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, 0), PLDM_SUCCESS);
315     EXPECT_NE(pldm_msgbuf_extract_real32(ctx, &val), PLDM_SUCCESS);
316     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_ERROR_INVALID_LENGTH);
317 }
318