diff options
author | Eric Lambert <eric_lambert@xyratex.com> | 2014-09-02 11:12:16 -0700 |
---|---|---|
committer | Eric Lambert <eric_lambert@xyratex.com> | 2014-09-02 11:12:16 -0700 |
commit | 81c47389ba9a6568224481ca4a2eabbb99f5db2f (patch) | |
tree | 7ac48ce93dfc56aea12dd1c25f9670132db96b42 | |
parent | cde80cfe27b40ab46d5e2afc1516e942f423a289 (diff) | |
download | liberasurecode-81c47389ba9a6568224481ca4a2eabbb99f5db2f.tar.gz |
Added more tests (most of which test that the "public" functions
perform some argument validity checks). Also fixed some bugs exposed by
these new tests. NOTE: liberasurecode_test now *requires* that the null
provider be loadable by the test (meaning is on LD_LIBRARY_PATH).
-rw-r--r-- | src/erasurecode.c | 104 | ||||
-rw-r--r-- | test/liberasurecode_test.c | 347 |
2 files changed, 402 insertions, 49 deletions
diff --git a/src/erasurecode.c b/src/erasurecode.c index b86f38e..b481ba9 100644 --- a/src/erasurecode.c +++ b/src/erasurecode.c @@ -56,6 +56,9 @@ char *ec_backends_supported_str[EC_BACKENDS_MAX]; /* Get EC backend by name */ ec_backend_t liberasurecode_backend_lookup_by_name(const char *name) { + if (NULL == name) + return NULL; + int b = 0; for (b = 0; ec_backends_supported[b]; ++b) { @@ -69,6 +72,8 @@ ec_backend_t liberasurecode_backend_lookup_by_name(const char *name) /* Name to ID mapping for EC backend */ ec_backend_id_t liberasurecode_backend_lookup_id(const char *name) { + if (NULL == name) + return -1; int b = 0; for (b = 0; ec_backends_supported[b]; ++b) { @@ -298,6 +303,8 @@ int liberasurecode_instance_create(const char *backend_name, int err = 0; ec_backend_t instance = NULL; struct ec_backend_args bargs; + if (!backend_name || !args) + return -1; ec_backend_id_t id = liberasurecode_backend_lookup_id(backend_name); if (-1 == id) @@ -348,7 +355,7 @@ int liberasurecode_instance_destroy(int desc) instance = liberasurecode_backend_instance_get_by_desc(desc); if (NULL == instance) - return EBACKENDNOTAVAIL; + return -EBACKENDNOTAVAIL; /* Call private exit() for the backend */ instance->common.ops->exit(instance->desc.backend_desc); @@ -393,17 +400,21 @@ int liberasurecode_encode_cleanup(int desc, k = instance->args.uargs.k; m = instance->args.uargs.m; - for (i = 0; i < k; i++) { - free(encoded_data[i]); - } + if (encoded_data) { + for (i = 0; i < k; i++) { + free(encoded_data[i]); + } - free(encoded_data); - - for (i = 0; i < m; i++) { - free(encoded_parity[i]); + free(encoded_data); } + + if (encoded_parity) { + for (i = 0; i < m; i++) { + free(encoded_parity[i]); + } - free(encoded_parity); + free(encoded_parity); + } return 0; } @@ -437,6 +448,34 @@ int liberasurecode_encode(int desc, int data_len; /* data len to write to fragment headers */ int aligned_data_len; /* EC algorithm compatible data length */ + if (orig_data == NULL) { + log_error("Pointer to data buffer is null!"); + ret = -1; + goto out; + } + + if (orig_data_size <= 0) { + log_error("Size of data to encode must be a positive value"); + ret = -1; + goto out; + } + + if (encoded_data == NULL) { + log_error("Pointer to encoded data buffers is null!"); + return -1; + } + + if (encoded_parity == NULL) { + log_error("Pointer to encoded parity buffers is null!"); + return -1; + } + + if (fragment_len == NULL) { + log_error("Pointer to fragment length is null!"); + ret = -1; + goto out; + } + ec_backend_t instance = liberasurecode_backend_instance_get_by_desc(desc); if (NULL == instance) { ret = -EBACKENDNOTAVAIL; @@ -551,6 +590,24 @@ int liberasurecode_decode(int desc, goto out; } + if (NULL == available_fragments) { + log_error("Pointer to encoded fragments buffer is null!"); + ret = -1; + goto out; + } + + if (NULL == out_data) { + log_error("Pointer to decoded data buffer is null!"); + ret = -1; + goto out; + } + + if (NULL == out_data_len) { + log_error("Pointer to decoded data length variable is null!"); + ret = -1; + goto out; + } + k = instance->args.uargs.k; m = instance->args.uargs.m; @@ -718,6 +775,18 @@ int liberasurecode_reconstruct_fragment(int desc, ret = -EBACKENDNOTAVAIL; goto out; } + + if (NULL == available_fragments) { + log_error("Can not reconstruct fragment, available fragments pointer is NULL"); + ret = -1; + goto out; + } + + if (NULL == out_fragment) { + log_error("Can not reconstruct fragment, output fragment pointer is NULL"); + ret = -1; + goto out; + } k = instance->args.uargs.k; m = instance->args.uargs.m; @@ -855,6 +924,23 @@ int liberasurecode_fragments_needed(int desc, ret = -EBACKENDNOTAVAIL; goto out_error; } + if (NULL == fragments_to_reconstruct) { + log_error("Unable to determine list of fragments needed, pointer to list of indexes to reconstruct is NULL."); + ret = -1; + goto out_error; + } + + if (NULL == fragments_to_exclude) { + log_error("Unable to determine list of fragments needed, pointer to list of fragments to exclude is NULL."); + ret = -1; + goto out_error; + } + + if (NULL == fragments_needed) { + log_error("Unable to determine list of fragments needed, pointer to list of fragments to reconstruct is NULL."); + ret = -1; + goto out_error; + } /* FIXME preprocessing */ diff --git a/test/liberasurecode_test.c b/test/liberasurecode_test.c index e91c144..71e00bb 100644 --- a/test/liberasurecode_test.c +++ b/test/liberasurecode_test.c @@ -42,6 +42,32 @@ struct testcase { bool skip; }; +struct ec_args null_args = { + .k = 8, + .m = 4, + .priv_args1.null_args.arg1 = 11, +}; + +struct ec_args flat_xor_hd_args = { + .k = 10, + .m = 6, + .hd = 4, +}; + +struct ec_args jerasure_rs_vand_args = { + .k = 10, + .m = 4, + .w = 16, + .hd = 5, +}; + +struct ec_args jerasure_rs_cauchy_args = { + .k = 10, + .m = 4, + .w = 4, + .hd = 5, +}; + //TODO Make this a but more useful char *create_buffer(int size, int fill) { @@ -138,6 +164,196 @@ static void test_create_and_destroy_backend( assert(0 == liberasurecode_instance_destroy(desc)); } +static void test_create_backend_invalid_args() +{ + assert(liberasurecode_instance_create(NULL, &null_args) < 0); + assert(liberasurecode_instance_create("DOESNOTEXIST", &null_args) == -EBACKENDNOTSUPP); + assert(liberasurecode_instance_create("", &null_args) == -EBACKENDNOTSUPP); + assert(liberasurecode_instance_create(" ", &null_args) == -EBACKENDNOTSUPP); + assert(liberasurecode_instance_create("null", NULL) < 0); +} + +static void test_destroy_backend_invalid_args() +{ + int desc = -1; + assert(liberasurecode_instance_destroy(desc) < 0); + desc = 1; + assert(liberasurecode_instance_destroy(desc) < 0); + desc = liberasurecode_instance_create("null", &null_args); + assert(desc > 0); + assert(0 == liberasurecode_instance_destroy(desc)); + assert(liberasurecode_instance_destroy(desc) < 0); +} + +static void test_encode_invalid_args() +{ + 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; + + assert(orig_data != NULL); + rc = liberasurecode_encode(desc, orig_data, orig_data_size, + &encoded_data, &encoded_parity, &encoded_fragment_len); + assert(rc < 0); + + desc = liberasurecode_instance_create("null", &null_args); + assert(desc > 0); + + rc = liberasurecode_encode(desc, NULL, orig_data_size, + &encoded_data, &encoded_parity, &encoded_fragment_len); + assert(rc < 0); + + rc = liberasurecode_encode(desc, orig_data, 0, + &encoded_data, &encoded_parity, &encoded_fragment_len); + assert(rc < 0); + + rc = liberasurecode_encode(desc, orig_data, orig_data_size, + NULL, &encoded_parity, &encoded_fragment_len); + assert(rc < 0); + + rc = liberasurecode_encode(desc, orig_data, orig_data_size, + &encoded_data, NULL, &encoded_fragment_len); + assert(rc < 0); + + rc = liberasurecode_encode(desc, orig_data, orig_data_size, + &encoded_data, &encoded_parity, NULL); + assert(rc < 0); +} + +static void test_encode_cleanup_invalid_args() +{ + 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; + + desc = liberasurecode_instance_create("null", &null_args); + assert(desc > 0); + + rc = liberasurecode_encode(desc, orig_data, orig_data_size, + &encoded_data, &encoded_parity, &encoded_fragment_len); + assert(rc == 0); + + rc = liberasurecode_encode_cleanup(-1, encoded_data, encoded_parity); + assert(rc < 0); + + rc = liberasurecode_encode_cleanup(desc, NULL, NULL); + assert(rc == 0); +} + +static void test_decode_invalid_args() +{ + 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; + int *skips = create_skips_array(&null_args, -1); + char *decoded_data = NULL; + uint64_t decoded_data_len = 0; + + desc = liberasurecode_instance_create("null", &null_args); + assert(desc > 0); + rc = liberasurecode_encode(desc, orig_data, orig_data_size, + &encoded_data, &encoded_parity, &encoded_fragment_len); + assert(0 == rc); + + num_avail_frags = create_frags_array(&avail_frags, encoded_data, + encoded_parity, &null_args, skips); + + rc = liberasurecode_decode(-1, avail_frags, num_avail_frags, + encoded_fragment_len, &decoded_data, + &decoded_data_len); + assert(rc < 0); + + rc = liberasurecode_decode(desc, NULL, num_avail_frags, + encoded_fragment_len, &decoded_data, + &decoded_data_len); + assert(rc < 0); + + rc = liberasurecode_decode(desc, avail_frags, num_avail_frags, + encoded_fragment_len, NULL, + &decoded_data_len); + assert(rc < 0); + + rc = liberasurecode_decode(desc, avail_frags, num_avail_frags, + encoded_fragment_len, &decoded_data, + NULL); + assert(rc < 0); +} + +static void test_decode_cleanup_invalid_args() +{ + int rc = 0; + int desc = 1; + char *orig_data = create_buffer(1024, 'x'); + + rc = liberasurecode_decode_cleanup(desc, orig_data); + assert(rc < 0); + + desc = liberasurecode_instance_create("null", &null_args); + assert(desc > 0); + + rc = liberasurecode_decode_cleanup(desc, NULL); + assert(rc == 0); +} + +static void test_reconstruct_fragment_invalid_args() +{ + int rc = -1; + int desc = 1; + int frag_len = 10; + char **avail_frags = malloc(sizeof(char *) * 2); + char *out_frag = malloc(frag_len); + + assert(avail_frags); + assert(out_frag); + + rc = liberasurecode_reconstruct_fragment(desc, avail_frags, 1, frag_len, 1, out_frag); + assert(rc < 0); + + desc = liberasurecode_instance_create("null", &null_args); + assert(desc > 0); + + rc = liberasurecode_reconstruct_fragment(desc, NULL, 1, frag_len, 1, out_frag); + assert(rc < 0); + + rc = liberasurecode_reconstruct_fragment(desc, avail_frags, 1, frag_len, 1, NULL); + assert(rc < 0); +} + +static void test_fragments_needed_invalid_args() +{ + int rc = -1; + int desc = 1; + int frags_to_recon = -1; + int frags_to_exclude = -1; + int *frags_needed= NULL; + + rc = liberasurecode_fragments_needed(desc, &frags_to_recon, &frags_to_exclude, frags_needed); + assert(rc < 0); + + desc = liberasurecode_instance_create("null", &null_args); + assert(desc > 0); + + rc = liberasurecode_fragments_needed(desc, NULL, &frags_to_exclude, frags_needed); + assert(rc < 0); + + rc = liberasurecode_fragments_needed(desc, &frags_to_recon, NULL, frags_needed); + assert(rc < 0); + + rc = liberasurecode_fragments_needed(desc, &frags_to_recon, &frags_to_exclude, NULL); + assert(rc < 0); +} + static void encode_decode_test_impl(const char *backend, struct ec_args *args, int *skip) @@ -199,18 +415,17 @@ static void encode_decode_test_impl(const char *backend, assert(decoded_data_len == orig_data_size); assert(memcmp(decoded_data, orig_data, orig_data_size) == 0); + 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); - if (avail_frags != NULL) { - int idx = 0; - for (idx = 0; idx < num_avail_frags; idx++) { - free(avail_frags[idx]); - } - free(avail_frags); - } } static void reconstruct_test_impl(const char *backend, @@ -498,31 +713,43 @@ static void test_fragments_needed(const char *backend, test_fragments_needed_impl(backend, args); } -struct ec_args null_args = { - .k = 8, - .m = 4, - .priv_args1.null_args.arg1 = 11, -}; +static void test_backend_lookup_by_name() +{ + const char *null_name = NULL; + const char *empty_name = ""; + const char *white_space_name = " "; + const char *missing_name = "1DONT3XIST!"; + int i =0, num_backends; + const char **supported_ec_backends = + liberasurecode_supported_backends(&num_backends); -struct ec_args flat_xor_hd_args = { - .k = 10, - .m = 6, - .hd = 4, -}; + assert(liberasurecode_backend_lookup_by_name(null_name) == NULL); + assert(liberasurecode_backend_lookup_by_name(empty_name) == NULL); + assert(liberasurecode_backend_lookup_by_name(white_space_name) == NULL); + assert(liberasurecode_backend_lookup_by_name(missing_name) == NULL); -struct ec_args jerasure_rs_vand_args = { - .k = 10, - .m = 4, - .w = 16, - .hd = 5, -}; + for (i = 0; i < num_backends; i++) { + assert(liberasurecode_backend_lookup_by_name(supported_ec_backends[i]) != NULL); + } +} -struct ec_args jerasure_rs_cauchy_args = { - .k = 10, - .m = 4, - .w = 4, - .hd = 5, -}; +static void test_backend_lookup_by_id() +{ + const char *null_name = NULL; + const char *empty_name = ""; + const char *white_space_name = " "; + const char *missing_name = "1DONT3XIST!"; + int i =0, num_backends; + const char **supported_ec_backends = + liberasurecode_supported_backends(&num_backends); + assert(liberasurecode_backend_lookup_id(null_name) == -1); + assert(liberasurecode_backend_lookup_id(empty_name) == -1); + assert(liberasurecode_backend_lookup_id(white_space_name) == -1); + assert(liberasurecode_backend_lookup_id(missing_name) == -1); + for (i = 0; i < num_backends; i++) { + assert(liberasurecode_backend_lookup_id(supported_ec_backends[i]) == i); + } +} struct testcase testcases[] = { {"liberasurecode_supported_backends", @@ -533,28 +760,60 @@ struct testcase testcases[] = { test_liberasurecode_supported_checksum_types, NULL, NULL, .skip = false}, - {"create_and_destroy_backend", - test_create_and_destroy_backend, - "null", &null_args, + {"look_up_by_name", + test_backend_lookup_by_name, + NULL, NULL, .skip = false}, - {"create_and_destroy_backend", - test_create_and_destroy_backend, - "flat_xor_hd", &flat_xor_hd_args, + {"look_up_by_id", + test_backend_lookup_by_id, + NULL, NULL, .skip = false}, - {"create_and_destroy_backend", - test_create_and_destroy_backend, - "jerasure_rs_vand", &jerasure_rs_vand_args, + {"test_create_backend_invalid_args", + test_create_backend_invalid_args, + NULL, NULL, + .skip = false}, + {"test_create_backend_invalid_args", + test_destroy_backend_invalid_args, + NULL, NULL, .skip = false}, + {"test_encode_invalid_args", + test_encode_invalid_args, + NULL, NULL, + .skip = false}, + {"test_encode_cleanup_invalid_args", + test_encode_cleanup_invalid_args, + NULL, NULL, + .skip = false}, + {"test_decode_invalid_args", + test_decode_invalid_args, + NULL, NULL, + .skip = false}, + {"test_decode_cleanup_invalid_args", + test_decode_cleanup_invalid_args, + NULL, NULL, + .skip = false}, + {"test_reconstruct_fragment_invalid_args", + test_reconstruct_fragment_invalid_args, + NULL, NULL, + .skip = false}, + {"test_fragments_needed_invalid_args", + test_fragments_needed_invalid_args, + NULL, NULL, + .skip = false}, + // NULL backend test {"create_and_destroy_backend", test_create_and_destroy_backend, - "jerasure_rs_cauchy", &jerasure_rs_cauchy_args, + "null", &null_args, .skip = false}, - // NULL backend tests {"simple_encode_null", test_simple_encode_decode, "null", &null_args, .skip = false}, // Flat XOR backend tests + {"create_and_destroy_backend", + test_create_and_destroy_backend, + "flat_xor_hd", &flat_xor_hd_args, + .skip = false}, {"simple_encode_flat_xor_hd", test_simple_encode_decode, "flat_xor_hd", &flat_xor_hd_args, @@ -588,6 +847,10 @@ struct testcase testcases[] = { "flat_xor_hd", &flat_xor_hd_args, .skip = false}, // Jerasure RS Vand backend tests + {"create_and_destroy_backend", + test_create_and_destroy_backend, + "jerasure_rs_vand", &jerasure_rs_vand_args, + .skip = false}, {"simple_encode_jerasure_rs_vand", test_simple_encode_decode, "jerasure_rs_vand", &jerasure_rs_vand_args, @@ -617,6 +880,10 @@ struct testcase testcases[] = { "jerasure_rs_vand", &jerasure_rs_vand_args, .skip = false}, // Jerasure RS Cauchy backend tests + {"create_and_destroy_backend", + test_create_and_destroy_backend, + "jerasure_rs_cauchy", &jerasure_rs_cauchy_args, + .skip = false}, {"simple_encode_jerasure_rs_cauchy", test_simple_encode_decode, "jerasure_rs_cauchy", &jerasure_rs_cauchy_args, |