xref: /isa-l/raid/xor_check_test.c (revision ae951677ab3f79d379a9da251b5a1245e7b76aca)
1 /**********************************************************************
2   Copyright(c) 2011-2015 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 <stdint.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include "raid.h"
35 #include "test.h"
36 
37 #define TEST_SOURCES 16
38 #define TEST_LEN     1024
39 #define TEST_MEM     ((TEST_SOURCES + 1) * (TEST_LEN))
40 #ifndef TEST_SEED
41 #define TEST_SEED 0x1234
42 #endif
43 
44 // Generates pseudo-random data
45 
46 void
rand_buffer(unsigned char * buf,long buffer_size)47 rand_buffer(unsigned char *buf, long buffer_size)
48 {
49         long i;
50         for (i = 0; i < buffer_size; i++)
51                 buf[i] = rand();
52 }
53 
54 int
main(int argc,char * argv[])55 main(int argc, char *argv[])
56 {
57         int i, j, k, ret, fail = 0;
58         void *buffs[TEST_SOURCES + 1] = { NULL };
59         char c;
60         int serr, lerr;
61         char *tmp_buf[TEST_SOURCES + 1];
62 
63         printf("Test xor_check_test %d sources X %d bytes\n", TEST_SOURCES, TEST_LEN);
64 
65         srand(TEST_SEED);
66 
67         // Allocate the arrays
68         for (i = 0; i < TEST_SOURCES + 1; i++) {
69                 void *buf;
70                 if (posix_memalign(&buf, 16, TEST_LEN)) {
71                         printf("alloc error: Fail");
72                         fail = 1;
73                         goto exit;
74                 }
75                 buffs[i] = buf;
76         }
77 
78         // Test of all zeros
79         for (i = 0; i < TEST_SOURCES + 1; i++)
80                 memset(buffs[i], 0, TEST_LEN);
81 
82         xor_gen_base(TEST_SOURCES + 1, TEST_LEN, buffs);
83         ret = xor_check(TEST_SOURCES + 1, TEST_LEN, buffs);
84         if (ret != 0) {
85                 fail++;
86                 printf("\nfail zero test %d\n", ret);
87         }
88 
89         ((char *) (buffs[0]))[TEST_LEN - 2] = 0x7; // corrupt buffer
90         ret = xor_check(TEST_SOURCES + 1, TEST_LEN, buffs);
91         if (ret == 0) {
92                 fail++;
93                 printf("\nfail corrupt buffer test %d\n", ret);
94         }
95         ((char *) (buffs[0]))[TEST_LEN - 2] = 0; // un-corrupt buffer
96 
97         // Test corrupted buffer any location on all sources
98         for (j = 0; j < TEST_SOURCES + 1; j++) {
99                 for (i = TEST_LEN - 1; i >= 0; i--) {
100                         ((char *) buffs[j])[i] = 0x5; // corrupt buffer
101                         ret = xor_check(TEST_SOURCES + 1, TEST_LEN, buffs);
102                         if (ret == 0) {
103                                 fail++;
104                                 printf("\nfail corrupt buffer test j=%d, i=%d\n", j, i);
105                                 goto exit;
106                         }
107                         ((char *) buffs[j])[i] = 0; // un-corrupt buffer
108                 }
109 #ifdef TEST_VERBOSE
110                 putchar('.');
111 #endif
112         }
113 
114         // Test rand1
115         for (i = 0; i < TEST_SOURCES + 1; i++)
116                 rand_buffer(buffs[i], TEST_LEN);
117 
118         xor_gen_base(TEST_SOURCES + 1, TEST_LEN, buffs);
119         ret = xor_check(TEST_SOURCES + 1, TEST_LEN, buffs);
120         if (ret != 0) {
121                 fail++;
122                 printf("fail first rand test %d\n", ret);
123         }
124 
125         c = ((char *) (buffs[0]))[TEST_LEN - 2];
126         ((char *) (buffs[0]))[TEST_LEN - 2] = c ^ 0x1;
127         ret = xor_check(TEST_SOURCES + 1, TEST_LEN, buffs);
128         if (ret == 0) {
129                 fail++;
130                 printf("\nFail corrupt buffer test, passed when should have failed\n");
131         }
132         ((char *) (buffs[0]))[TEST_LEN - 2] = c; // un-corrupt buffer
133 
134         // Test corrupted buffer any location on all sources w/ random data
135         for (j = 0; j < TEST_SOURCES + 1; j++) {
136                 for (i = TEST_LEN - 1; i >= 0; i--) {
137                         // Check it still passes
138                         ret = xor_check(TEST_SOURCES + 1, TEST_LEN, buffs);
139                         if (ret != 0) { // should pass
140                                 fail++;
141                                 printf("\nFail rand test with un-corrupted buffer j=%d, i=%d\n", j,
142                                        i);
143                                 goto exit;
144                         }
145                         c = ((char *) buffs[j])[i];
146                         ((char *) buffs[j])[i] = c ^ 1; // corrupt buffer
147                         ret = xor_check(TEST_SOURCES + 1, TEST_LEN, buffs);
148                         if (ret == 0) { // Check it now fails
149                                 fail++;
150                                 printf("\nfail corrupt buffer test j=%d, i=%d\n", j, i);
151                                 goto exit;
152                         }
153                         ((char *) buffs[j])[i] = c; // un-corrupt buffer
154                 }
155 #ifdef TEST_VERBOSE
156                 putchar('.');
157 #endif
158         }
159 
160         // Test various number of sources, full length
161         for (j = 3; j <= TEST_SOURCES + 1; j++) {
162                 // New random data
163                 for (i = 0; i < j; i++)
164                         rand_buffer(buffs[i], TEST_LEN);
165 
166                 // Generate xor parity for this number of sources
167                 xor_gen_base(j, TEST_LEN, buffs);
168 
169                 // Set errors up in each source and len position
170                 for (i = 0; i < j; i++) {
171                         for (k = 0; k < TEST_LEN; k++) {
172                                 // See if it still passes
173                                 ret = xor_check(j, TEST_LEN, buffs);
174                                 if (ret != 0) { // Should pass
175                                         printf("\nfail rand test %d sources\n", j);
176                                         fail++;
177                                         goto exit;
178                                 }
179 
180                                 c = ((char *) buffs[i])[k];
181                                 ((char *) buffs[i])[k] = c ^ 1; // corrupt buffer
182 
183                                 ret = xor_check(j, TEST_LEN, buffs);
184                                 if (ret == 0) { // Should fail
185                                         printf("\nfail rand test corrupted buffer %d sources\n", j);
186                                         fail++;
187                                         goto exit;
188                                 }
189                                 ((char *) buffs[i])[k] = c; // un-corrupt buffer
190                         }
191                 }
192 #ifdef TEST_VERBOSE
193                 putchar('.');
194 #endif
195         }
196 
197         fflush(0);
198 
199         // Test various number of sources and len
200         k = 1;
201         while (k <= TEST_LEN) {
202                 for (j = 3; j <= TEST_SOURCES + 1; j++) {
203                         for (i = 0; i < j; i++)
204                                 rand_buffer(buffs[i], k);
205 
206                         // Generate xor parity for this number of sources
207                         xor_gen_base(j, k, buffs);
208 
209                         // Inject errors at various source and len positions
210                         for (lerr = 0; lerr < k; lerr += 10) {
211                                 for (serr = 0; serr < j; serr++) {
212 
213                                         // See if it still passes
214                                         ret = xor_check(j, k, buffs);
215                                         if (ret != 0) { // Should pass
216                                                 printf("\nfail rand test %d sources\n", j);
217                                                 fail++;
218                                                 goto exit;
219                                         }
220 
221                                         c = ((char *) buffs[serr])[lerr];
222                                         ((char *) buffs[serr])[lerr] = c ^ 1; // corrupt buffer
223 
224                                         ret = xor_check(j, k, buffs);
225                                         if (ret == 0) { // Should fail
226                                                 printf("\nfail rand test corrupted buffer "
227                                                        "%d sources, len=%d, ret=%d\n",
228                                                        j, k, ret);
229                                                 fail++;
230                                                 goto exit;
231                                         }
232                                         ((char *) buffs[serr])[lerr] = c; // un-corrupt buffer
233                                 }
234                         }
235                 }
236 #ifdef TEST_VERBOSE
237                 putchar('.');
238 #endif
239                 fflush(0);
240                 k += 1;
241         }
242 
243         // Test at the end of buffer
244         for (i = 0; i < TEST_LEN; i += 32) {
245                 for (j = 0; j < TEST_SOURCES + 1; j++) {
246                         rand_buffer(buffs[j], TEST_LEN - i);
247                         tmp_buf[j] = (char *) buffs[j] + i;
248                 }
249 
250                 xor_gen_base(TEST_SOURCES + 1, TEST_LEN - i, (void *) tmp_buf);
251 
252                 // Test good data
253                 ret = xor_check(TEST_SOURCES + 1, TEST_LEN - i, (void *) tmp_buf);
254                 if (ret != 0) {
255                         printf("fail end test - offset: %d, len: %d\n", i, TEST_LEN - i);
256                         fail++;
257                         goto exit;
258                 }
259                 // Test bad data
260                 for (serr = 0; serr < TEST_SOURCES + 1; serr++) {
261                         for (lerr = 0; lerr < (TEST_LEN - i); lerr++) {
262                                 c = tmp_buf[serr][lerr];
263                                 tmp_buf[serr][lerr] = c ^ 1;
264 
265                                 ret = xor_check(TEST_SOURCES + 1, TEST_LEN - i, (void *) tmp_buf);
266                                 if (ret == 0) {
267                                         printf("fail end test corrupted buffer - "
268                                                "offset: %d, len: %d, ret: %d\n",
269                                                i, TEST_LEN - i, ret);
270                                         fail++;
271                                         goto exit;
272                                 }
273 
274                                 tmp_buf[serr][lerr] = c;
275                         }
276                 }
277 
278 #ifdef TEST_VERBOSE
279                 putchar('.');
280 #endif
281                 fflush(0);
282         }
283 
284         if (fail == 0)
285                 printf("Pass\n");
286 
287 exit:
288         for (i = 0; i < TEST_SOURCES + 1; i++)
289                 aligned_free(buffs[i]);
290 
291         return fail;
292 }
293