xref: /openbmc/libpldm/tests/msgbuf.cpp (revision a918a62831ef49e2788b48454029d180131a70fe)
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  
319  TEST(msgbuf, extract_array_uint8_buf0_req0)
320  {
321      struct pldm_msgbuf _ctx;
322      struct pldm_msgbuf* ctx = &_ctx;
323      uint8_t buf[1] = {};
324      uint8_t arr[1];
325  
326      ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, 0), PLDM_SUCCESS);
327      EXPECT_EQ(pldm_msgbuf_extract_array_uint8(ctx, arr, 0), PLDM_SUCCESS);
328      ASSERT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
329  }
330  
331  TEST(msgbuf, extract_array_uint8_buf1_req1)
332  {
333      struct pldm_msgbuf _ctx;
334      struct pldm_msgbuf* ctx = &_ctx;
335      uint8_t buf[1] = {};
336      uint8_t arr[1];
337  
338      ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
339      EXPECT_EQ(pldm_msgbuf_extract_array_uint8(ctx, arr, sizeof(arr)),
340                PLDM_SUCCESS);
341      EXPECT_EQ(arr[0], 0);
342      ASSERT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
343  }
344  
345  TEST(msgbuf, extract_array_uint8_buf1_req2)
346  {
347      struct pldm_msgbuf _ctx;
348      struct pldm_msgbuf* ctx = &_ctx;
349      uint8_t buf[1] = {};
350      uint8_t arr[2];
351  
352      ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
353      EXPECT_NE(pldm_msgbuf_extract_array_uint8(ctx, arr, sizeof(arr)),
354                PLDM_SUCCESS);
355      ASSERT_EQ(pldm_msgbuf_destroy(ctx), PLDM_ERROR_INVALID_LENGTH);
356  }
357  
358  TEST(msgbuf, consumed_under)
359  {
360      struct pldm_msgbuf _ctx;
361      struct pldm_msgbuf* ctx = &_ctx;
362      uint8_t buf[1] = {};
363  
364      ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
365      EXPECT_EQ(pldm_msgbuf_destroy_consumed(ctx), PLDM_ERROR_INVALID_LENGTH);
366  }
367  
368  TEST(msgbuf, consumed_exact)
369  {
370      struct pldm_msgbuf _ctx;
371      struct pldm_msgbuf* ctx = &_ctx;
372      uint8_t buf[1] = {};
373      uint8_t val;
374  
375      ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
376      EXPECT_EQ(pldm_msgbuf_extract_uint8(ctx, &val), PLDM_SUCCESS);
377      EXPECT_EQ(pldm_msgbuf_destroy_consumed(ctx), PLDM_SUCCESS);
378  }
379  
380  TEST(msgbuf, consumed_over)
381  {
382      struct pldm_msgbuf _ctx;
383      struct pldm_msgbuf* ctx = &_ctx;
384      uint8_t buf[1] = {};
385      uint8_t val[2];
386  
387      ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
388      EXPECT_EQ(pldm_msgbuf_extract_uint8(ctx, &val[0]), PLDM_SUCCESS);
389      EXPECT_NE(pldm_msgbuf_extract_uint8(ctx, &val[1]), PLDM_SUCCESS);
390      EXPECT_EQ(pldm_msgbuf_destroy_consumed(ctx), PLDM_ERROR_INVALID_LENGTH);
391  }
392