blob: c78b58ea2936f0e8094ff6a13ebca8a155f23f17 [file] [log] [blame]
Simon Glass78b0ef52018-11-15 18:43:53 -07001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2018, Google Inc. All rights reserved.
4 */
5
6#include <common.h>
7#include <bloblist.h>
8#include <log.h>
9#include <mapmem.h>
10#include <test/suites.h>
11#include <test/test.h>
12#include <test/ut.h>
13
14DECLARE_GLOBAL_DATA_PTR;
15
16/* Declare a new compression test */
17#define BLOBLIST_TEST(_name, _flags) \
18 UNIT_TEST(_name, _flags, bloblist_test)
19
20enum {
21 TEST_TAG = 1,
22 TEST_TAG2 = 2,
23 TEST_TAG_MISSING = 3,
24
25 TEST_SIZE = 10,
26 TEST_SIZE2 = 20,
Simon Glass1e0304e2020-01-27 08:49:50 -070027 TEST_SIZE_LARGE = 0xe0,
Simon Glass78b0ef52018-11-15 18:43:53 -070028
29 TEST_ADDR = CONFIG_BLOBLIST_ADDR,
30 TEST_BLOBLIST_SIZE = 0x100,
31};
32
33static struct bloblist_hdr *clear_bloblist(void)
34{
35 struct bloblist_hdr *hdr;
36
37 /* Clear out any existing bloblist so we have a clean slate */
38 hdr = map_sysmem(CONFIG_BLOBLIST_ADDR, TEST_BLOBLIST_SIZE);
39 memset(hdr, '\0', TEST_BLOBLIST_SIZE);
40
41 return hdr;
42}
43
44static int bloblist_test_init(struct unit_test_state *uts)
45{
46 struct bloblist_hdr *hdr;
47
48 hdr = clear_bloblist();
49 ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
50 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
51 hdr->version++;
52 ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR,
53 TEST_BLOBLIST_SIZE));
54
55 ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0));
56 ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
57 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
58
59 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
60 ut_assertok(bloblist_finish());
61 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
62 hdr->flags++;
63 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
64
65 return 1;
66}
67BLOBLIST_TEST(bloblist_test_init, 0);
68
69static int bloblist_test_blob(struct unit_test_state *uts)
70{
71 struct bloblist_hdr *hdr;
72 struct bloblist_rec *rec, *rec2;
73 char *data;
74
75 /* At the start there should be no records */
76 hdr = clear_bloblist();
77 ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
78 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
79
80 /* Add a record and check that we can find it */
81 data = bloblist_add(TEST_TAG, TEST_SIZE);
82 rec = (void *)(hdr + 1);
83 ut_asserteq_ptr(rec + 1, data);
84 data = bloblist_find(TEST_TAG, TEST_SIZE);
85 ut_asserteq_ptr(rec + 1, data);
86
87 /* Check the 'ensure' method */
88 ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
89 ut_assertnull(bloblist_ensure(TEST_TAG, TEST_SIZE2));
90 rec2 = (struct bloblist_rec *)(data + ALIGN(TEST_SIZE, BLOBLIST_ALIGN));
91
92 /* Check for a non-existent record */
93 ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
94 ut_asserteq_ptr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2));
95 ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0));
96
97 return 0;
98}
99BLOBLIST_TEST(bloblist_test_blob, 0);
100
Simon Glass1e0304e2020-01-27 08:49:50 -0700101/* Check bloblist_ensure_size_ret() */
102static int bloblist_test_blob_ensure(struct unit_test_state *uts)
103{
104 void *data, *data2;
105 int size;
106
107 /* At the start there should be no records */
108 clear_bloblist();
109 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
110
111 /* Test with an empty bloblist */
112 size = TEST_SIZE;
113 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data));
114 ut_asserteq(TEST_SIZE, size);
115
116 /* Check that we get the same thing again */
117 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data2));
118 ut_asserteq(TEST_SIZE, size);
119 ut_asserteq_ptr(data, data2);
120
121 /* Check that the size remains the same */
122 size = TEST_SIZE2;
123 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data));
124 ut_asserteq(TEST_SIZE, size);
125
126 /* Check running out of space */
127 size = TEST_SIZE_LARGE;
128 ut_asserteq(-ENOSPC, bloblist_ensure_size_ret(TEST_TAG2, &size, &data));
129
130 return 0;
131}
132BLOBLIST_TEST(bloblist_test_blob_ensure, 0);
133
Simon Glass78b0ef52018-11-15 18:43:53 -0700134static int bloblist_test_bad_blob(struct unit_test_state *uts)
135{
136 struct bloblist_hdr *hdr;
137 void *data;
138
139 hdr = clear_bloblist();
140 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
141 data = hdr + 1;
142 data += sizeof(struct bloblist_rec);
143 ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
144 ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
145
146 return 0;
147}
148BLOBLIST_TEST(bloblist_test_bad_blob, 0);
149
150static int bloblist_test_checksum(struct unit_test_state *uts)
151{
152 struct bloblist_hdr *hdr;
153 char *data, *data2;
154
155 hdr = clear_bloblist();
156 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
157 ut_assertok(bloblist_finish());
158 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
159
160 /*
161 * Now change things amd make sure that the checksum notices. We cannot
162 * change the size or alloced fields, since that will crash the code.
163 * It has to rely on these being correct.
164 */
165 hdr->flags--;
166 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
167 hdr->flags++;
168
169 hdr->size--;
170 ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
171 hdr->size++;
172
173 hdr->spare++;
174 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
175 hdr->spare--;
176
177 hdr->chksum++;
178 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
179 hdr->chksum--;
180
181 /* Make sure the checksum changes when we add blobs */
182 data = bloblist_add(TEST_TAG, TEST_SIZE);
183 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
184
185 data2 = bloblist_add(TEST_TAG2, TEST_SIZE2);
186 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
187 ut_assertok(bloblist_finish());
188
189 /* It should also change if we change the data */
190 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
191 *data += 1;
192 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
193 *data -= 1;
194
195 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
196 *data2 += 1;
197 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
198 *data2 -= 1;
199
200 /*
201 * Changing data outside the range of valid data should not affect
202 * the checksum.
203 */
204 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
205 data[TEST_SIZE]++;
206 data2[TEST_SIZE2]++;
207 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
208
209 return 0;
210}
211
212BLOBLIST_TEST(bloblist_test_checksum, 0);
213
214int do_ut_bloblist(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
215{
216 struct unit_test *tests = ll_entry_start(struct unit_test,
217 bloblist_test);
218 const int n_ents = ll_entry_count(struct unit_test, bloblist_test);
219
Philippe Reynes1f99f842019-12-17 19:07:04 +0100220 return cmd_ut_category("bloblist", "bloblist_test_",
221 tests, n_ents, argc, argv);
Simon Glass78b0ef52018-11-15 18:43:53 -0700222}