summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorKota Tsuyuzaki <tsuyuzaki.kota@lab.ntt.co.jp>2016-11-03 19:49:49 -0700
committerClay Gerrard <clay.gerrard@gmail.com>2016-11-09 23:28:55 +0000
commit74eaa374c107d1a9e140fc7a8c1bf91386619940 (patch)
tree14aa116eb85e3cb1fa3db7e77fd1974385432b5e /test
parentb96cf4b2cc98dbdcdf60c80cd4a353f5c11959c8 (diff)
downloadliberasurecode-74eaa374c107d1a9e140fc7a8c1bf91386619940.tar.gz
Fix error handling on gf_ivnert_matrix in isa-l backend
Current isa-l has possibility to return corrupted decoded data or corrupted reconstructed data on decode/reconstruct without error code. That is from the specification of isa-l rs vandermond matrix discussed at [1]. With many # of parities cases, we may hit the case above due to failing to get the inverse matrix from the encode matrix. The isa-l maintener gbtucker suggests a good way to detect the failing inverse matrix, that we should handle the return value gf_invert_matrix. If gf_invert_matrix returns not 0, we should stop to decode/reconstruct and return failure return code to the caller immediately. Otherwise, the caller regards the garbage data/fragment as correct one. And this patch adds the specific test case we can hit the issue (it happens not so general). 1: https://github.com/01org/isa-l/issues/10 Related-Change: I6eb150d9d0c3febf233570fa7729f9f72df2e9be Change-Id: Icee788a0931fe692fe0de31fabc4ba450e338a87
Diffstat (limited to 'test')
-rw-r--r--test/liberasurecode_test.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/test/liberasurecode_test.c b/test/liberasurecode_test.c
index c94c466..386d49f 100644
--- a/test/liberasurecode_test.c
+++ b/test/liberasurecode_test.c
@@ -1346,6 +1346,102 @@ static void test_decode_with_missing_multi_data_parity(
}
}
+static void test_decode_reconstruct_specific_error_case(
+ const ec_backend_id_t be_id, struct ec_args *args)
+{
+ struct ec_args specific_1010_args = {
+ .k = 10,
+ .m = 10,
+ };
+
+ int rc = 0;
+ int desc = -1;
+ int orig_data_size = 1024 * 1024;
+ char *orig_data = create_buffer(orig_data_size, 'x');
+ char **encoded_data = NULL, **encoded_parity = NULL;
+ uint64_t encoded_fragment_len = 0;
+ int num_avail_frags = -1;
+ char **avail_frags = NULL;
+ char *decoded_data = NULL;
+ char *out_frag = NULL;
+ uint64_t decoded_data_len = 0;
+
+ int *skips = create_skips_array(&specific_1010_args,-1);
+ assert(skips != NULL);
+ // available frags for a bad pattern: [0, 1, 2, 3, 4, 6, 7, 10, 12, 15]
+ skips[5] = skips[8] = skips[9] = skips[11] = skips[13] = skips[14] =
+ skips[16] = skips[17] = skips[18] = skips[19] = 1;
+
+ desc = liberasurecode_instance_create(
+ EC_BACKEND_ISA_L_RS_VAND, &specific_1010_args);
+ if (-EBACKENDNOTAVAIL == desc) {
+ fprintf (stderr, "Backend library not available!\n");
+ return;
+ }
+ assert(desc > 0);
+
+ rc = liberasurecode_encode(desc, orig_data, orig_data_size,
+ &encoded_data, &encoded_parity, &encoded_fragment_len);
+ assert(rc == 0);
+
+ num_avail_frags = create_frags_array(&avail_frags, encoded_data,
+ encoded_parity, &specific_1010_args,
+ skips);
+ assert(num_avail_frags > 0);
+
+ rc = liberasurecode_decode(desc, avail_frags, num_avail_frags,
+ encoded_fragment_len, 1,
+ &decoded_data, &decoded_data_len);
+ assert(rc == -1);
+ free(avail_frags);
+
+ // 5 is a hole in available frags
+ num_avail_frags = create_frags_array(&avail_frags, encoded_data,
+ encoded_parity, &specific_1010_args,
+ skips);
+ out_frag = malloc(sizeof(char) * encoded_fragment_len);
+ rc = liberasurecode_reconstruct_fragment(
+ desc, avail_frags, 10, encoded_fragment_len, 5, out_frag);
+ assert(rc == -1);
+
+ free(out_frag);
+ free(avail_frags);
+
+ // sanity; [0, 1, 2, 3, 4, 6, 7, 10, 12, 14] is ok
+ skips[15] = 1; skips[14] = 0;
+ num_avail_frags = create_frags_array(&avail_frags, encoded_data,
+ encoded_parity, &specific_1010_args,
+ skips);
+ assert(num_avail_frags > 0);
+ rc = liberasurecode_decode(desc, avail_frags, num_avail_frags,
+ encoded_fragment_len, 1,
+ &decoded_data, &decoded_data_len);
+ assert(rc == 0);
+ // 5 is a hole in available frags
+ out_frag = malloc(sizeof(char) * encoded_fragment_len);
+ rc = liberasurecode_reconstruct_fragment(
+ desc, avail_frags, 10, encoded_fragment_len, 5, out_frag);
+
+ assert(rc == 0);
+
+ free(out_frag);
+
+ // cleanup all
+ rc = liberasurecode_encode_cleanup(desc, encoded_data, encoded_parity);
+ assert(rc == 0);
+
+ rc = liberasurecode_decode_cleanup(desc, decoded_data);
+ assert(rc == 0);
+
+ if (desc) {
+ assert(0 == liberasurecode_instance_destroy(desc));
+ }
+
+ free(orig_data);
+ free(avail_frags);
+ free(skips);
+}
+
static void test_simple_encode_decode(const ec_backend_id_t be_id,
struct ec_args *args)
{
@@ -1875,6 +1971,10 @@ struct testcase testcases[] = {
test_verify_stripe_metadata_frag_idx_invalid,
EC_BACKEND_ISA_L_RS_VAND, CHKSUM_CRC32,
.skip = false},
+ {"test_isa_l_decode_reconstruct_specific_error_case",
+ test_decode_reconstruct_specific_error_case,
+ EC_BACKENDS_MAX, 0, // note this test is using ISA-L in hard coded
+ .skip = false},
// shss tests
{"create_and_destroy_backend",
test_create_and_destroy_backend,