Merge branch '2020-01-07-master-imports'
[platform/kernel/u-boot.git] / test / bloblist.c
1 // 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
14 DECLARE_GLOBAL_DATA_PTR;
15
16 /* Declare a new compression test */
17 #define BLOBLIST_TEST(_name, _flags) \
18                 UNIT_TEST(_name, _flags, bloblist_test)
19
20 enum {
21         TEST_TAG                = 1,
22         TEST_TAG2               = 2,
23         TEST_TAG_MISSING        = 3,
24
25         TEST_SIZE               = 10,
26         TEST_SIZE2              = 20,
27
28         TEST_ADDR               = CONFIG_BLOBLIST_ADDR,
29         TEST_BLOBLIST_SIZE      = 0x100,
30 };
31
32 static struct bloblist_hdr *clear_bloblist(void)
33 {
34         struct bloblist_hdr *hdr;
35
36         /* Clear out any existing bloblist so we have a clean slate */
37         hdr = map_sysmem(CONFIG_BLOBLIST_ADDR, TEST_BLOBLIST_SIZE);
38         memset(hdr, '\0', TEST_BLOBLIST_SIZE);
39
40         return hdr;
41 }
42
43 static int bloblist_test_init(struct unit_test_state *uts)
44 {
45         struct bloblist_hdr *hdr;
46
47         hdr = clear_bloblist();
48         ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
49         ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
50         hdr->version++;
51         ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR,
52                                                      TEST_BLOBLIST_SIZE));
53
54         ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0));
55         ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
56         ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
57
58         ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
59         ut_assertok(bloblist_finish());
60         ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
61         hdr->flags++;
62         ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
63
64         return 1;
65 }
66 BLOBLIST_TEST(bloblist_test_init, 0);
67
68 static int bloblist_test_blob(struct unit_test_state *uts)
69 {
70         struct bloblist_hdr *hdr;
71         struct bloblist_rec *rec, *rec2;
72         char *data;
73
74         /* At the start there should be no records */
75         hdr = clear_bloblist();
76         ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
77         ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
78
79         /* Add a record and check that we can find it */
80         data = bloblist_add(TEST_TAG, TEST_SIZE);
81         rec = (void *)(hdr + 1);
82         ut_asserteq_ptr(rec + 1, data);
83         data = bloblist_find(TEST_TAG, TEST_SIZE);
84         ut_asserteq_ptr(rec + 1, data);
85
86         /* Check the 'ensure' method */
87         ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
88         ut_assertnull(bloblist_ensure(TEST_TAG, TEST_SIZE2));
89         rec2 = (struct bloblist_rec *)(data + ALIGN(TEST_SIZE, BLOBLIST_ALIGN));
90
91         /* Check for a non-existent record */
92         ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
93         ut_asserteq_ptr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2));
94         ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0));
95
96         return 0;
97 }
98 BLOBLIST_TEST(bloblist_test_blob, 0);
99
100 static int bloblist_test_bad_blob(struct unit_test_state *uts)
101 {
102         struct bloblist_hdr *hdr;
103         void *data;
104
105         hdr = clear_bloblist();
106         ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
107         data = hdr + 1;
108         data += sizeof(struct bloblist_rec);
109         ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
110         ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
111
112         return 0;
113 }
114 BLOBLIST_TEST(bloblist_test_bad_blob, 0);
115
116 static int bloblist_test_checksum(struct unit_test_state *uts)
117 {
118         struct bloblist_hdr *hdr;
119         char *data, *data2;
120
121         hdr = clear_bloblist();
122         ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
123         ut_assertok(bloblist_finish());
124         ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
125
126         /*
127          * Now change things amd make sure that the checksum notices. We cannot
128          * change the size or alloced fields, since that will crash the code.
129          * It has to rely on these being correct.
130          */
131         hdr->flags--;
132         ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
133         hdr->flags++;
134
135         hdr->size--;
136         ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
137         hdr->size++;
138
139         hdr->spare++;
140         ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
141         hdr->spare--;
142
143         hdr->chksum++;
144         ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
145         hdr->chksum--;
146
147         /* Make sure the checksum changes when we add blobs */
148         data = bloblist_add(TEST_TAG, TEST_SIZE);
149         ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
150
151         data2 = bloblist_add(TEST_TAG2, TEST_SIZE2);
152         ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
153         ut_assertok(bloblist_finish());
154
155         /* It should also change if we change the data */
156         ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
157         *data += 1;
158         ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
159         *data -= 1;
160
161         ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
162         *data2 += 1;
163         ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
164         *data2 -= 1;
165
166         /*
167          * Changing data outside the range of valid data should not affect
168          * the checksum.
169          */
170         ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
171         data[TEST_SIZE]++;
172         data2[TEST_SIZE2]++;
173         ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
174
175         return 0;
176 }
177
178 BLOBLIST_TEST(bloblist_test_checksum, 0);
179
180 int do_ut_bloblist(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
181 {
182         struct unit_test *tests = ll_entry_start(struct unit_test,
183                                                  bloblist_test);
184         const int n_ents = ll_entry_count(struct unit_test, bloblist_test);
185
186         return cmd_ut_category("bloblist", "bloblist_test_",
187                                tests, n_ents, argc, argv);
188 }