xref: /aosp_15_r20/external/mesa3d/src/util/tests/blob_test.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2014 Intel Corporation
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #include <inttypes.h>
25*61046927SAndroid Build Coastguard Worker #include <stdio.h>
26*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
27*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
28*61046927SAndroid Build Coastguard Worker #include <string.h>
29*61046927SAndroid Build Coastguard Worker #ifdef _MSC_VER
30*61046927SAndroid Build Coastguard Worker #include <BaseTsd.h>
31*61046927SAndroid Build Coastguard Worker typedef SSIZE_T ssize_t;
32*61046927SAndroid Build Coastguard Worker #endif
33*61046927SAndroid Build Coastguard Worker 
34*61046927SAndroid Build Coastguard Worker #include "util/ralloc.h"
35*61046927SAndroid Build Coastguard Worker #include "blob.h"
36*61046927SAndroid Build Coastguard Worker 
37*61046927SAndroid Build Coastguard Worker #include <gtest/gtest.h>
38*61046927SAndroid Build Coastguard Worker #include "mesa-gtest-extras.h"
39*61046927SAndroid Build Coastguard Worker 
40*61046927SAndroid Build Coastguard Worker #define bytes_test_str     "bytes_test"
41*61046927SAndroid Build Coastguard Worker #define reserve_test_str   "reserve_test"
42*61046927SAndroid Build Coastguard Worker 
43*61046927SAndroid Build Coastguard Worker // This placeholder must be the same length as the next overwrite_test_str.
44*61046927SAndroid Build Coastguard Worker #define placeholder_str    "XXXXXXXXXXXXXX"
45*61046927SAndroid Build Coastguard Worker #define overwrite_test_str "overwrite_test"
46*61046927SAndroid Build Coastguard Worker #define uint32_test        0x12345678
47*61046927SAndroid Build Coastguard Worker #define uint32_placeholder 0xDEADBEEF
48*61046927SAndroid Build Coastguard Worker #define uint32_overwrite   0xA1B2C3D4
49*61046927SAndroid Build Coastguard Worker #define uint64_test        0x1234567890ABCDEF
50*61046927SAndroid Build Coastguard Worker #define string_test_str    "string_test"
51*61046927SAndroid Build Coastguard Worker 
52*61046927SAndroid Build Coastguard Worker 
53*61046927SAndroid Build Coastguard Worker // Test at least one call of each blob_write_foo and blob_read_foo function,
54*61046927SAndroid Build Coastguard Worker // verifying that we read out everything we wrote, that every bytes is
55*61046927SAndroid Build Coastguard Worker // consumed, and that the overrun bit is not set.
TEST(BlobTest,WriteAndReadFunctions)56*61046927SAndroid Build Coastguard Worker TEST(BlobTest, WriteAndReadFunctions)
57*61046927SAndroid Build Coastguard Worker {
58*61046927SAndroid Build Coastguard Worker    struct blob blob;
59*61046927SAndroid Build Coastguard Worker    struct blob_reader reader;
60*61046927SAndroid Build Coastguard Worker    ssize_t reserved;
61*61046927SAndroid Build Coastguard Worker    size_t str_offset, uint_offset;
62*61046927SAndroid Build Coastguard Worker    uint8_t reserve_buf[sizeof(reserve_test_str)];
63*61046927SAndroid Build Coastguard Worker 
64*61046927SAndroid Build Coastguard Worker    blob_init(&blob);
65*61046927SAndroid Build Coastguard Worker 
66*61046927SAndroid Build Coastguard Worker    // Test blob by writing one of every possible kind of value.
67*61046927SAndroid Build Coastguard Worker 
68*61046927SAndroid Build Coastguard Worker    blob_write_bytes(&blob, bytes_test_str, sizeof(bytes_test_str));
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker    reserved = blob_reserve_bytes(&blob, sizeof(reserve_test_str));
71*61046927SAndroid Build Coastguard Worker    blob_overwrite_bytes(&blob, reserved, reserve_test_str, sizeof(reserve_test_str));
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker    // Write a placeholder, (to be replaced later via overwrite_bytes).
74*61046927SAndroid Build Coastguard Worker    str_offset = blob.size;
75*61046927SAndroid Build Coastguard Worker    blob_write_bytes(&blob, placeholder_str, sizeof(placeholder_str));
76*61046927SAndroid Build Coastguard Worker 
77*61046927SAndroid Build Coastguard Worker    blob_write_uint32(&blob, uint32_test);
78*61046927SAndroid Build Coastguard Worker 
79*61046927SAndroid Build Coastguard Worker    // Write a placeholder, (to be replaced later via overwrite_uint32).
80*61046927SAndroid Build Coastguard Worker    uint_offset = blob.size;
81*61046927SAndroid Build Coastguard Worker    blob_write_uint32(&blob, uint32_placeholder);
82*61046927SAndroid Build Coastguard Worker 
83*61046927SAndroid Build Coastguard Worker    blob_write_uint64(&blob, uint64_test);
84*61046927SAndroid Build Coastguard Worker 
85*61046927SAndroid Build Coastguard Worker    blob_write_intptr(&blob, (intptr_t) &blob);
86*61046927SAndroid Build Coastguard Worker 
87*61046927SAndroid Build Coastguard Worker    blob_write_string(&blob, string_test_str);
88*61046927SAndroid Build Coastguard Worker 
89*61046927SAndroid Build Coastguard Worker    // Finally, overwrite our placeholders.
90*61046927SAndroid Build Coastguard Worker    blob_overwrite_bytes(&blob, str_offset, overwrite_test_str,
91*61046927SAndroid Build Coastguard Worker                         sizeof(overwrite_test_str));
92*61046927SAndroid Build Coastguard Worker    blob_overwrite_uint32(&blob, uint_offset, uint32_overwrite);
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker    // Now read each value and verify.
95*61046927SAndroid Build Coastguard Worker 
96*61046927SAndroid Build Coastguard Worker    blob_reader_init(&reader, blob.data, blob.size);
97*61046927SAndroid Build Coastguard Worker 
98*61046927SAndroid Build Coastguard Worker    EXPECT_STREQ(bytes_test_str,
99*61046927SAndroid Build Coastguard Worker                 (const char *)blob_read_bytes(&reader, sizeof(bytes_test_str))) <<
100*61046927SAndroid Build Coastguard Worker                 "blob_write/read_bytes";
101*61046927SAndroid Build Coastguard Worker 
102*61046927SAndroid Build Coastguard Worker    blob_copy_bytes(&reader, reserve_buf, sizeof(reserve_buf));
103*61046927SAndroid Build Coastguard Worker 
104*61046927SAndroid Build Coastguard Worker    EXPECT_STREQ(reserve_test_str, (char *) reserve_buf)
105*61046927SAndroid Build Coastguard Worker       << "blob_reserve_bytes/blob_copy_bytes";
106*61046927SAndroid Build Coastguard Worker 
107*61046927SAndroid Build Coastguard Worker    EXPECT_STREQ(overwrite_test_str,
108*61046927SAndroid Build Coastguard Worker                 (const char *) blob_read_bytes(&reader, sizeof(overwrite_test_str)))
109*61046927SAndroid Build Coastguard Worker       << "blob_overwrite_bytes";
110*61046927SAndroid Build Coastguard Worker 
111*61046927SAndroid Build Coastguard Worker    EXPECT_EQ(uint32_test, blob_read_uint32(&reader)) << "blob_write/read_uint32";
112*61046927SAndroid Build Coastguard Worker    EXPECT_EQ(uint32_overwrite, blob_read_uint32(&reader)) << "blob_overwrite_uint32";
113*61046927SAndroid Build Coastguard Worker    EXPECT_EQ(uint64_test, blob_read_uint64(&reader)) << "blob_write/read_uint64";
114*61046927SAndroid Build Coastguard Worker    EXPECT_EQ((intptr_t) &blob, blob_read_intptr(&reader)) << "blob_write/read_intptr";
115*61046927SAndroid Build Coastguard Worker 
116*61046927SAndroid Build Coastguard Worker    EXPECT_STREQ(string_test_str, blob_read_string(&reader)) << "blob_write/read_string";
117*61046927SAndroid Build Coastguard Worker 
118*61046927SAndroid Build Coastguard Worker    EXPECT_EQ(reader.end - reader.data, reader.current - reader.data) << "read_consumes_all_bytes";
119*61046927SAndroid Build Coastguard Worker    EXPECT_FALSE(reader.overrun) << "read_does_not_overrun";
120*61046927SAndroid Build Coastguard Worker 
121*61046927SAndroid Build Coastguard Worker    blob_finish(&blob);
122*61046927SAndroid Build Coastguard Worker }
123*61046927SAndroid Build Coastguard Worker 
124*61046927SAndroid Build Coastguard Worker // Test that data values are written and read with proper alignment.
TEST(BlobTest,Alignment)125*61046927SAndroid Build Coastguard Worker TEST(BlobTest, Alignment)
126*61046927SAndroid Build Coastguard Worker {
127*61046927SAndroid Build Coastguard Worker    struct blob blob;
128*61046927SAndroid Build Coastguard Worker    struct blob_reader reader;
129*61046927SAndroid Build Coastguard Worker    uint8_t bytes[] = "ABCDEFGHIJKLMNOP";
130*61046927SAndroid Build Coastguard Worker    size_t delta, last, num_bytes;
131*61046927SAndroid Build Coastguard Worker 
132*61046927SAndroid Build Coastguard Worker    blob_init(&blob);
133*61046927SAndroid Build Coastguard Worker 
134*61046927SAndroid Build Coastguard Worker    // First, write an intptr value to the blob and capture that size. This is
135*61046927SAndroid Build Coastguard Worker    // the expected offset between any pair of intptr values (if written with
136*61046927SAndroid Build Coastguard Worker    // alignment).
137*61046927SAndroid Build Coastguard Worker    blob_write_intptr(&blob, (intptr_t) &blob);
138*61046927SAndroid Build Coastguard Worker 
139*61046927SAndroid Build Coastguard Worker    delta = blob.size;
140*61046927SAndroid Build Coastguard Worker    last = blob.size;
141*61046927SAndroid Build Coastguard Worker 
142*61046927SAndroid Build Coastguard Worker    // Then loop doing the following:
143*61046927SAndroid Build Coastguard Worker    //
144*61046927SAndroid Build Coastguard Worker    //   1. Write an unaligned number of bytes
145*61046927SAndroid Build Coastguard Worker    //   2. Verify that write results in an unaligned size
146*61046927SAndroid Build Coastguard Worker    //   3. Write an intptr_t value
147*61046927SAndroid Build Coastguard Worker    //   2. Verify that that write results in an aligned size
148*61046927SAndroid Build Coastguard Worker    //
149*61046927SAndroid Build Coastguard Worker    for (num_bytes = 1; num_bytes < sizeof(intptr_t); num_bytes++) {
150*61046927SAndroid Build Coastguard Worker       blob_write_bytes(&blob, bytes, num_bytes);
151*61046927SAndroid Build Coastguard Worker 
152*61046927SAndroid Build Coastguard Worker       EXPECT_NE(delta, blob.size - last) << "unaligned write of bytes";
153*61046927SAndroid Build Coastguard Worker 
154*61046927SAndroid Build Coastguard Worker       blob_write_intptr(&blob, (intptr_t) &blob);
155*61046927SAndroid Build Coastguard Worker 
156*61046927SAndroid Build Coastguard Worker       EXPECT_EQ(2 * delta, blob.size - last) << "aligned write of intptr";
157*61046927SAndroid Build Coastguard Worker 
158*61046927SAndroid Build Coastguard Worker       last = blob.size;
159*61046927SAndroid Build Coastguard Worker    }
160*61046927SAndroid Build Coastguard Worker 
161*61046927SAndroid Build Coastguard Worker    // Finally, test that reading also does proper alignment. Since we know
162*61046927SAndroid Build Coastguard Worker    // that values were written with all the right alignment, all we have to do
163*61046927SAndroid Build Coastguard Worker    // here is verify that correct values are read.
164*61046927SAndroid Build Coastguard Worker    blob_reader_init(&reader, blob.data, blob.size);
165*61046927SAndroid Build Coastguard Worker 
166*61046927SAndroid Build Coastguard Worker    EXPECT_EQ((intptr_t) &blob, blob_read_intptr(&reader))
167*61046927SAndroid Build Coastguard Worker       << "read of initial, aligned intptr_t";
168*61046927SAndroid Build Coastguard Worker 
169*61046927SAndroid Build Coastguard Worker    for (num_bytes = 1; num_bytes < sizeof(intptr_t); num_bytes++) {
170*61046927SAndroid Build Coastguard Worker       EXPECT_U8_ARRAY_EQUAL(bytes, (const uint8_t *) blob_read_bytes(&reader, num_bytes),
171*61046927SAndroid Build Coastguard Worker                             num_bytes) << "unaligned read of bytes";
172*61046927SAndroid Build Coastguard Worker       EXPECT_EQ((intptr_t) &blob, blob_read_intptr(&reader)) << "aligned read of intptr_t";
173*61046927SAndroid Build Coastguard Worker    }
174*61046927SAndroid Build Coastguard Worker 
175*61046927SAndroid Build Coastguard Worker    blob_finish(&blob);
176*61046927SAndroid Build Coastguard Worker }
177*61046927SAndroid Build Coastguard Worker 
178*61046927SAndroid Build Coastguard Worker // Test that we detect overrun.
TEST(BlobTest,DetectOverrun)179*61046927SAndroid Build Coastguard Worker TEST(BlobTest, DetectOverrun)
180*61046927SAndroid Build Coastguard Worker {
181*61046927SAndroid Build Coastguard Worker    struct blob blob;
182*61046927SAndroid Build Coastguard Worker    struct blob_reader reader;
183*61046927SAndroid Build Coastguard Worker    uint32_t value = 0xdeadbeef;
184*61046927SAndroid Build Coastguard Worker 
185*61046927SAndroid Build Coastguard Worker    blob_init(&blob);
186*61046927SAndroid Build Coastguard Worker 
187*61046927SAndroid Build Coastguard Worker    blob_write_uint32(&blob, value);
188*61046927SAndroid Build Coastguard Worker 
189*61046927SAndroid Build Coastguard Worker    blob_reader_init(&reader, blob.data, blob.size);
190*61046927SAndroid Build Coastguard Worker 
191*61046927SAndroid Build Coastguard Worker    EXPECT_EQ(value, blob_read_uint32(&reader)) << "read before overrun";
192*61046927SAndroid Build Coastguard Worker    EXPECT_FALSE(reader.overrun);
193*61046927SAndroid Build Coastguard Worker    EXPECT_EQ(0, blob_read_uint32(&reader)) << "read at overrun";
194*61046927SAndroid Build Coastguard Worker    EXPECT_TRUE(reader.overrun);
195*61046927SAndroid Build Coastguard Worker 
196*61046927SAndroid Build Coastguard Worker    blob_finish(&blob);
197*61046927SAndroid Build Coastguard Worker }
198*61046927SAndroid Build Coastguard Worker 
199*61046927SAndroid Build Coastguard Worker // Test that we can read and write some large objects, (exercising the code in
200*61046927SAndroid Build Coastguard Worker // the blob_write functions to realloc blob->data.
TEST(BlobTest,BigObjects)201*61046927SAndroid Build Coastguard Worker TEST(BlobTest, BigObjects)
202*61046927SAndroid Build Coastguard Worker {
203*61046927SAndroid Build Coastguard Worker    void *ctx = ralloc_context(NULL);
204*61046927SAndroid Build Coastguard Worker    struct blob blob;
205*61046927SAndroid Build Coastguard Worker    struct blob_reader reader;
206*61046927SAndroid Build Coastguard Worker    int size = 1000;
207*61046927SAndroid Build Coastguard Worker    int count = 1000;
208*61046927SAndroid Build Coastguard Worker    char *buf;
209*61046927SAndroid Build Coastguard Worker 
210*61046927SAndroid Build Coastguard Worker    blob_init(&blob);
211*61046927SAndroid Build Coastguard Worker 
212*61046927SAndroid Build Coastguard Worker    // Initialize our buffer.
213*61046927SAndroid Build Coastguard Worker    buf = (char *) ralloc_size(ctx, size);
214*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < size; i++) {
215*61046927SAndroid Build Coastguard Worker       buf[i] = i % 256;
216*61046927SAndroid Build Coastguard Worker    }
217*61046927SAndroid Build Coastguard Worker 
218*61046927SAndroid Build Coastguard Worker    // Write it many times.
219*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < count; i++) {
220*61046927SAndroid Build Coastguard Worker       blob_write_bytes(&blob, buf, size);
221*61046927SAndroid Build Coastguard Worker    }
222*61046927SAndroid Build Coastguard Worker 
223*61046927SAndroid Build Coastguard Worker    blob_reader_init(&reader, blob.data, blob.size);
224*61046927SAndroid Build Coastguard Worker 
225*61046927SAndroid Build Coastguard Worker    // Read and verify it many times.
226*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < count; i++) {
227*61046927SAndroid Build Coastguard Worker       EXPECT_U8_ARRAY_EQUAL((uint8_t *) buf,
228*61046927SAndroid Build Coastguard Worker                             (const uint8_t *) blob_read_bytes(&reader, size), size)
229*61046927SAndroid Build Coastguard Worker          << "read of large objects, iteration " << i;
230*61046927SAndroid Build Coastguard Worker    }
231*61046927SAndroid Build Coastguard Worker 
232*61046927SAndroid Build Coastguard Worker    EXPECT_EQ(reader.end - reader.data, reader.current - reader.data)
233*61046927SAndroid Build Coastguard Worker       << "number of bytes read reading large objects";
234*61046927SAndroid Build Coastguard Worker 
235*61046927SAndroid Build Coastguard Worker    EXPECT_FALSE(reader.overrun) << "overrun flag not set reading large objects";
236*61046927SAndroid Build Coastguard Worker 
237*61046927SAndroid Build Coastguard Worker    blob_finish(&blob);
238*61046927SAndroid Build Coastguard Worker    ralloc_free(ctx);
239*61046927SAndroid Build Coastguard Worker }
240