1 /**********************************************************************
2 Copyright(c) 2011-2018 Intel Corporation All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in
11 the documentation and/or other materials provided with the
12 distribution.
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 **********************************************************************/
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdint.h>
34 #include "crc.h"
35 #include "crc_ref.h"
36 #include "test.h"
37
38 #ifndef TEST_SEED
39 #define TEST_SEED 0x1234
40 #endif
41
42 #define MAX_BUF 4096
43 #define TEST_SIZE 32
44
45 typedef uint32_t (*crc32_func_t)(uint32_t, const uint8_t *, uint64_t);
46 typedef uint32_t (*crc32_func_t_base)(uint32_t, uint8_t *, uint64_t);
47 typedef uint32_t (*crc32_func_t_ref)(uint32_t, uint8_t *, uint64_t);
48
49 typedef struct func_case {
50 char *note;
51 crc32_func_t crc32_func_call;
52 crc32_func_t_base crc32_base_call;
53 crc32_func_t_ref crc32_ref_call;
54 } func_case_t;
55
56 uint32_t
crc32_iscsi_wrap(uint32_t seed,const uint8_t * buf,uint64_t len)57 crc32_iscsi_wrap(uint32_t seed, const uint8_t *buf, uint64_t len)
58 {
59 return crc32_iscsi((uint8_t *) buf, len, seed);
60 }
61
62 uint32_t
crc32_iscsi_base_wrap(uint32_t seed,uint8_t * buf,uint64_t len)63 crc32_iscsi_base_wrap(uint32_t seed, uint8_t *buf, uint64_t len)
64 {
65 return crc32_iscsi_base(buf, len, seed);
66 }
67
68 uint32_t
crc32_iscsi_ref_wrap(uint32_t seed,uint8_t * buf,uint64_t len)69 crc32_iscsi_ref_wrap(uint32_t seed, uint8_t *buf, uint64_t len)
70 {
71 return crc32_iscsi_ref(buf, len, seed);
72 }
73
74 func_case_t test_funcs[] = {
75 { "crc32_ieee", crc32_ieee, crc32_ieee_base, crc32_ieee_ref },
76 { "crc32_gzip_refl", crc32_gzip_refl, crc32_gzip_refl_base, crc32_gzip_refl_ref },
77 { "crc32_iscsi", crc32_iscsi_wrap, crc32_iscsi_base_wrap, crc32_iscsi_ref_wrap }
78 };
79
80 // Generates pseudo-random data
81
82 void
rand_buffer(unsigned char * buf,long buffer_size)83 rand_buffer(unsigned char *buf, long buffer_size)
84 {
85 long i;
86 for (i = 0; i < buffer_size; i++)
87 buf[i] = rand();
88 }
89
90 // Test cases
91 int
92 zeros_test(func_case_t *test_func);
93
94 int
95 simple_pattern_test(func_case_t *test_func);
96
97 int
98 seeds_sizes_test(func_case_t *test_func);
99
100 int
101 eob_test(func_case_t *test_func);
102
103 int
104 update_test(func_case_t *test_func);
105
106 void *buf_alloc = NULL;
107
108 int
main(int argc,char * argv[])109 main(int argc, char *argv[])
110 {
111 int fail = 0, fail_case;
112 int i, ret;
113 func_case_t *test_func;
114
115 // Align to TEST_SIZE boundary
116 ret = posix_memalign(&buf_alloc, TEST_SIZE, MAX_BUF * TEST_SIZE);
117 if (ret) {
118 printf("alloc error: Fail");
119 return -1;
120 }
121 srand(TEST_SEED);
122 printf("CRC32 Tests\n");
123
124 for (i = 0; i < sizeof(test_funcs) / sizeof(test_funcs[0]); i++) {
125 fail_case = 0;
126 test_func = &test_funcs[i];
127
128 printf("Test %s\t", test_func->note);
129 fail_case += zeros_test(test_func);
130 fail_case += simple_pattern_test(test_func);
131 fail_case += seeds_sizes_test(test_func);
132 fail_case += eob_test(test_func);
133 fail_case += update_test(test_func);
134 printf(" done: %s\n", fail_case ? "Fail" : "Pass");
135
136 if (fail_case) {
137 printf("\n%s Failed %d tests\n", test_func->note, fail_case);
138 fail++;
139 }
140 }
141
142 printf("CRC32 Tests all done: %s\n", fail ? "Fail" : "Pass");
143
144 aligned_free(buf_alloc);
145
146 return fail;
147 }
148
149 // Test of all zeros
150 int
zeros_test(func_case_t * test_func)151 zeros_test(func_case_t *test_func)
152 {
153 uint32_t crc_ref, crc_base, crc;
154 int fail = 0;
155 unsigned char *buf = NULL;
156
157 buf = (unsigned char *) buf_alloc;
158 memset(buf, 0, MAX_BUF * 10);
159 crc_ref = test_func->crc32_ref_call(TEST_SEED, buf, MAX_BUF * 10);
160 crc_base = test_func->crc32_base_call(TEST_SEED, buf, MAX_BUF * 10);
161 crc = test_func->crc32_func_call(TEST_SEED, buf, MAX_BUF * 10);
162
163 if ((crc_base != crc_ref) || (crc != crc_ref)) {
164 fail++;
165 printf("\n opt ref\n");
166 printf(" ------ ------\n");
167 printf("fail crc zero = 0x%8x 0x%8x 0x%8x\n", crc_ref, crc_base, crc);
168 }
169 #ifdef TEST_VERBOSE
170 else
171 printf(".");
172 #endif
173
174 return fail;
175 }
176
177 // Another simple test pattern
178 int
simple_pattern_test(func_case_t * test_func)179 simple_pattern_test(func_case_t *test_func)
180 {
181 uint32_t crc_ref, crc_base, crc;
182 int fail = 0;
183 unsigned char *buf = NULL;
184
185 buf = (unsigned char *) buf_alloc;
186 memset(buf, 0x8a, MAX_BUF);
187 crc_ref = test_func->crc32_ref_call(TEST_SEED, buf, MAX_BUF);
188 crc_base = test_func->crc32_base_call(TEST_SEED, buf, MAX_BUF);
189 crc = test_func->crc32_func_call(TEST_SEED, buf, MAX_BUF);
190
191 if ((crc_base != crc_ref) || (crc != crc_ref)) {
192 fail++;
193 printf("fail crc all 8a = 0x%8x 0x%8x 0x%8x\n", crc_ref, crc_base, crc);
194 }
195 #ifdef TEST_VERBOSE
196 else
197 printf(".");
198 #endif
199
200 return fail;
201 }
202
203 int
seeds_sizes_test(func_case_t * test_func)204 seeds_sizes_test(func_case_t *test_func)
205 {
206 uint32_t crc_ref, crc_base, crc;
207 int fail = 0;
208 int i;
209 uint64_t r, s;
210 unsigned char *buf = NULL;
211
212 // Do a few random tests
213 buf = (unsigned char *) buf_alloc; // reset buf
214 r = rand();
215 rand_buffer(buf, MAX_BUF * TEST_SIZE);
216
217 for (i = 0; i < TEST_SIZE; i++) {
218 crc_ref = test_func->crc32_ref_call(r, buf, MAX_BUF);
219 crc_base = test_func->crc32_base_call(r, buf, MAX_BUF);
220 crc = test_func->crc32_func_call(r, buf, MAX_BUF);
221
222 if ((crc_base != crc_ref) || (crc != crc_ref)) {
223 fail++;
224 printf("fail crc rand%3d = 0x%8x 0x%8x 0x%8x\n", i, crc_ref, crc_base, crc);
225 }
226 #ifdef TEST_VERBOSE
227 else if (i % (TEST_SIZE / 8) == 0)
228 printf(".");
229 #endif
230 buf += MAX_BUF;
231 }
232
233 // Do a few random sizes
234 buf = (unsigned char *) buf_alloc; // reset buf
235 r = rand();
236
237 for (i = MAX_BUF; i >= 0; i--) {
238 crc_ref = test_func->crc32_ref_call(r, buf, i);
239 crc_base = test_func->crc32_base_call(r, buf, i);
240 crc = test_func->crc32_func_call(r, buf, i);
241
242 if ((crc_base != crc_ref) || (crc != crc_ref)) {
243 fail++;
244 printf("fail random size%i 0x%8x 0x%8x 0x%8x\n", i, crc_ref, crc_base, crc);
245 }
246 #ifdef TEST_VERBOSE
247 else if (i % (MAX_BUF / 8) == 0)
248 printf(".");
249 #endif
250 }
251
252 // Try different seeds
253 for (s = 0; s < 20; s++) {
254 buf = (unsigned char *) buf_alloc; // reset buf
255
256 r = rand(); // just to get a new seed
257 rand_buffer(buf, MAX_BUF * TEST_SIZE); // new pseudo-rand data
258
259 #ifdef TEST_VERBOSE
260 printf("seed = 0x%lx\n", r);
261 #endif
262
263 for (i = 0; i < TEST_SIZE; i++) {
264 crc_ref = test_func->crc32_ref_call(r, buf, MAX_BUF);
265 crc_base = test_func->crc32_base_call(r, buf, MAX_BUF);
266 crc = test_func->crc32_func_call(r, buf, MAX_BUF);
267
268 if ((crc_base != crc_ref) || (crc != crc_ref)) {
269 fail++;
270 printf("fail crc rand%3d = 0x%8x 0x%8x 0x%8x\n", i, crc_ref,
271 crc_base, crc);
272 }
273 #ifdef TEST_VERBOSE
274 else if (i % (TEST_SIZE * 20 / 8) == 0)
275 printf(".");
276 #endif
277 buf += MAX_BUF;
278 }
279 }
280
281 return fail;
282 }
283
284 // Run tests at end of buffer
285 int
eob_test(func_case_t * test_func)286 eob_test(func_case_t *test_func)
287 {
288 uint32_t crc_ref, crc_base, crc;
289 int fail = 0;
290 int i;
291 unsigned char *buf = NULL;
292
293 // Null test
294 if (0 != test_func->crc32_func_call(0, NULL, 0)) {
295 fail++;
296 printf("crc null test fail\n");
297 }
298
299 buf = (unsigned char *) buf_alloc; // reset buf
300 buf = buf + ((MAX_BUF - 1) * TEST_SIZE); // Line up TEST_SIZE from end
301 for (i = 0; i <= TEST_SIZE; i++) {
302 crc_ref = test_func->crc32_ref_call(TEST_SEED, buf + i, TEST_SIZE - i);
303 crc_base = test_func->crc32_base_call(TEST_SEED, buf + i, TEST_SIZE - i);
304 crc = test_func->crc32_func_call(TEST_SEED, buf + i, TEST_SIZE - i);
305
306 if ((crc_base != crc_ref) || (crc != crc_ref)) {
307 fail++;
308 printf("fail crc eob rand%3d = 0x%8x 0x%8x 0x%8x\n", i, crc_ref, crc_base,
309 crc);
310 }
311 #ifdef TEST_VERBOSE
312 else if (i % (TEST_SIZE / 8) == 0)
313 printf(".");
314 #endif
315 }
316
317 return fail;
318 }
319
320 int
update_test(func_case_t * test_func)321 update_test(func_case_t *test_func)
322 {
323 uint32_t crc_ref, crc_base, crc;
324 int fail = 0;
325 int i;
326 uint64_t r;
327 unsigned char *buf = NULL;
328
329 buf = (unsigned char *) buf_alloc; // reset buf
330 r = rand();
331 // Process the whole buf with reference func single call.
332 crc_ref = test_func->crc32_ref_call(r, buf, MAX_BUF * TEST_SIZE);
333 crc_base = test_func->crc32_base_call(r, buf, MAX_BUF * TEST_SIZE);
334 // Process buf with update method.
335 for (i = 0; i < TEST_SIZE; i++) {
336 crc = test_func->crc32_func_call(r, buf, MAX_BUF);
337 // Update crc seeds and buf pointer.
338 r = crc;
339 buf += MAX_BUF;
340 }
341
342 if ((crc_base != crc_ref) || (crc != crc_ref)) {
343 fail++;
344 printf("fail crc rand%3d = 0x%8x 0x%8x 0x%8x\n", i, crc_ref, crc_base, crc);
345 }
346 #ifdef TEST_VERBOSE
347 else
348 printf(".");
349 #endif
350
351 return fail;
352 }
353