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