blob: b68d38e122a8564b537bac9e50577f27475bf2eb [file] [log] [blame]
Jakub Czapigac1e4c5a2021-07-23 13:35:14 +02001/* 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
14struct 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
21static 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
29static 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 */
41static 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 Czapigac08b6a72022-01-10 13:36:47 +000054 const size_t raw_filename_size =
55 strlen(path_prefix) + strlen(fname_base) + ARRAY_SIZE(raw_file_suffix);
Jakub Czapigac1e4c5a2021-07-23 13:35:14 +020056 s->raw_filename = test_malloc(raw_filename_size);
57
Jakub Czapigac08b6a72022-01-10 13:36:47 +000058 const size_t comp_filename_size =
59 strlen(path_prefix) + strlen(fname_base) + ARRAY_SIZE(comp_file_suffix);
Jakub Czapigac1e4c5a2021-07-23 13:35:14 +020060 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 Czapigac08b6a72022-01-10 13:36:47 +000070 comp_file_suffix);
Jakub Czapigac1e4c5a2021-07-23 13:35:14 +020071
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;
89error:
90 teardown_ulzman_file((void **)&s);
91 return ret;
92}
93
94static 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
108static 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 Czapigac08b6a72022-01-10 13:36:47 +0000120 read_file(s->comp_filename, comp_buf, s->comp_file_sz));
Jakub Czapigac1e4c5a2021-07-23 13:35:14 +0200121
122 assert_int_equal(s->raw_file_sz,
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000123 ulzman(comp_buf, s->comp_file_sz, decomp_buf, s->raw_file_sz));
Jakub Czapigac1e4c5a2021-07-23 13:35:14 +0200124 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
131static void test_ulzman_input_too_small(void **state)
132{
Jakub Czapiga19ad39b2021-12-14 16:47:49 +0000133 uint8_t in_buf[32] = {0};
Jakub Czapigac1e4c5a2021-07-23 13:35:14 +0200134 uint8_t out_buf[32];
135
136 assert_int_equal(0, ulzman(in_buf, LZMA_PROPERTIES_SIZE, out_buf, sizeof(out_buf)));
137}
138
139static 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 Czapigac08b6a72022-01-10 13:36:47 +0000151 { \
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 Czapigac1e4c5a2021-07-23 13:35:14 +0200156
157int 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}