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 */
31 #include "util/ralloc.h"
34 #define bytes_test_str "bytes_test"
35 #define reserve_test_str "reserve_test"
37 /* This placeholder must be the same length as the next overwrite_test_str */
38 #define placeholder_str "XXXXXXXXXXXXXX"
39 #define overwrite_test_str "overwrite_test"
40 #define uint32_test 0x12345678
41 #define uint32_placeholder 0xDEADBEEF
42 #define uint32_overwrite 0xA1B2C3D4
43 #define uint64_test 0x1234567890ABCDEF
44 #define string_test_str "string_test"
49 expect_equal(uint64_t expected
, uint64_t actual
, const char *test
)
51 if (actual
!= expected
) {
52 fprintf (stderr
, "Error: Test '%s' failed: Expected=%ld, Actual=%ld\n",
53 test
, expected
, actual
);
59 expect_unequal(uint64_t expected
, uint64_t actual
, const char *test
)
61 if (actual
== expected
) {
62 fprintf (stderr
, "Error: Test '%s' failed: Result=%ld, but expected something different.\n",
69 expect_equal_str(const char *expected
, const char *actual
, const char *test
)
71 if (strcmp(expected
, actual
)) {
72 fprintf (stderr
, "Error: Test '%s' failed:\n\t"
73 "Expected=\"%s\", Actual=\"%s\"\n",
74 test
, expected
, actual
);
80 expect_equal_bytes(uint8_t *expected
, uint8_t *actual
,
81 size_t num_bytes
, const char *test
)
85 if (memcmp(expected
, actual
, num_bytes
)) {
86 fprintf (stderr
, "Error: Test '%s' failed:\n\t", test
);
88 fprintf (stderr
, "Expected=[");
89 for (i
= 0; i
< num_bytes
; i
++) {
91 fprintf(stderr
, ", ");
92 fprintf(stderr
, "0x%02x", expected
[i
]);
94 fprintf (stderr
, "]");
96 fprintf (stderr
, "Actual=[");
97 for (i
= 0; i
< num_bytes
; i
++) {
99 fprintf(stderr
, ", ");
100 fprintf(stderr
, "0x%02x", actual
[i
]);
102 fprintf (stderr
, "]\n");
108 /* Test at least one call of each blob_write_foo and blob_read_foo function,
109 * verifying that we read out everything we wrote, that every bytes is
110 * consumed, and that the overrun bit is not set.
113 test_write_and_read_functions (void)
115 void *ctx
= ralloc_context(NULL
);
117 struct blob_reader reader
;
119 size_t str_offset
, uint_offset
;
120 uint8_t reserve_buf
[sizeof(reserve_test_str
)];
122 blob
= blob_create(ctx
);
124 /*** Test blob by writing one of every possible kind of value. */
126 blob_write_bytes(blob
, bytes_test_str
, sizeof(bytes_test_str
));
128 reserved
= blob_reserve_bytes(blob
, sizeof(reserve_test_str
));
129 memcpy(reserved
, reserve_test_str
, sizeof(reserve_test_str
));
131 /* Write a placeholder, (to be replaced later via overwrite_bytes) */
132 str_offset
= blob
->size
;
133 blob_write_bytes(blob
, placeholder_str
, sizeof(placeholder_str
));
135 blob_write_uint32(blob
, uint32_test
);
137 /* Write a placeholder, (to be replaced later via overwrite_uint32) */
138 uint_offset
= blob
->size
;
139 blob_write_uint32(blob
, uint32_placeholder
);
141 blob_write_uint64(blob
, uint64_test
);
143 blob_write_intptr(blob
, (intptr_t) blob
);
145 blob_write_string(blob
, string_test_str
);
147 /* Finally, overwrite our placeholders. */
148 blob_overwrite_bytes(blob
, str_offset
, overwrite_test_str
,
149 sizeof(overwrite_test_str
));
150 blob_overwrite_uint32(blob
, uint_offset
, uint32_overwrite
);
152 /*** Now read each value and verify. */
153 blob_reader_init(&reader
, blob
->data
, blob
->size
);
155 expect_equal_str(bytes_test_str
,
156 blob_read_bytes(&reader
, sizeof(bytes_test_str
)),
157 "blob_write/read_bytes");
159 blob_copy_bytes(&reader
, reserve_buf
, sizeof(reserve_buf
));
160 expect_equal_str(reserve_test_str
, (char *) reserve_buf
,
161 "blob_reserve_bytes/blob_copy_bytes");
163 expect_equal_str(overwrite_test_str
,
164 blob_read_bytes(&reader
, sizeof(overwrite_test_str
)),
165 "blob_overwrite_bytes");
167 expect_equal(uint32_test
, blob_read_uint32(&reader
),
168 "blob_write/read_uint32");
169 expect_equal(uint32_overwrite
, blob_read_uint32(&reader
),
170 "blob_overwrite_uint32");
171 expect_equal(uint64_test
, blob_read_uint64(&reader
),
172 "blob_write/read_uint64");
173 expect_equal((intptr_t) blob
, blob_read_intptr(&reader
),
174 "blob_write/read_intptr");
175 expect_equal_str(string_test_str
, blob_read_string(&reader
),
176 "blob_write/read_string");
178 expect_equal(reader
.end
- reader
.data
, reader
.current
- reader
.data
,
179 "read_consumes_all_bytes");
180 expect_equal(false, reader
.overrun
, "read_does_not_overrun");
185 /* Test that data values are written and read with proper alignment. */
189 void *ctx
= ralloc_context(NULL
);
191 struct blob_reader reader
;
192 uint8_t bytes
[] = "ABCDEFGHIJKLMNOP";
193 size_t delta
, last
, num_bytes
;
195 blob
= blob_create(ctx
);
197 /* First, write an intptr value to the blob and capture that size. This is
198 * the expected offset between any pair of intptr values (if written with
201 blob_write_intptr(blob
, (intptr_t) blob
);
206 /* Then loop doing the following:
208 * 1. Write an unaligned number of bytes
209 * 2. Verify that write results in an unaligned size
210 * 3. Write an intptr_t value
211 * 2. Verify that that write results in an aligned size
213 for (num_bytes
= 1; num_bytes
< sizeof(intptr_t); num_bytes
++) {
214 blob_write_bytes(blob
, bytes
, num_bytes
);
216 expect_unequal(delta
, blob
->size
- last
, "unaligned write of bytes");
218 blob_write_intptr(blob
, (intptr_t) blob
);
220 expect_equal(2 * delta
, blob
->size
- last
, "aligned write of intptr");
225 /* Finally, test that reading also does proper alignment. Since we know
226 * that values were written with all the right alignment, all we have to do
227 * here is verify that correct values are read.
229 blob_reader_init(&reader
, blob
->data
, blob
->size
);
231 expect_equal((intptr_t) blob
, blob_read_intptr(&reader
),
232 "read of initial, aligned intptr_t");
234 for (num_bytes
= 1; num_bytes
< sizeof(intptr_t); num_bytes
++) {
235 expect_equal_bytes(bytes
, blob_read_bytes(&reader
, num_bytes
),
236 num_bytes
, "unaligned read of bytes");
237 expect_equal((intptr_t) blob
, blob_read_intptr(&reader
),
238 "aligned read of intptr_t");
244 /* Test that we detect overrun. */
248 void *ctx
=ralloc_context(NULL
);
250 struct blob_reader reader
;
251 uint32_t value
= 0xdeadbeef;
253 blob
= blob_create(ctx
);
255 blob_write_uint32(blob
, value
);
257 blob_reader_init(&reader
, blob
->data
, blob
->size
);
259 expect_equal(value
, blob_read_uint32(&reader
), "read before overrun");
260 expect_equal(false, reader
.overrun
, "overrun flag not set");
261 expect_equal(0, blob_read_uint32(&reader
), "read at overrun");
262 expect_equal(true, reader
.overrun
, "overrun flag set");
267 /* Test that we can read and write some large objects, (exercising the code in
268 * the blob_write functions to realloc blob->data.
271 test_big_objects(void)
273 void *ctx
= ralloc_context(NULL
);
275 struct blob_reader reader
;
281 blob
= blob_create(ctx
);
283 /* Initialize our buffer. */
284 buf
= ralloc_size(ctx
, size
);
285 for (i
= 0; i
< size
; i
++) {
289 /* Write it many times. */
290 for (i
= 0; i
< count
; i
++) {
291 blob_write_bytes(blob
, buf
, size
);
294 blob_reader_init(&reader
, blob
->data
, blob
->size
);
296 /* Read and verify it many times. */
297 for (i
= 0; i
< count
; i
++) {
298 expect_equal_bytes((uint8_t *) buf
, blob_read_bytes(&reader
, size
), size
,
299 "read of large objects");
302 expect_equal(reader
.end
- reader
.data
, reader
.current
- reader
.data
,
303 "number of bytes read reading large objects");
305 expect_equal(false, reader
.overrun
,
306 "overrun flag not set reading large objects");
314 test_write_and_read_functions ();
319 return error
? 1 : 0;