This is the fix for Issue #13:
https://bitbucket.org/tsg-/liberasurecode/issue/13/decode-fails-for-many-cases-when-m-k This fix includes: 1.) Proper buffer allocation for the 'missing_idxs' structure, which was not allocating enough space when k > m. 2.) Checks to use header fields of parity fragments during decode when *no* data fragments are available. 3.) Fixed the unit tests to properly handle the case where k <= m. 4.) Extended the unit test framework to support multiple tests per backend 5.) Added tests for all RS implementations: (4,8), (4,4), (10,10)
This commit is contained in:
parent
a380246762
commit
a01b1818c8
|
@ -587,7 +587,7 @@ int liberasurecode_decode(int desc,
|
|||
goto out;
|
||||
}
|
||||
|
||||
missing_idxs = alloc_and_set_buffer(sizeof(char*) * k, -1);
|
||||
missing_idxs = alloc_and_set_buffer(sizeof(char*) * (k + m), -1);
|
||||
if (NULL == missing_idxs) {
|
||||
log_error("Could not allocate missing_idxs buffer!");
|
||||
goto out;
|
||||
|
@ -771,7 +771,7 @@ int liberasurecode_reconstruct_fragment(int desc,
|
|||
goto out;
|
||||
}
|
||||
|
||||
missing_idxs = alloc_and_set_buffer(sizeof(int*) * k, -1);
|
||||
missing_idxs = alloc_and_set_buffer(sizeof(int*) * (k + m), -1);
|
||||
if (NULL == missing_idxs) {
|
||||
log_error("Could not allocate missing_idxs buffer!");
|
||||
goto out;
|
||||
|
|
|
@ -192,6 +192,20 @@ int prepare_fragments_for_decode(
|
|||
*realloc_bm = *realloc_bm | (1 << (k + i));
|
||||
}
|
||||
|
||||
/* Need to determine the size of the original data */
|
||||
if (((missing_bm & (1 << (k + i))) == 0) && orig_data_size < 0) {
|
||||
orig_data_size = get_orig_data_size(parity[i]);
|
||||
if (orig_data_size < 0) {
|
||||
log_error("Invalid orig_data_size in fragment header!");
|
||||
return -EBADHEADER;
|
||||
}
|
||||
payload_size = get_fragment_payload_size(parity[i]);
|
||||
if (orig_data_size < 0) {
|
||||
log_error("Invalid fragment_size in fragment header!");
|
||||
return -EBADHEADER;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*orig_size = orig_data_size;
|
||||
|
|
|
@ -57,6 +57,8 @@ struct ec_args null_args = {
|
|||
.ct = CHKSUM_NONE,
|
||||
};
|
||||
|
||||
struct ec_args *null_test_args[] = { &null_args, NULL };
|
||||
|
||||
struct ec_args flat_xor_hd_args = {
|
||||
.k = 3,
|
||||
.m = 3,
|
||||
|
@ -64,6 +66,8 @@ struct ec_args flat_xor_hd_args = {
|
|||
.ct = CHKSUM_NONE,
|
||||
};
|
||||
|
||||
struct ec_args *flat_xor_test_args[] = { &flat_xor_hd_args, NULL };
|
||||
|
||||
struct ec_args jerasure_rs_vand_args = {
|
||||
.k = 10,
|
||||
.m = 4,
|
||||
|
@ -72,6 +76,35 @@ struct ec_args jerasure_rs_vand_args = {
|
|||
.ct = CHKSUM_NONE,
|
||||
};
|
||||
|
||||
struct ec_args jerasure_rs_vand_44_args = {
|
||||
.k = 4,
|
||||
.m = 4,
|
||||
.w = 16,
|
||||
.hd = 5,
|
||||
.ct = CHKSUM_NONE,
|
||||
};
|
||||
|
||||
struct ec_args jerasure_rs_vand_48_args = {
|
||||
.k = 4,
|
||||
.m = 8,
|
||||
.w = 16,
|
||||
.hd = 9,
|
||||
.ct = CHKSUM_NONE,
|
||||
};
|
||||
|
||||
struct ec_args jerasure_rs_vand_1010_args = {
|
||||
.k = 10,
|
||||
.m = 10,
|
||||
.w = 16,
|
||||
.hd = 11,
|
||||
.ct = CHKSUM_NONE,
|
||||
};
|
||||
|
||||
struct ec_args *jerasure_rs_vand_test_args[] = { &jerasure_rs_vand_args,
|
||||
&jerasure_rs_vand_44_args,
|
||||
&jerasure_rs_vand_1010_args,
|
||||
&jerasure_rs_vand_48_args,
|
||||
NULL };
|
||||
struct ec_args jerasure_rs_cauchy_args = {
|
||||
.k = 10,
|
||||
.m = 4,
|
||||
|
@ -80,6 +113,37 @@ struct ec_args jerasure_rs_cauchy_args = {
|
|||
.ct = CHKSUM_NONE,
|
||||
};
|
||||
|
||||
struct ec_args jerasure_rs_cauchy_44_args = {
|
||||
.k = 4,
|
||||
.m = 4,
|
||||
.w = 4,
|
||||
.hd = 5,
|
||||
.ct = CHKSUM_NONE,
|
||||
};
|
||||
|
||||
struct ec_args jerasure_rs_cauchy_48_args = {
|
||||
.k = 4,
|
||||
.m = 8,
|
||||
.w = 8,
|
||||
.hd = 9,
|
||||
.ct = CHKSUM_NONE,
|
||||
};
|
||||
|
||||
|
||||
struct ec_args jerasure_rs_cauchy_1010_args = {
|
||||
.k = 10,
|
||||
.m = 10,
|
||||
.w = 8,
|
||||
.hd = 11,
|
||||
.ct = CHKSUM_NONE,
|
||||
};
|
||||
|
||||
struct ec_args *jerasure_rs_cauchy_test_args[] = { &jerasure_rs_cauchy_args,
|
||||
&jerasure_rs_cauchy_44_args,
|
||||
&jerasure_rs_cauchy_48_args,
|
||||
&jerasure_rs_cauchy_1010_args,
|
||||
NULL };
|
||||
|
||||
struct ec_args isa_l_args = {
|
||||
.k = 10,
|
||||
.m = 4,
|
||||
|
@ -87,6 +151,25 @@ struct ec_args isa_l_args = {
|
|||
.hd = 5,
|
||||
};
|
||||
|
||||
struct ec_args isa_l_44_args = {
|
||||
.k = 4,
|
||||
.m = 4,
|
||||
.w = 8,
|
||||
.hd = 5,
|
||||
};
|
||||
|
||||
struct ec_args isa_l_1010_args = {
|
||||
.k = 10,
|
||||
.m = 10,
|
||||
.w = 8,
|
||||
.hd = 11,
|
||||
};
|
||||
|
||||
struct ec_args *isa_l_test_args[] = { &isa_l_args,
|
||||
&isa_l_44_args,
|
||||
&isa_l_1010_args,
|
||||
NULL };
|
||||
|
||||
int priv = 128;
|
||||
struct ec_args shss_args = {
|
||||
.k = 6,
|
||||
|
@ -95,6 +178,43 @@ struct ec_args shss_args = {
|
|||
.priv_args2 = &priv,
|
||||
};
|
||||
|
||||
struct ec_args *shss_test_args[] = { &shss_args, NULL };
|
||||
|
||||
struct ec_args **all_backend_tests[] = { null_test_args,
|
||||
flat_xor_test_args,
|
||||
jerasure_rs_vand_test_args,
|
||||
jerasure_rs_cauchy_test_args,
|
||||
isa_l_test_args,
|
||||
shss_test_args , NULL};
|
||||
|
||||
int num_backends()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (NULL != all_backend_tests[i]) {
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int max_tests_for_backends()
|
||||
{
|
||||
int n_backends = num_backends();
|
||||
int i = 0;
|
||||
int max = 0;
|
||||
|
||||
for (i = 0; i < n_backends; i++) {
|
||||
int j = 0;
|
||||
while (NULL != all_backend_tests[i][j]) {
|
||||
j++;
|
||||
}
|
||||
if (j > max) {
|
||||
max = j;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
LIBEC_VERSION_MISMATCH,
|
||||
|
@ -122,32 +242,48 @@ char * get_name_from_backend_id(ec_backend_id_t be) {
|
|||
}
|
||||
}
|
||||
|
||||
struct ec_args *create_ec_args(ec_backend_id_t be, ec_checksum_type_t ct)
|
||||
struct ec_args *create_ec_args(ec_backend_id_t be, ec_checksum_type_t ct, int backend_test_idx)
|
||||
{
|
||||
size_t ec_args_size = sizeof(struct ec_args);
|
||||
struct ec_args *template = NULL;
|
||||
struct ec_args** backend_args_array = NULL;
|
||||
int i = 0;
|
||||
|
||||
switch(be) {
|
||||
case EC_BACKEND_NULL:
|
||||
template = &null_args;
|
||||
backend_args_array = null_test_args;
|
||||
break;
|
||||
case EC_BACKEND_JERASURE_RS_VAND:
|
||||
template = &jerasure_rs_vand_args;
|
||||
backend_args_array = jerasure_rs_vand_test_args;
|
||||
break;
|
||||
case EC_BACKEND_JERASURE_RS_CAUCHY:
|
||||
template = &jerasure_rs_cauchy_args;
|
||||
backend_args_array = jerasure_rs_cauchy_test_args;
|
||||
break;
|
||||
case EC_BACKEND_FLAT_XOR_HD:
|
||||
template = &flat_xor_hd_args;
|
||||
backend_args_array = flat_xor_test_args;
|
||||
break;
|
||||
case EC_BACKEND_ISA_L_RS_VAND:
|
||||
template = &isa_l_args;
|
||||
backend_args_array = isa_l_test_args;
|
||||
break;
|
||||
case EC_BACKEND_SHSS:
|
||||
template = &shss_args;
|
||||
backend_args_array = shss_test_args;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (NULL != backend_args_array && NULL != backend_args_array[i]) {
|
||||
if (i == backend_test_idx) {
|
||||
template = backend_args_array[i];
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (NULL == template) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ec_args *args = malloc(ec_args_size);
|
||||
assert(args);
|
||||
memcpy(args, template, ec_args_size);
|
||||
|
@ -1077,13 +1213,13 @@ static void test_decode_with_missing_parity(const ec_backend_id_t be_id,
|
|||
static void test_decode_with_missing_multi_data(const ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
int max_num_missing = args->hd - 1;
|
||||
int max_num_missing = args->k <= (args->hd - 1) ? args->k : args->hd - 1;
|
||||
int i,j;
|
||||
for (i = 0; i < args->k - max_num_missing + 1; i++) {
|
||||
int *skip = create_skips_array(args,-1);
|
||||
assert(skip != NULL);
|
||||
for (j = i; j < i + max_num_missing; j++) {
|
||||
skip[j]=1;
|
||||
skip[j % args->k]=1;
|
||||
}
|
||||
encode_decode_test_impl(be_id, args, skip);
|
||||
free(skip);
|
||||
|
@ -1111,8 +1247,8 @@ static void test_decode_with_missing_multi_data_parity(
|
|||
{
|
||||
int i,j;
|
||||
int max_num_missing = args->hd - 1;
|
||||
int start = args->k - max_num_missing + 1;
|
||||
for (i = start; i < start + max_num_missing -1; i++) {
|
||||
int end = (args->k + args->m) - max_num_missing + 1;
|
||||
for (i = 0; i < end; i++) {
|
||||
int *skip = create_skips_array(args,-1);
|
||||
assert(skip != NULL);
|
||||
for (j = i; j < i + max_num_missing; j++) {
|
||||
|
@ -1651,30 +1787,30 @@ struct testcase testcases[] = {
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ii = 0, num_cases = 0;
|
||||
|
||||
for (num_cases = 0; testcases[num_cases].description; num_cases++) {
|
||||
/* Just counting */
|
||||
}
|
||||
|
||||
printf("1..%d\n", num_cases);
|
||||
int ii = 0, num_cases = 0, i = 0;
|
||||
int max_backend_tests = max_tests_for_backends();
|
||||
|
||||
for (i = 0; i < max_backend_tests; i++) {
|
||||
for (ii = 0; testcases[ii].description != NULL; ++ii) {
|
||||
const char *testname = get_name_from_backend_id(testcases[ii].be_id);
|
||||
fflush(stdout);
|
||||
if (testcases[ii].skip) {
|
||||
fprintf(stdout, "ok # SKIP %d - %s: %s\n", ii + 1,
|
||||
fprintf(stdout, "ok # SKIP %d - %s: %s (idx=%d)\n", num_cases,
|
||||
testcases[ii].description,
|
||||
(testname) ? testname : "");
|
||||
(testname) ? testname : "", i);
|
||||
continue;
|
||||
}
|
||||
struct ec_args *args = create_ec_args(testcases[ii].be_id, testcases[ii].ct);
|
||||
struct ec_args *args = create_ec_args(testcases[ii].be_id, testcases[ii].ct, i);
|
||||
if (NULL != args) {
|
||||
testcases[ii].function(testcases[ii].be_id, args);
|
||||
fprintf(stdout, "ok %d - %s: %s\n", ii + 1,
|
||||
fprintf(stdout, "ok %d - %s: %s (idx=%d)\n", num_cases,
|
||||
testcases[ii].description,
|
||||
(testname) ? testname : "");
|
||||
(testname) ? testname : "", i);
|
||||
fflush(stdout);
|
||||
free(args);
|
||||
num_cases++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue