xref: /isa-l/crc/crc32_funcs_test.c (revision 671e67b62d859950f86e6eec04e16b72404f3bf9)
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