summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Lambert <eric_lambert@xyratex.com>2014-09-02 11:12:16 -0700
committerEric Lambert <eric_lambert@xyratex.com>2014-09-02 11:12:16 -0700
commit81c47389ba9a6568224481ca4a2eabbb99f5db2f (patch)
tree7ac48ce93dfc56aea12dd1c25f9670132db96b42
parentcde80cfe27b40ab46d5e2afc1516e942f423a289 (diff)
downloadliberasurecode-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.c104
-rw-r--r--test/liberasurecode_test.c347
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,