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 */
33 typedef SSIZE_T ssize_t
;
36 #include "util/ralloc.h"
39 #define bytes_test_str "bytes_test"
40 #define reserve_test_str "reserve_test"
42 /* This placeholder must be the same length as the next overwrite_test_str */
43 #define placeholder_str "XXXXXXXXXXXXXX"
44 #define overwrite_test_str "overwrite_test"
45 #define uint32_test 0x12345678
46 #define uint32_placeholder 0xDEADBEEF
47 #define uint32_overwrite 0xA1B2C3D4
48 #define uint64_test 0x1234567890ABCDEF
49 #define string_test_str "string_test"
54 expect_equal(uint64_t expected
, uint64_t actual
, const char *test
)
56 if (actual
!= expected
) {
58 "Error: Test '%s' failed: "
59 "Expected=%" PRIu64
", "
60 "Actual=%" PRIu64
"\n",
61 test
, expected
, actual
);
67 expect_unequal(uint64_t expected
, uint64_t actual
, const char *test
)
69 if (actual
== expected
) {
71 "Error: Test '%s' failed: Result=%" PRIu64
", "
72 "but expected something different.\n",
79 expect_equal_str(const char *expected
, const char *actual
, const char *test
)
81 if (strcmp(expected
, actual
)) {
82 fprintf (stderr
, "Error: Test '%s' failed:\n\t"
83 "Expected=\"%s\", Actual=\"%s\"\n",
84 test
, expected
, actual
);
90 expect_equal_bytes(uint8_t *expected
, const uint8_t *actual
,
91 size_t num_bytes
, const char *test
)
95 if (memcmp(expected
, actual
, num_bytes
)) {
96 fprintf (stderr
, "Error: Test '%s' failed:\n\t", test
);
98 fprintf (stderr
, "Expected=[");
99 for (i
= 0; i
< num_bytes
; i
++) {
101 fprintf(stderr
, ", ");
102 fprintf(stderr
, "0x%02x", expected
[i
]);
104 fprintf (stderr
, "]");
106 fprintf (stderr
, "Actual=[");
107 for (i
= 0; i
< num_bytes
; i
++) {
109 fprintf(stderr
, ", ");
110 fprintf(stderr
, "0x%02x", actual
[i
]);
112 fprintf (stderr
, "]\n");
118 /* Test at least one call of each blob_write_foo and blob_read_foo function,
119 * verifying that we read out everything we wrote, that every bytes is
120 * consumed, and that the overrun bit is not set.
123 test_write_and_read_functions (void)
126 struct blob_reader reader
;
128 size_t str_offset
, uint_offset
;
129 uint8_t reserve_buf
[sizeof(reserve_test_str
)];
133 /*** Test blob by writing one of every possible kind of value. */
135 blob_write_bytes(&blob
, bytes_test_str
, sizeof(bytes_test_str
));
137 reserved
= blob_reserve_bytes(&blob
, sizeof(reserve_test_str
));
138 blob_overwrite_bytes(&blob
, reserved
, reserve_test_str
, sizeof(reserve_test_str
));
140 /* Write a placeholder, (to be replaced later via overwrite_bytes) */
141 str_offset
= blob
.size
;
142 blob_write_bytes(&blob
, placeholder_str
, sizeof(placeholder_str
));
144 blob_write_uint32(&blob
, uint32_test
);
146 /* Write a placeholder, (to be replaced later via overwrite_uint32) */
147 uint_offset
= blob
.size
;
148 blob_write_uint32(&blob
, uint32_placeholder
);
150 blob_write_uint64(&blob
, uint64_test
);
152 blob_write_intptr(&blob
, (intptr_t) &blob
);
154 blob_write_string(&blob
, string_test_str
);
156 /* Finally, overwrite our placeholders. */
157 blob_overwrite_bytes(&blob
, str_offset
, overwrite_test_str
,
158 sizeof(overwrite_test_str
));
159 blob_overwrite_uint32(&blob
, uint_offset
, uint32_overwrite
);
161 /*** Now read each value and verify. */
162 blob_reader_init(&reader
, blob
.data
, blob
.size
);
164 expect_equal_str(bytes_test_str
,
165 blob_read_bytes(&reader
, sizeof(bytes_test_str
)),
166 "blob_write/read_bytes");
168 blob_copy_bytes(&reader
, reserve_buf
, sizeof(reserve_buf
));
169 expect_equal_str(reserve_test_str
, (char *) reserve_buf
,
170 "blob_reserve_bytes/blob_copy_bytes");
172 expect_equal_str(overwrite_test_str
,
173 blob_read_bytes(&reader
, sizeof(overwrite_test_str
)),
174 "blob_overwrite_bytes");
176 expect_equal(uint32_test
, blob_read_uint32(&reader
),
177 "blob_write/read_uint32");
178 expect_equal(uint32_overwrite
, blob_read_uint32(&reader
),
179 "blob_overwrite_uint32");
180 expect_equal(uint64_test
, blob_read_uint64(&reader
),
181 "blob_write/read_uint64");
182 expect_equal((intptr_t) &blob
, blob_read_intptr(&reader
),
183 "blob_write/read_intptr");
184 expect_equal_str(string_test_str
, blob_read_string(&reader
),
185 "blob_write/read_string");
187 expect_equal(reader
.end
- reader
.data
, reader
.current
- reader
.data
,
188 "read_consumes_all_bytes");
189 expect_equal(false, reader
.overrun
, "read_does_not_overrun");
194 /* Test that data values are written and read with proper alignment. */
199 struct blob_reader reader
;
200 uint8_t bytes
[] = "ABCDEFGHIJKLMNOP";
201 size_t delta
, last
, num_bytes
;
205 /* First, write an intptr value to the blob and capture that size. This is
206 * the expected offset between any pair of intptr values (if written with
209 blob_write_intptr(&blob
, (intptr_t) &blob
);
214 /* Then loop doing the following:
216 * 1. Write an unaligned number of bytes
217 * 2. Verify that write results in an unaligned size
218 * 3. Write an intptr_t value
219 * 2. Verify that that write results in an aligned size
221 for (num_bytes
= 1; num_bytes
< sizeof(intptr_t); num_bytes
++) {
222 blob_write_bytes(&blob
, bytes
, num_bytes
);
224 expect_unequal(delta
, blob
.size
- last
, "unaligned write of bytes");
226 blob_write_intptr(&blob
, (intptr_t) &blob
);
228 expect_equal(2 * delta
, blob
.size
- last
, "aligned write of intptr");
233 /* Finally, test that reading also does proper alignment. Since we know
234 * that values were written with all the right alignment, all we have to do
235 * here is verify that correct values are read.
237 blob_reader_init(&reader
, blob
.data
, blob
.size
);
239 expect_equal((intptr_t) &blob
, blob_read_intptr(&reader
),
240 "read of initial, aligned intptr_t");
242 for (num_bytes
= 1; num_bytes
< sizeof(intptr_t); num_bytes
++) {
243 expect_equal_bytes(bytes
, blob_read_bytes(&reader
, num_bytes
),
244 num_bytes
, "unaligned read of bytes");
245 expect_equal((intptr_t) &blob
, blob_read_intptr(&reader
),
246 "aligned read of intptr_t");
252 /* Test that we detect overrun. */
257 struct blob_reader reader
;
258 uint32_t value
= 0xdeadbeef;
262 blob_write_uint32(&blob
, value
);
264 blob_reader_init(&reader
, blob
.data
, blob
.size
);
266 expect_equal(value
, blob_read_uint32(&reader
), "read before overrun");
267 expect_equal(false, reader
.overrun
, "overrun flag not set");
268 expect_equal(0, blob_read_uint32(&reader
), "read at overrun");
269 expect_equal(true, reader
.overrun
, "overrun flag set");
274 /* Test that we can read and write some large objects, (exercising the code in
275 * the blob_write functions to realloc blob->data.
278 test_big_objects(void)
280 void *ctx
= ralloc_context(NULL
);
282 struct blob_reader reader
;
290 /* Initialize our buffer. */
291 buf
= ralloc_size(ctx
, size
);
292 for (i
= 0; i
< size
; i
++) {
296 /* Write it many times. */
297 for (i
= 0; i
< count
; i
++) {
298 blob_write_bytes(&blob
, buf
, size
);
301 blob_reader_init(&reader
, blob
.data
, blob
.size
);
303 /* Read and verify it many times. */
304 for (i
= 0; i
< count
; i
++) {
305 expect_equal_bytes((uint8_t *) buf
, blob_read_bytes(&reader
, size
), size
,
306 "read of large objects");
309 expect_equal(reader
.end
- reader
.data
, reader
.current
- reader
.data
,
310 "number of bytes read reading large objects");
312 expect_equal(false, reader
.overrun
,
313 "overrun flag not set reading large objects");
322 test_write_and_read_functions ();
327 return error
? 1 : 0;