df0e91af353407808e85b62c32f067e29d68a4f2
2 * Copyright © 2014 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 /* A collection of unit tests for blob.c */
32 #include "util/ralloc.h"
35 #define bytes_test_str "bytes_test"
36 #define reserve_test_str "reserve_test"
38 /* This placeholder must be the same length as the next overwrite_test_str */
39 #define placeholder_str "XXXXXXXXXXXXXX"
40 #define overwrite_test_str "overwrite_test"
41 #define uint32_test 0x12345678
42 #define uint32_placeholder 0xDEADBEEF
43 #define uint32_overwrite 0xA1B2C3D4
44 #define uint64_test 0x1234567890ABCDEF
45 #define string_test_str "string_test"
50 expect_equal(uint64_t expected
, uint64_t actual
, const char *test
)
52 if (actual
!= expected
) {
54 "Error: Test '%s' failed: "
55 "Expected=%" PRIu64
", "
56 "Actual=%" PRIu64
"\n",
57 test
, expected
, actual
);
63 expect_unequal(uint64_t expected
, uint64_t actual
, const char *test
)
65 if (actual
== expected
) {
67 "Error: Test '%s' failed: Result=%" PRIu64
", "
68 "but expected something different.\n",
75 expect_equal_str(const char *expected
, const char *actual
, const char *test
)
77 if (strcmp(expected
, actual
)) {
78 fprintf (stderr
, "Error: Test '%s' failed:\n\t"
79 "Expected=\"%s\", Actual=\"%s\"\n",
80 test
, expected
, actual
);
86 expect_equal_bytes(uint8_t *expected
, uint8_t *actual
,
87 size_t num_bytes
, const char *test
)
91 if (memcmp(expected
, actual
, num_bytes
)) {
92 fprintf (stderr
, "Error: Test '%s' failed:\n\t", test
);
94 fprintf (stderr
, "Expected=[");
95 for (i
= 0; i
< num_bytes
; i
++) {
97 fprintf(stderr
, ", ");
98 fprintf(stderr
, "0x%02x", expected
[i
]);
100 fprintf (stderr
, "]");
102 fprintf (stderr
, "Actual=[");
103 for (i
= 0; i
< num_bytes
; i
++) {
105 fprintf(stderr
, ", ");
106 fprintf(stderr
, "0x%02x", actual
[i
]);
108 fprintf (stderr
, "]\n");
114 /* Test at least one call of each blob_write_foo and blob_read_foo function,
115 * verifying that we read out everything we wrote, that every bytes is
116 * consumed, and that the overrun bit is not set.
119 test_write_and_read_functions (void)
122 struct blob_reader reader
;
124 size_t str_offset
, uint_offset
;
125 uint8_t reserve_buf
[sizeof(reserve_test_str
)];
127 blob
= blob_create();
129 /*** Test blob by writing one of every possible kind of value. */
131 blob_write_bytes(blob
, bytes_test_str
, sizeof(bytes_test_str
));
133 reserved
= blob_reserve_bytes(blob
, sizeof(reserve_test_str
));
134 memcpy(reserved
, reserve_test_str
, sizeof(reserve_test_str
));
136 /* Write a placeholder, (to be replaced later via overwrite_bytes) */
137 str_offset
= blob
->size
;
138 blob_write_bytes(blob
, placeholder_str
, sizeof(placeholder_str
));
140 blob_write_uint32(blob
, uint32_test
);
142 /* Write a placeholder, (to be replaced later via overwrite_uint32) */
143 uint_offset
= blob
->size
;
144 blob_write_uint32(blob
, uint32_placeholder
);
146 blob_write_uint64(blob
, uint64_test
);
148 blob_write_intptr(blob
, (intptr_t) blob
);
150 blob_write_string(blob
, string_test_str
);
152 /* Finally, overwrite our placeholders. */
153 blob_overwrite_bytes(blob
, str_offset
, overwrite_test_str
,
154 sizeof(overwrite_test_str
));
155 blob_overwrite_uint32(blob
, uint_offset
, uint32_overwrite
);
157 /*** Now read each value and verify. */
158 blob_reader_init(&reader
, blob
->data
, blob
->size
);
160 expect_equal_str(bytes_test_str
,
161 blob_read_bytes(&reader
, sizeof(bytes_test_str
)),
162 "blob_write/read_bytes");
164 blob_copy_bytes(&reader
, reserve_buf
, sizeof(reserve_buf
));
165 expect_equal_str(reserve_test_str
, (char *) reserve_buf
,
166 "blob_reserve_bytes/blob_copy_bytes");
168 expect_equal_str(overwrite_test_str
,
169 blob_read_bytes(&reader
, sizeof(overwrite_test_str
)),
170 "blob_overwrite_bytes");
172 expect_equal(uint32_test
, blob_read_uint32(&reader
),
173 "blob_write/read_uint32");
174 expect_equal(uint32_overwrite
, blob_read_uint32(&reader
),
175 "blob_overwrite_uint32");
176 expect_equal(uint64_test
, blob_read_uint64(&reader
),
177 "blob_write/read_uint64");
178 expect_equal((intptr_t) blob
, blob_read_intptr(&reader
),
179 "blob_write/read_intptr");
180 expect_equal_str(string_test_str
, blob_read_string(&reader
),
181 "blob_write/read_string");
183 expect_equal(reader
.end
- reader
.data
, reader
.current
- reader
.data
,
184 "read_consumes_all_bytes");
185 expect_equal(false, reader
.overrun
, "read_does_not_overrun");
190 /* Test that data values are written and read with proper alignment. */
195 struct blob_reader reader
;
196 uint8_t bytes
[] = "ABCDEFGHIJKLMNOP";
197 size_t delta
, last
, num_bytes
;
199 blob
= blob_create();
201 /* First, write an intptr value to the blob and capture that size. This is
202 * the expected offset between any pair of intptr values (if written with
205 blob_write_intptr(blob
, (intptr_t) blob
);
210 /* Then loop doing the following:
212 * 1. Write an unaligned number of bytes
213 * 2. Verify that write results in an unaligned size
214 * 3. Write an intptr_t value
215 * 2. Verify that that write results in an aligned size
217 for (num_bytes
= 1; num_bytes
< sizeof(intptr_t); num_bytes
++) {
218 blob_write_bytes(blob
, bytes
, num_bytes
);
220 expect_unequal(delta
, blob
->size
- last
, "unaligned write of bytes");
222 blob_write_intptr(blob
, (intptr_t) blob
);
224 expect_equal(2 * delta
, blob
->size
- last
, "aligned write of intptr");
229 /* Finally, test that reading also does proper alignment. Since we know
230 * that values were written with all the right alignment, all we have to do
231 * here is verify that correct values are read.
233 blob_reader_init(&reader
, blob
->data
, blob
->size
);
235 expect_equal((intptr_t) blob
, blob_read_intptr(&reader
),
236 "read of initial, aligned intptr_t");
238 for (num_bytes
= 1; num_bytes
< sizeof(intptr_t); num_bytes
++) {
239 expect_equal_bytes(bytes
, blob_read_bytes(&reader
, num_bytes
),
240 num_bytes
, "unaligned read of bytes");
241 expect_equal((intptr_t) blob
, blob_read_intptr(&reader
),
242 "aligned read of intptr_t");
248 /* Test that we detect overrun. */
253 struct blob_reader reader
;
254 uint32_t value
= 0xdeadbeef;
256 blob
= blob_create();
258 blob_write_uint32(blob
, value
);
260 blob_reader_init(&reader
, blob
->data
, blob
->size
);
262 expect_equal(value
, blob_read_uint32(&reader
), "read before overrun");
263 expect_equal(false, reader
.overrun
, "overrun flag not set");
264 expect_equal(0, blob_read_uint32(&reader
), "read at overrun");
265 expect_equal(true, reader
.overrun
, "overrun flag set");
270 /* Test that we can read and write some large objects, (exercising the code in
271 * the blob_write functions to realloc blob->data.
274 test_big_objects(void)
276 void *ctx
= ralloc_context(NULL
);
278 struct blob_reader reader
;
284 blob
= blob_create();
286 /* Initialize our buffer. */
287 buf
= ralloc_size(ctx
, size
);
288 for (i
= 0; i
< size
; i
++) {
292 /* Write it many times. */
293 for (i
= 0; i
< count
; i
++) {
294 blob_write_bytes(blob
, buf
, size
);
297 blob_reader_init(&reader
, blob
->data
, blob
->size
);
299 /* Read and verify it many times. */
300 for (i
= 0; i
< count
; i
++) {
301 expect_equal_bytes((uint8_t *) buf
, blob_read_bytes(&reader
, size
), size
,
302 "read of large objects");
305 expect_equal(reader
.end
- reader
.data
, reader
.current
- reader
.data
,
306 "number of bytes read reading large objects");
308 expect_equal(false, reader
.overrun
,
309 "overrun flag not set reading large objects");
318 test_write_and_read_functions ();
323 return error
? 1 : 0;