bloblist.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2018, Google Inc. All rights reserved.
  4. */
  5. #include <common.h>
  6. #include <bloblist.h>
  7. #include <log.h>
  8. #include <mapmem.h>
  9. #include <test/suites.h>
  10. #include <test/test.h>
  11. #include <test/ut.h>
  12. DECLARE_GLOBAL_DATA_PTR;
  13. /* Declare a new compression test */
  14. #define BLOBLIST_TEST(_name, _flags) \
  15. UNIT_TEST(_name, _flags, bloblist_test)
  16. enum {
  17. TEST_TAG = 1,
  18. TEST_TAG2 = 2,
  19. TEST_TAG_MISSING = 3,
  20. TEST_SIZE = 10,
  21. TEST_SIZE2 = 20,
  22. TEST_ADDR = CONFIG_BLOBLIST_ADDR,
  23. TEST_BLOBLIST_SIZE = 0x100,
  24. };
  25. static struct bloblist_hdr *clear_bloblist(void)
  26. {
  27. struct bloblist_hdr *hdr;
  28. /* Clear out any existing bloblist so we have a clean slate */
  29. hdr = map_sysmem(CONFIG_BLOBLIST_ADDR, TEST_BLOBLIST_SIZE);
  30. memset(hdr, '\0', TEST_BLOBLIST_SIZE);
  31. return hdr;
  32. }
  33. static int bloblist_test_init(struct unit_test_state *uts)
  34. {
  35. struct bloblist_hdr *hdr;
  36. hdr = clear_bloblist();
  37. ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  38. ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
  39. hdr->version++;
  40. ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR,
  41. TEST_BLOBLIST_SIZE));
  42. ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0));
  43. ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
  44. ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
  45. ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  46. ut_assertok(bloblist_finish());
  47. ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  48. hdr->flags++;
  49. ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  50. return 1;
  51. }
  52. BLOBLIST_TEST(bloblist_test_init, 0);
  53. static int bloblist_test_blob(struct unit_test_state *uts)
  54. {
  55. struct bloblist_hdr *hdr;
  56. struct bloblist_rec *rec, *rec2;
  57. char *data;
  58. /* At the start there should be no records */
  59. hdr = clear_bloblist();
  60. ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
  61. ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
  62. /* Add a record and check that we can find it */
  63. data = bloblist_add(TEST_TAG, TEST_SIZE);
  64. rec = (void *)(hdr + 1);
  65. ut_asserteq_ptr(rec + 1, data);
  66. data = bloblist_find(TEST_TAG, TEST_SIZE);
  67. ut_asserteq_ptr(rec + 1, data);
  68. /* Check the 'ensure' method */
  69. ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
  70. ut_assertnull(bloblist_ensure(TEST_TAG, TEST_SIZE2));
  71. rec2 = (struct bloblist_rec *)(data + ALIGN(TEST_SIZE, BLOBLIST_ALIGN));
  72. /* Check for a non-existent record */
  73. ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
  74. ut_asserteq_ptr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2));
  75. ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0));
  76. return 0;
  77. }
  78. BLOBLIST_TEST(bloblist_test_blob, 0);
  79. static int bloblist_test_bad_blob(struct unit_test_state *uts)
  80. {
  81. struct bloblist_hdr *hdr;
  82. void *data;
  83. hdr = clear_bloblist();
  84. ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
  85. data = hdr + 1;
  86. data += sizeof(struct bloblist_rec);
  87. ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
  88. ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
  89. return 0;
  90. }
  91. BLOBLIST_TEST(bloblist_test_bad_blob, 0);
  92. static int bloblist_test_checksum(struct unit_test_state *uts)
  93. {
  94. struct bloblist_hdr *hdr;
  95. char *data, *data2;
  96. hdr = clear_bloblist();
  97. ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
  98. ut_assertok(bloblist_finish());
  99. ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  100. /*
  101. * Now change things amd make sure that the checksum notices. We cannot
  102. * change the size or alloced fields, since that will crash the code.
  103. * It has to rely on these being correct.
  104. */
  105. hdr->flags--;
  106. ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  107. hdr->flags++;
  108. hdr->size--;
  109. ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  110. hdr->size++;
  111. hdr->spare++;
  112. ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  113. hdr->spare--;
  114. hdr->chksum++;
  115. ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  116. hdr->chksum--;
  117. /* Make sure the checksum changes when we add blobs */
  118. data = bloblist_add(TEST_TAG, TEST_SIZE);
  119. ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  120. data2 = bloblist_add(TEST_TAG2, TEST_SIZE2);
  121. ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  122. ut_assertok(bloblist_finish());
  123. /* It should also change if we change the data */
  124. ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  125. *data += 1;
  126. ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  127. *data -= 1;
  128. ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  129. *data2 += 1;
  130. ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  131. *data2 -= 1;
  132. /*
  133. * Changing data outside the range of valid data should not affect
  134. * the checksum.
  135. */
  136. ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  137. data[TEST_SIZE]++;
  138. data2[TEST_SIZE2]++;
  139. ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
  140. return 0;
  141. }
  142. BLOBLIST_TEST(bloblist_test_checksum, 0);
  143. int do_ut_bloblist(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
  144. {
  145. struct unit_test *tests = ll_entry_start(struct unit_test,
  146. bloblist_test);
  147. const int n_ents = ll_entry_count(struct unit_test, bloblist_test);
  148. return cmd_ut_category("bloblist", tests, n_ents, argc, argv);
  149. }