123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * Copyright (c) 2018, Google Inc. All rights reserved.
- */
- #include <common.h>
- #include <bloblist.h>
- #include <log.h>
- #include <mapmem.h>
- #include <test/suites.h>
- #include <test/test.h>
- #include <test/ut.h>
- DECLARE_GLOBAL_DATA_PTR;
- /* Declare a new compression test */
- #define BLOBLIST_TEST(_name, _flags) \
- UNIT_TEST(_name, _flags, bloblist_test)
- enum {
- TEST_TAG = 1,
- TEST_TAG2 = 2,
- TEST_TAG_MISSING = 3,
- TEST_SIZE = 10,
- TEST_SIZE2 = 20,
- TEST_SIZE_LARGE = 0xe0,
- TEST_ADDR = CONFIG_BLOBLIST_ADDR,
- TEST_BLOBLIST_SIZE = 0x100,
- };
- static struct bloblist_hdr *clear_bloblist(void)
- {
- struct bloblist_hdr *hdr;
- /*
- * Clear out any existing bloblist so we have a clean slate. Zero the
- * header so that existing records are removed, but set everything else
- * to 0xff for testing purposes.
- */
- hdr = map_sysmem(CONFIG_BLOBLIST_ADDR, TEST_BLOBLIST_SIZE);
- memset(hdr, '\xff', TEST_BLOBLIST_SIZE);
- memset(hdr, '\0', sizeof(*hdr));
- return hdr;
- }
- static int check_zero(void *data, int size)
- {
- u8 *ptr;
- int i;
- for (ptr = data, i = 0; i < size; i++, ptr++) {
- if (*ptr)
- return -EINVAL;
- }
- return 0;
- }
- static int bloblist_test_init(struct unit_test_state *uts)
- {
- struct bloblist_hdr *hdr;
- hdr = clear_bloblist();
- ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
- hdr->version++;
- ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR,
- TEST_BLOBLIST_SIZE));
- ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0));
- ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
- ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
- ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- ut_assertok(bloblist_finish());
- ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- hdr->flags++;
- ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- return 1;
- }
- BLOBLIST_TEST(bloblist_test_init, 0);
- static int bloblist_test_blob(struct unit_test_state *uts)
- {
- struct bloblist_hdr *hdr;
- struct bloblist_rec *rec, *rec2;
- char *data;
- /* At the start there should be no records */
- hdr = clear_bloblist();
- ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
- ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
- /* Add a record and check that we can find it */
- data = bloblist_add(TEST_TAG, TEST_SIZE);
- rec = (void *)(hdr + 1);
- ut_asserteq_ptr(rec + 1, data);
- data = bloblist_find(TEST_TAG, TEST_SIZE);
- ut_asserteq_ptr(rec + 1, data);
- /* Check the data is zeroed */
- ut_assertok(check_zero(data, TEST_SIZE));
- /* Check the 'ensure' method */
- ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
- ut_assertnull(bloblist_ensure(TEST_TAG, TEST_SIZE2));
- rec2 = (struct bloblist_rec *)(data + ALIGN(TEST_SIZE, BLOBLIST_ALIGN));
- ut_assertok(check_zero(data, TEST_SIZE));
- /* Check for a non-existent record */
- ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
- ut_asserteq_ptr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2));
- ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0));
- return 0;
- }
- BLOBLIST_TEST(bloblist_test_blob, 0);
- /* Check bloblist_ensure_size_ret() */
- static int bloblist_test_blob_ensure(struct unit_test_state *uts)
- {
- void *data, *data2;
- int size;
- /* At the start there should be no records */
- clear_bloblist();
- ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
- /* Test with an empty bloblist */
- size = TEST_SIZE;
- ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data));
- ut_asserteq(TEST_SIZE, size);
- ut_assertok(check_zero(data, TEST_SIZE));
- /* Check that we get the same thing again */
- ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data2));
- ut_asserteq(TEST_SIZE, size);
- ut_asserteq_ptr(data, data2);
- /* Check that the size remains the same */
- size = TEST_SIZE2;
- ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data));
- ut_asserteq(TEST_SIZE, size);
- /* Check running out of space */
- size = TEST_SIZE_LARGE;
- ut_asserteq(-ENOSPC, bloblist_ensure_size_ret(TEST_TAG2, &size, &data));
- return 0;
- }
- BLOBLIST_TEST(bloblist_test_blob_ensure, 0);
- static int bloblist_test_bad_blob(struct unit_test_state *uts)
- {
- struct bloblist_hdr *hdr;
- void *data;
- hdr = clear_bloblist();
- ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
- data = hdr + 1;
- data += sizeof(struct bloblist_rec);
- ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
- ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
- return 0;
- }
- BLOBLIST_TEST(bloblist_test_bad_blob, 0);
- static int bloblist_test_checksum(struct unit_test_state *uts)
- {
- struct bloblist_hdr *hdr;
- char *data, *data2;
- hdr = clear_bloblist();
- ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
- ut_assertok(bloblist_finish());
- ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- /*
- * Now change things amd make sure that the checksum notices. We cannot
- * change the size or alloced fields, since that will crash the code.
- * It has to rely on these being correct.
- */
- hdr->flags--;
- ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- hdr->flags++;
- hdr->size--;
- ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- hdr->size++;
- hdr->spare++;
- ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- hdr->spare--;
- hdr->chksum++;
- ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- hdr->chksum--;
- /* Make sure the checksum changes when we add blobs */
- data = bloblist_add(TEST_TAG, TEST_SIZE);
- ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- data2 = bloblist_add(TEST_TAG2, TEST_SIZE2);
- ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- ut_assertok(bloblist_finish());
- /* It should also change if we change the data */
- ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- *data += 1;
- ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- *data -= 1;
- ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- *data2 += 1;
- ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- *data2 -= 1;
- /*
- * Changing data outside the range of valid data should not affect
- * the checksum.
- */
- ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- data[TEST_SIZE]++;
- data2[TEST_SIZE2]++;
- ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- return 0;
- }
- BLOBLIST_TEST(bloblist_test_checksum, 0);
- int do_ut_bloblist(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
- {
- struct unit_test *tests = ll_entry_start(struct unit_test,
- bloblist_test);
- const int n_ents = ll_entry_count(struct unit_test, bloblist_test);
- return cmd_ut_category("bloblist", "bloblist_test_",
- tests, n_ents, argc, argv);
- }
|