Jakub Czapiga | c1e4c5a | 2021-07-23 13:35:14 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | |
| 3 | #include <fcntl.h> |
| 4 | #include <lib.h> |
| 5 | #include <lib/lzmadecode.h> |
| 6 | #include <stdlib.h> |
| 7 | #include <string.h> |
| 8 | #include <sys/types.h> |
| 9 | #include <sys/stat.h> |
| 10 | #include <tests/test.h> |
| 11 | #include <unistd.h> |
| 12 | |
| 13 | |
| 14 | struct lzma_test_state { |
| 15 | char *raw_filename; |
| 16 | size_t raw_file_sz; |
| 17 | char *comp_filename; |
| 18 | size_t comp_file_sz; |
| 19 | }; |
| 20 | |
| 21 | static int get_file_size(const char *fname) |
| 22 | { |
| 23 | struct stat st; |
| 24 | if (stat(fname, &st) == -1) |
| 25 | return -1; |
| 26 | return st.st_size; |
| 27 | } |
| 28 | |
| 29 | static int teardown_ulzman_file(void **state) |
| 30 | { |
| 31 | struct lzma_test_state *s = *state; |
| 32 | |
| 33 | test_free(s->raw_filename); |
| 34 | test_free(s->comp_filename); |
| 35 | test_free(s); |
| 36 | |
| 37 | return 0; |
| 38 | } |
| 39 | |
| 40 | /* Set data file with prestate */ |
| 41 | static int setup_ulzman_file(void **state) |
| 42 | { |
| 43 | int ret = 0; |
| 44 | const char *fname_base = *state; |
| 45 | const char path_prefix[] = __TEST_DATA_DIR__ "/lib/lzma-test/%s%s"; |
| 46 | const char raw_file_suffix[] = ".bin"; |
| 47 | const char comp_file_suffix[] = ".lzma.bin"; |
| 48 | struct lzma_test_state *s = test_malloc(sizeof(*s)); |
| 49 | memset(s, 0, sizeof(*s)); |
| 50 | |
| 51 | if (!s) |
| 52 | return 1; |
| 53 | |
Jakub Czapiga | c08b6a7 | 2022-01-10 13:36:47 +0000 | [diff] [blame] | 54 | const size_t raw_filename_size = |
| 55 | strlen(path_prefix) + strlen(fname_base) + ARRAY_SIZE(raw_file_suffix); |
Jakub Czapiga | c1e4c5a | 2021-07-23 13:35:14 +0200 | [diff] [blame] | 56 | s->raw_filename = test_malloc(raw_filename_size); |
| 57 | |
Jakub Czapiga | c08b6a7 | 2022-01-10 13:36:47 +0000 | [diff] [blame] | 58 | const size_t comp_filename_size = |
| 59 | strlen(path_prefix) + strlen(fname_base) + ARRAY_SIZE(comp_file_suffix); |
Jakub Czapiga | c1e4c5a | 2021-07-23 13:35:14 +0200 | [diff] [blame] | 60 | s->comp_filename = test_malloc(comp_filename_size); |
| 61 | |
| 62 | if (!s->raw_filename || !s->comp_filename) { |
| 63 | print_error("File path allocation error\n"); |
| 64 | ret = 2; |
| 65 | goto error; |
| 66 | } |
| 67 | |
| 68 | snprintf(s->raw_filename, raw_filename_size, path_prefix, fname_base, raw_file_suffix); |
| 69 | snprintf(s->comp_filename, comp_filename_size, path_prefix, fname_base, |
Jakub Czapiga | c08b6a7 | 2022-01-10 13:36:47 +0000 | [diff] [blame] | 70 | comp_file_suffix); |
Jakub Czapiga | c1e4c5a | 2021-07-23 13:35:14 +0200 | [diff] [blame] | 71 | |
| 72 | s->raw_file_sz = get_file_size(s->raw_filename); |
| 73 | s->comp_file_sz = get_file_size(s->comp_filename); |
| 74 | |
| 75 | if (s->raw_file_sz == -1) { |
| 76 | print_error("Unable to open file: %s\n", s->raw_filename); |
| 77 | ret = 3; |
| 78 | goto error; |
| 79 | } |
| 80 | |
| 81 | if (s->comp_file_sz == -1) { |
| 82 | print_error("Unable to open file: %s\n", s->comp_filename); |
| 83 | ret = 3; |
| 84 | goto error; |
| 85 | } |
| 86 | |
| 87 | *state = s; |
| 88 | return 0; |
| 89 | error: |
| 90 | teardown_ulzman_file((void **)&s); |
| 91 | return ret; |
| 92 | } |
| 93 | |
| 94 | static int read_file(const char *fname, uint8_t *buf, size_t sz) |
| 95 | { |
| 96 | int f = open(fname, O_RDONLY); |
| 97 | int read_sz = 0; |
| 98 | |
| 99 | if (f == -1) |
| 100 | return -1; |
| 101 | |
| 102 | read_sz = read(f, buf, sz); |
| 103 | |
| 104 | close(f); |
| 105 | return read_sz; |
| 106 | } |
| 107 | |
| 108 | static void test_ulzman_correct_file(void **state) |
| 109 | { |
| 110 | struct lzma_test_state *s = *state; |
| 111 | uint8_t *raw_buf = test_malloc(s->raw_file_sz); |
| 112 | uint8_t *decomp_buf = test_malloc(s->raw_file_sz); |
| 113 | uint8_t *comp_buf = test_malloc(s->comp_file_sz); |
| 114 | |
| 115 | assert_non_null(raw_buf); |
| 116 | assert_non_null(decomp_buf); |
| 117 | assert_non_null(comp_buf); |
| 118 | assert_int_equal(s->raw_file_sz, read_file(s->raw_filename, raw_buf, s->raw_file_sz)); |
| 119 | assert_int_equal(s->comp_file_sz, |
Jakub Czapiga | c08b6a7 | 2022-01-10 13:36:47 +0000 | [diff] [blame] | 120 | read_file(s->comp_filename, comp_buf, s->comp_file_sz)); |
Jakub Czapiga | c1e4c5a | 2021-07-23 13:35:14 +0200 | [diff] [blame] | 121 | |
| 122 | assert_int_equal(s->raw_file_sz, |
Jakub Czapiga | c08b6a7 | 2022-01-10 13:36:47 +0000 | [diff] [blame] | 123 | ulzman(comp_buf, s->comp_file_sz, decomp_buf, s->raw_file_sz)); |
Jakub Czapiga | c1e4c5a | 2021-07-23 13:35:14 +0200 | [diff] [blame] | 124 | assert_memory_equal(raw_buf, decomp_buf, s->raw_file_sz); |
| 125 | |
| 126 | test_free(raw_buf); |
| 127 | test_free(decomp_buf); |
| 128 | test_free(comp_buf); |
| 129 | } |
| 130 | |
| 131 | static void test_ulzman_input_too_small(void **state) |
| 132 | { |
Jakub Czapiga | 19ad39b | 2021-12-14 16:47:49 +0000 | [diff] [blame] | 133 | uint8_t in_buf[32] = {0}; |
Jakub Czapiga | c1e4c5a | 2021-07-23 13:35:14 +0200 | [diff] [blame] | 134 | uint8_t out_buf[32]; |
| 135 | |
| 136 | assert_int_equal(0, ulzman(in_buf, LZMA_PROPERTIES_SIZE, out_buf, sizeof(out_buf))); |
| 137 | } |
| 138 | |
| 139 | static void test_ulzman_zero_buffer(void **state) |
| 140 | { |
| 141 | uint8_t in_buf[LZMA_PROPERTIES_SIZE + 1 * KiB]; |
| 142 | uint8_t out_buf[2 * KiB]; |
| 143 | |
| 144 | memset(in_buf, 0, sizeof(in_buf)); |
| 145 | memset(out_buf, 0, sizeof(out_buf)); |
| 146 | |
| 147 | assert_int_equal(0, ulzman(in_buf, sizeof(in_buf), out_buf, sizeof(out_buf))); |
| 148 | } |
| 149 | |
| 150 | #define ULZMAN_CORRECT_FILE_TEST(_file_prefix) \ |
Jakub Czapiga | c08b6a7 | 2022-01-10 13:36:47 +0000 | [diff] [blame] | 151 | { \ |
| 152 | .name = "test_ulzman_correct_file(" _file_prefix ")", \ |
| 153 | .test_func = test_ulzman_correct_file, .setup_func = setup_ulzman_file, \ |
| 154 | .teardown_func = teardown_ulzman_file, .initial_state = (_file_prefix) \ |
| 155 | } |
Jakub Czapiga | c1e4c5a | 2021-07-23 13:35:14 +0200 | [diff] [blame] | 156 | |
| 157 | int main(void) |
| 158 | { |
| 159 | const struct CMUnitTest tests[] = { |
| 160 | /* "data.N" in macros below refers to files: |
| 161 | - __TEST_DATA_DIR__ /lib/lzma-test/data.N.bin |
| 162 | - __TEST_DATA_DIR__ /lib/lzma-test/data.N.bin.lzma |
| 163 | Files data.N.bin suffix are raw data, and data.N.lzma.bin are its |
| 164 | LZMA-compressed form. Both are required to exist. |
| 165 | */ |
| 166 | |
| 167 | /* util/cbfs-compression-tool compressed by itself. |
| 168 | To test compression of executable files like payloads. */ |
| 169 | ULZMAN_CORRECT_FILE_TEST("data.1"), |
| 170 | |
| 171 | /* README.md compressed by util/cbfs-compression-tool. */ |
| 172 | ULZMAN_CORRECT_FILE_TEST("data.2"), |
| 173 | |
| 174 | /* tests/lib/imd-test.c compressed by util/cbfs-compression-tool |
| 175 | Structured text file. */ |
| 176 | ULZMAN_CORRECT_FILE_TEST("data.3"), |
| 177 | |
| 178 | /* libcmocka.so.0.7.0 compressed by util/cbfs-compression-tool |
| 179 | Another binary file, shared object. */ |
| 180 | ULZMAN_CORRECT_FILE_TEST("data.4"), |
| 181 | |
| 182 | cmocka_unit_test(test_ulzman_input_too_small), |
| 183 | |
| 184 | cmocka_unit_test(test_ulzman_zero_buffer), |
| 185 | }; |
| 186 | |
| 187 | return cb_run_group_tests(tests, NULL, NULL); |
| 188 | } |