summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2021-07-06 01:32:53 +0300
committerSimon Glass <sjg@chromium.org>2021-07-21 19:27:34 +0300
commit1fe59375498fb84cd9ab72cf1f7f89437cd24cf4 (patch)
tree89be56988d867198dec854907c36e764010ce6be /test
parent56dae9ef3c56a7de6ed4af5efb82e661329d4738 (diff)
downloadu-boot-1fe59375498fb84cd9ab72cf1f7f89437cd24cf4.tar.xz
bloblist: Support resizing a blob
Sometimes a blob needs to expand, e.g. because it needs to hold more log data. Add support for this. Note that the bloblist must have sufficient spare space for this to work. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'test')
-rw-r--r--test/bloblist.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/test/bloblist.c b/test/bloblist.c
index d876b63918..345eb181ff 100644
--- a/test/bloblist.c
+++ b/test/bloblist.c
@@ -33,6 +33,9 @@ enum {
ERASE_BYTE = '\xff',
};
+static const char test1_str[] = "the eyes are open";
+static const char test2_str[] = "the mouth moves";
+
static struct bloblist_hdr *clear_bloblist(void)
{
struct bloblist_hdr *hdr;
@@ -384,6 +387,195 @@ static int bloblist_test_reloc(struct unit_test_state *uts)
}
BLOBLIST_TEST(bloblist_test_reloc, 0);
+/* Test expansion of a blob */
+static int bloblist_test_grow(struct unit_test_state *uts)
+{
+ const uint small_size = 0x20;
+ void *blob1, *blob2, *blob1_new;
+ struct bloblist_hdr *hdr;
+ void *ptr;
+
+ ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
+ hdr = ptr;
+ memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE);
+
+ /* Create two blobs */
+ ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+ blob1 = bloblist_add(TEST_TAG, small_size, 0);
+ ut_assertnonnull(blob1);
+ ut_assertok(check_zero(blob1, small_size));
+ strcpy(blob1, test1_str);
+
+ blob2 = bloblist_add(TEST_TAG2, small_size, 0);
+ ut_assertnonnull(blob2);
+ strcpy(blob2, test2_str);
+
+ ut_asserteq(sizeof(struct bloblist_hdr) +
+ sizeof(struct bloblist_rec) * 2 + small_size * 2,
+ hdr->alloced);
+
+ /* Resize the first one */
+ ut_assertok(bloblist_resize(TEST_TAG, small_size + 4));
+
+ /* The first one should not have moved, just got larger */
+ blob1_new = bloblist_find(TEST_TAG, small_size + 4);
+ ut_asserteq_ptr(blob1, blob1_new);
+
+ /* The new space should be zeroed */
+ ut_assertok(check_zero(blob1 + small_size, 4));
+
+ /* The second one should have moved */
+ blob2 = bloblist_find(TEST_TAG2, small_size);
+ ut_assertnonnull(blob2);
+ ut_asserteq_str(test2_str, blob2);
+
+ /* The header should have more bytes in use */
+ hdr = ptr;
+ ut_asserteq(sizeof(struct bloblist_hdr) +
+ sizeof(struct bloblist_rec) * 2 + small_size * 2 +
+ BLOBLIST_ALIGN,
+ hdr->alloced);
+
+ return 0;
+}
+BLOBLIST_TEST(bloblist_test_grow, 0);
+
+/* Test shrinking of a blob */
+static int bloblist_test_shrink(struct unit_test_state *uts)
+{
+ const uint small_size = 0x20;
+ void *blob1, *blob2, *blob1_new;
+ struct bloblist_hdr *hdr;
+ int new_size;
+ void *ptr;
+
+ ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
+
+ /* Create two blobs */
+ ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+ blob1 = bloblist_add(TEST_TAG, small_size, 0);
+ ut_assertnonnull(blob1);
+ strcpy(blob1, test1_str);
+
+ blob2 = bloblist_add(TEST_TAG2, small_size, 0);
+ ut_assertnonnull(blob2);
+ strcpy(blob2, test2_str);
+
+ hdr = ptr;
+ ut_asserteq(sizeof(struct bloblist_hdr) +
+ sizeof(struct bloblist_rec) * 2 + small_size * 2,
+ hdr->alloced);
+
+ /* Resize the first one */
+ new_size = small_size - BLOBLIST_ALIGN - 4;
+ ut_assertok(bloblist_resize(TEST_TAG, new_size));
+
+ /* The first one should not have moved, just got smaller */
+ blob1_new = bloblist_find(TEST_TAG, new_size);
+ ut_asserteq_ptr(blob1, blob1_new);
+
+ /* The second one should have moved */
+ blob2 = bloblist_find(TEST_TAG2, small_size);
+ ut_assertnonnull(blob2);
+ ut_asserteq_str(test2_str, blob2);
+
+ /* The header should have fewer bytes in use */
+ hdr = ptr;
+ ut_asserteq(sizeof(struct bloblist_hdr) +
+ sizeof(struct bloblist_rec) * 2 + small_size * 2 -
+ BLOBLIST_ALIGN,
+ hdr->alloced);
+
+ return 0;
+}
+BLOBLIST_TEST(bloblist_test_shrink, 0);
+
+/* Test failing to adjust a blob size */
+static int bloblist_test_resize_fail(struct unit_test_state *uts)
+{
+ const uint small_size = 0x20;
+ struct bloblist_hdr *hdr;
+ void *blob1, *blob2;
+ int new_size;
+ void *ptr;
+
+ ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
+
+ /* Create two blobs */
+ ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+ blob1 = bloblist_add(TEST_TAG, small_size, 0);
+ ut_assertnonnull(blob1);
+
+ blob2 = bloblist_add(TEST_TAG2, small_size, 0);
+ ut_assertnonnull(blob2);
+
+ hdr = ptr;
+ ut_asserteq(sizeof(struct bloblist_hdr) +
+ sizeof(struct bloblist_rec) * 2 + small_size * 2,
+ hdr->alloced);
+
+ /* Resize the first one, to check the boundary conditions */
+ ut_asserteq(-EINVAL, bloblist_resize(TEST_TAG, -1));
+
+ new_size = small_size + (hdr->size - hdr->alloced);
+ ut_asserteq(-ENOSPC, bloblist_resize(TEST_TAG, new_size + 1));
+ ut_assertok(bloblist_resize(TEST_TAG, new_size));
+
+ return 0;
+}
+BLOBLIST_TEST(bloblist_test_resize_fail, 0);
+
+/* Test expanding the last blob in a bloblist */
+static int bloblist_test_resize_last(struct unit_test_state *uts)
+{
+ const uint small_size = 0x20;
+ struct bloblist_hdr *hdr;
+ void *blob1, *blob2, *blob2_new;
+ int alloced_val;
+ void *ptr;
+
+ ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
+ memset(ptr, ERASE_BYTE, TEST_BLOBLIST_SIZE);
+ hdr = ptr;
+
+ /* Create two blobs */
+ ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+ blob1 = bloblist_add(TEST_TAG, small_size, 0);
+ ut_assertnonnull(blob1);
+
+ blob2 = bloblist_add(TEST_TAG2, small_size, 0);
+ ut_assertnonnull(blob2);
+
+ /* Check the byte after the last blob */
+ alloced_val = sizeof(struct bloblist_hdr) +
+ sizeof(struct bloblist_rec) * 2 + small_size * 2;
+ ut_asserteq(alloced_val, hdr->alloced);
+ ut_asserteq_ptr((void *)hdr + alloced_val, blob2 + small_size);
+ ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->alloced));
+
+ /* Resize the second one, checking nothing changes */
+ ut_asserteq(0, bloblist_resize(TEST_TAG2, small_size + 4));
+
+ blob2_new = bloblist_find(TEST_TAG2, small_size + 4);
+ ut_asserteq_ptr(blob2, blob2_new);
+
+ /*
+ * the new blob should encompass the byte we checked now, so it should
+ * be zeroed. This zeroing should affect only the four new bytes added
+ * to the blob.
+ */
+ ut_asserteq(0, *((u8 *)hdr + alloced_val));
+ ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + alloced_val + 4));
+
+ /* Check that the new top of the allocated blobs has not been touched */
+ alloced_val += BLOBLIST_ALIGN;
+ ut_asserteq(alloced_val, hdr->alloced);
+ ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->alloced));
+
+ return 0;
+}
+BLOBLIST_TEST(bloblist_test_resize_last, 0);
+
int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{