/*
* Copyright (C) 2011 Andrea Mazzoleni
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "portable.h"
#include "snapraid.h"
#include "util.h"
#include "raid.h"
#include "cpu.h"
#include "elem.h"
#include "state.h"
struct hash_test_vector {
const char* data;
int len;
unsigned char digest[HASH_SIZE];
};
/**
* Test vectors for MurmorHash3_x86_128
*/
static struct hash_test_vector TEST_MURMUR3[] = {
#include "murmur3test.c"
{ 0, 0, { 0 } }
};
/**
* Test vectors for SpookyHash_128
*/
static struct hash_test_vector TEST_SPOOKY2[] = {
#include "spooky2test.c"
{ 0, 0, { 0 } }
};
static void recovtest(unsigned diskmax, unsigned block_size)
{
void* buffer_alloc;
unsigned char** buffer;
unsigned char* buffer_test0;
unsigned char* buffer_test1;
unsigned char* buffer_test2;
unsigned char* buffer_test3;
unsigned char* buffer_zero;
unsigned char* buffer_bad;
unsigned buffermax;
unsigned i, j, k, l;
unsigned n;
struct combo1 {
int ignore[3];
int use;
} COMBO1[] = {
{ { 1, 2, 3 }, 0 },
{ { 0, 2, 3 }, 1 },
{ { 0, 1, 3 }, 2 },
{ { 0, 1, 2 }, 3 }
};
struct combo2 {
int ignore[2];
int use[2];
} COMBO2[] = {
{ { 0, 1 }, { 2, 3 } },
{ { 0, 2 }, { 1, 3 } },
{ { 0, 3 }, { 1, 2 } },
{ { 1, 2 }, { 0, 3 } },
{ { 1, 3 }, { 0, 2 } },
{ { 2, 3 }, { 0, 1 } }
};
struct combo3 {
int ignore;
int use[3];
} COMBO3[] = {
{ 0, { 1, 2, 3 } },
{ 1, { 0, 2, 3 } },
{ 2, { 0, 1, 3 } },
{ 3, { 0, 1, 2 } }
};
buffermax = diskmax + LEV_MAX * 2 + 1 + 1;
buffer = malloc_nofail_vector_align(buffermax, block_size, &buffer_alloc);
buffer_test0 = buffer[buffermax-6];
buffer_test1 = buffer[buffermax-5];
buffer_test2 = buffer[buffermax-4];
buffer_test3 = buffer[buffermax-3];
buffer_zero = buffer[buffermax-2];
buffer_bad = buffer[buffermax-1];
memset(buffer_zero, 0, block_size);
memset(buffer_bad, 0xA5, block_size);
/* fill with random */
for(i=0;i RAIDQP_DATA_LIMIT && COMBO3[n].use[2] >= 3)
continue;
/* save */
a = buffer[i];
b = buffer[j];
c = buffer[k];
/* damage */
buffer[i] = buffer_test0;
buffer[j] = buffer_test1;
buffer[k] = buffer_test2;
/* ignore parity */
l = diskmax + COMBO3[n].ignore;
p = buffer[l];
buffer[l] = buffer_bad;
/* recover ignoring p */
raid_recov_3data(i, j, k, COMBO3[n].use[0], COMBO3[n].use[1], COMBO3[n].use[2], buffer, diskmax, buffer_zero, block_size);
/* check */
if (memcmp(buffer_test0, a, block_size) != 0
|| memcmp(buffer_test1, b, block_size) != 0
|| memcmp(buffer_test2, c, block_size) != 0
) {
fprintf(stderr, "Failed RAID test\n");
exit(EXIT_FAILURE);
}
/* restore parity */
buffer[l] = p;
/* restore */
buffer[i] = a;
buffer[j] = b;
buffer[k] = c;
}
}
}
}
/* check 2data */
for(i=0;i