Break out multi-threaded tests to separate file
Change-Id: Ie640f84a83256cdc3ea7cc3dfb745a0e7a7298b1 Signed-off-by: Tim Burke <tim.burke@gmail.com>
This commit is contained in:
@@ -47,6 +47,7 @@ install-exec-hook:
|
||||
|
||||
test: check
|
||||
@./test/liberasurecode_test
|
||||
@./test/liberasurecode_threaded_test
|
||||
@./test/alg_sig_test
|
||||
@./test/test_xor_hd_code
|
||||
@./test/libec_slap
|
||||
@@ -59,6 +60,7 @@ VALGRIND_EXEC_COMMAND = $(LIBTOOL_COMMAND) valgrind --tool=memcheck \
|
||||
valgrind-test: check
|
||||
@$(VALGRIND_EXEC_COMMAND) ./test/alg_sig_test
|
||||
@$(VALGRIND_EXEC_COMMAND) ./test/liberasurecode_test
|
||||
@$(VALGRIND_EXEC_COMMAND) ./test/liberasurecode_threaded_test
|
||||
@$(VALGRIND_EXEC_COMMAND) ./test/test_xor_hd_code
|
||||
@$(VALGRIND_EXEC_COMMAND) ./test/libec_slap
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
noinst_HEADERS = builtin/xor_codes/test_xor_hd_code.h
|
||||
noinst_PROGRAMS = test_xor_hd_code alg_sig_test liberasurecode_test libec_slap rs_galois_test liberasurecode_rs_vand_test liberasurecode_rs_isal_stress_test
|
||||
noinst_PROGRAMS = test_xor_hd_code alg_sig_test liberasurecode_test liberasurecode_threaded_test libec_slap rs_galois_test liberasurecode_rs_vand_test liberasurecode_rs_isal_stress_test
|
||||
|
||||
test_xor_hd_code_SOURCES = \
|
||||
builtin/xor_codes/test_xor_hd_code.c \
|
||||
@@ -18,6 +18,11 @@ liberasurecode_test_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/e
|
||||
liberasurecode_test_LDFLAGS = @GCOV_LDFLAGS@ $(top_builddir)/src/liberasurecode.la -ldl -lpthread -lz
|
||||
check_PROGRAMS += liberasurecode_test
|
||||
|
||||
liberasurecode_threaded_test_SOURCES = liberasurecode_threaded_test.c
|
||||
liberasurecode_threaded_test_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/erasurecode @GCOV_FLAGS@
|
||||
liberasurecode_threaded_test_LDFLAGS = @GCOV_LDFLAGS@ $(top_builddir)/src/liberasurecode.la -ldl -lpthread -lz
|
||||
check_PROGRAMS += liberasurecode_threaded_test
|
||||
|
||||
libec_slap_SOURCES = libec_slap.c
|
||||
libec_slap_CPPFLAGS = -I. -I$(top_srcdir)/include -I$(top_srcdir)/include/erasurecode @GCOV_FLAGS@
|
||||
libec_slap_LDFLAGS = @GCOV_LDFLAGS@ $(top_builddir)/src/liberasurecode.la -ldl -lpthread
|
||||
|
||||
@@ -566,425 +566,6 @@ static void test_create_and_destroy_multiple_backends(
|
||||
assert(0 == liberasurecode_instance_destroy(desc2));
|
||||
}
|
||||
|
||||
void* destroy_backend_in_thread(void* arg)
|
||||
{
|
||||
int *desc = arg;
|
||||
int *rc = malloc(sizeof(int));
|
||||
*rc = liberasurecode_instance_destroy(*desc);
|
||||
assert(0 == *rc || -EBACKENDNOTAVAIL == *rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void test_multi_thread_destroy_backend(
|
||||
ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
pthread_t tid1, tid2;
|
||||
int *rc1, *rc2;
|
||||
int desc = liberasurecode_instance_create(be_id, args);
|
||||
if (-EBACKENDNOTAVAIL == desc) {
|
||||
fprintf(stderr, "Backend library not available!\n");
|
||||
return;
|
||||
}
|
||||
assert(desc > 0);
|
||||
pthread_create(&tid1, NULL, destroy_backend_in_thread, &desc);
|
||||
pthread_create(&tid2, NULL, destroy_backend_in_thread, &desc);
|
||||
pthread_join(tid1, (void *) &rc1);
|
||||
pthread_join(tid2, (void *) &rc2);
|
||||
/* The threads race; only one succeeds */
|
||||
assert(*rc1 == 0 || *rc2 == 0);
|
||||
/* The other fails with -EBACKENDNOTAVAIL */
|
||||
assert(*rc1 == -EBACKENDNOTAVAIL || *rc2 == -EBACKENDNOTAVAIL);
|
||||
free(rc1);
|
||||
free(rc2);
|
||||
}
|
||||
|
||||
struct encode_state {
|
||||
int desc1;
|
||||
int desc2;
|
||||
int data_sz;
|
||||
char *data;
|
||||
};
|
||||
|
||||
void* encode_in_thread(void* arg)
|
||||
{
|
||||
struct encode_state *s = arg;
|
||||
int *rc = malloc(sizeof(int));
|
||||
char **encoded_data = NULL, **encoded_parity = NULL;
|
||||
uint64_t encoded_fragment_len = 0;
|
||||
*rc = liberasurecode_encode(s->desc1, s->data, s->data_sz,
|
||||
&encoded_data, &encoded_parity, &encoded_fragment_len);
|
||||
assert(0 == *rc || -EBACKENDNOTAVAIL == *rc);
|
||||
if (*rc == 0) {
|
||||
assert(liberasurecode_encode_cleanup(s->desc2, encoded_data, encoded_parity) == 0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void test_multi_thread_encode_and_destroy_backend(
|
||||
ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
pthread_t tid1, tid2;
|
||||
int *rc1, *rc2;
|
||||
int desc = liberasurecode_instance_create(be_id, args);
|
||||
if (-EBACKENDNOTAVAIL == desc) {
|
||||
fprintf(stderr, "Backend library not available!\n");
|
||||
return;
|
||||
}
|
||||
assert(desc > 0);
|
||||
int orig_data_size = 1024 * 1024;
|
||||
struct encode_state s = {
|
||||
desc,
|
||||
/* need a second descriptor so we can clean up
|
||||
* even after first descriptor is destroyed */
|
||||
liberasurecode_instance_create(be_id, args),
|
||||
orig_data_size,
|
||||
create_buffer(orig_data_size, 'x')
|
||||
};
|
||||
assert(s.data != NULL);
|
||||
pthread_create(&tid2, NULL, encode_in_thread, &s);
|
||||
pthread_create(&tid1, NULL, destroy_backend_in_thread, &desc);
|
||||
pthread_join(tid1, (void *) &rc1);
|
||||
pthread_join(tid2, (void *) &rc2);
|
||||
/* The threads race, but destroy always succeeds */
|
||||
assert(*rc1 == 0);
|
||||
assert(liberasurecode_instance_destroy(s.desc2) == 0);
|
||||
free(rc1);
|
||||
free(rc2);
|
||||
free(s.data);
|
||||
}
|
||||
|
||||
struct create_state {
|
||||
ec_backend_id_t be_id;
|
||||
struct ec_args *args;
|
||||
};
|
||||
|
||||
void* create_backend_in_thread(void* arg)
|
||||
{
|
||||
struct create_state *s = arg;
|
||||
int *desc = malloc(sizeof(int));
|
||||
*desc = liberasurecode_instance_create(s->be_id, s->args);
|
||||
return desc;
|
||||
}
|
||||
|
||||
static void test_multi_thread_create_backend(
|
||||
ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
pthread_t tid1, tid2;
|
||||
int *desc1, *desc2;
|
||||
|
||||
struct create_state s = {
|
||||
be_id,
|
||||
args
|
||||
};
|
||||
if (!liberasurecode_backend_available(be_id)) {
|
||||
fprintf(stderr, "Backend library not available!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_create(&tid1, NULL, create_backend_in_thread, &s);
|
||||
pthread_create(&tid2, NULL, create_backend_in_thread, &s);
|
||||
pthread_join(tid1, (void *) &desc1);
|
||||
pthread_join(tid2, (void *) &desc2);
|
||||
assert(*desc1 > 0);
|
||||
assert(*desc2 > 0);
|
||||
assert(*desc1 != *desc2);
|
||||
/**
|
||||
* Each can be destroyed, showing that each was properly added to the
|
||||
* registry */
|
||||
assert(0 == liberasurecode_instance_destroy(*desc1));
|
||||
assert(0 == liberasurecode_instance_destroy(*desc2));
|
||||
free(desc1);
|
||||
free(desc2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct decode_state {
|
||||
int desc1;
|
||||
int desc2;
|
||||
char **available_fragments;
|
||||
int num_fragments;
|
||||
uint64_t fragment_len;
|
||||
};
|
||||
|
||||
void* decode_in_thread(void* arg)
|
||||
{
|
||||
struct decode_state *s = arg;
|
||||
int *rc = malloc(sizeof(int));
|
||||
char *decoded_data = NULL;
|
||||
uint64_t decoded_data_len = 0;
|
||||
*rc = liberasurecode_decode(s->desc1, s->available_fragments,
|
||||
s->num_fragments, s->fragment_len, 0, /* force_metadata_checks */
|
||||
&decoded_data, &decoded_data_len);
|
||||
assert(0 == *rc || -EBACKENDNOTAVAIL == *rc);
|
||||
if (*rc == 0) {
|
||||
assert(liberasurecode_decode_cleanup(s->desc2, decoded_data) == 0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void test_multi_thread_decode_and_destroy_backend(
|
||||
ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
pthread_t tid1, tid2;
|
||||
int *rc1, *rc2;
|
||||
int desc = liberasurecode_instance_create(be_id, args);
|
||||
if (-EBACKENDNOTAVAIL == desc) {
|
||||
fprintf(stderr, "Backend library not available!\n");
|
||||
return;
|
||||
}
|
||||
assert(desc > 0);
|
||||
|
||||
int orig_data_size = 1024 * 1024;
|
||||
char *orig_data = create_buffer(orig_data_size, 'x');
|
||||
assert(orig_data != NULL);
|
||||
|
||||
char **encoded_data = NULL, **encoded_parity = NULL;
|
||||
uint64_t encoded_fragment_len = 0;
|
||||
int rc = liberasurecode_encode(desc, orig_data, orig_data_size,
|
||||
&encoded_data, &encoded_parity, &encoded_fragment_len);
|
||||
assert(rc == 0);
|
||||
|
||||
/* Create available fragments array using the same method as existing tests */
|
||||
char **available_fragments = NULL;
|
||||
int *skip = create_skips_array(args, -1);
|
||||
assert(skip != NULL);
|
||||
int num_avail_frags = create_frags_array(&available_fragments, encoded_data,
|
||||
encoded_parity, args, skip);
|
||||
assert(num_avail_frags > 0);
|
||||
|
||||
struct decode_state s = {
|
||||
desc,
|
||||
/* need a second descriptor so we can clean up
|
||||
* even after first descriptor is destroyed */
|
||||
liberasurecode_instance_create(be_id, args),
|
||||
available_fragments,
|
||||
num_avail_frags,
|
||||
encoded_fragment_len
|
||||
};
|
||||
assert(s.desc2 > 0);
|
||||
|
||||
pthread_create(&tid2, NULL, decode_in_thread, &s);
|
||||
pthread_create(&tid1, NULL, destroy_backend_in_thread, &desc);
|
||||
pthread_join(tid1, (void *) &rc1);
|
||||
pthread_join(tid2, (void *) &rc2);
|
||||
/* The threads race, but destroy always succeeds */
|
||||
assert(*rc1 == 0);
|
||||
|
||||
liberasurecode_encode_cleanup(s.desc2, encoded_data, encoded_parity);
|
||||
assert(liberasurecode_instance_destroy(s.desc2) == 0);
|
||||
|
||||
free(available_fragments);
|
||||
free(skip);
|
||||
free(rc1);
|
||||
free(rc2);
|
||||
free(orig_data);
|
||||
}
|
||||
|
||||
struct reconstruct_state {
|
||||
int desc1;
|
||||
int desc2;
|
||||
char **available_fragments;
|
||||
int num_fragments;
|
||||
uint64_t fragment_len;
|
||||
int missing_idx;
|
||||
char *out_fragment;
|
||||
};
|
||||
|
||||
void* reconstruct_in_thread(void* arg)
|
||||
{
|
||||
struct reconstruct_state *s = arg;
|
||||
int *rc = malloc(sizeof(int));
|
||||
*rc = liberasurecode_reconstruct_fragment(s->desc1, s->available_fragments,
|
||||
s->num_fragments, s->fragment_len, s->missing_idx, s->out_fragment);
|
||||
assert(0 == *rc || -EBACKENDNOTAVAIL == *rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void test_multi_thread_reconstruct_and_destroy_backend(
|
||||
ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
pthread_t tid1, tid2;
|
||||
int *rc1, *rc2;
|
||||
int desc = liberasurecode_instance_create(be_id, args);
|
||||
if (-EBACKENDNOTAVAIL == desc) {
|
||||
fprintf(stderr, "Backend library not available!\n");
|
||||
return;
|
||||
}
|
||||
assert(desc > 0);
|
||||
|
||||
int orig_data_size = 1024 * 1024;
|
||||
char *orig_data = create_buffer(orig_data_size, 'x');
|
||||
assert(orig_data != NULL);
|
||||
|
||||
char **encoded_data = NULL, **encoded_parity = NULL;
|
||||
uint64_t encoded_fragment_len = 0;
|
||||
int rc = liberasurecode_encode(desc, orig_data, orig_data_size,
|
||||
&encoded_data, &encoded_parity, &encoded_fragment_len);
|
||||
assert(rc == 0);
|
||||
|
||||
/* Create available fragments array with one missing fragment */
|
||||
char **available_fragments = NULL;
|
||||
int *skip = create_skips_array(args, -1);
|
||||
assert(skip != NULL);
|
||||
skip[0] = 1; /* skip first fragment */
|
||||
int num_avail_frags = create_frags_array(&available_fragments, encoded_data,
|
||||
encoded_parity, args, skip);
|
||||
assert(num_avail_frags > 0);
|
||||
|
||||
/* Allocate output fragment buffer */
|
||||
char *out_fragment = malloc(encoded_fragment_len);
|
||||
assert(out_fragment != NULL);
|
||||
|
||||
struct reconstruct_state s = {
|
||||
desc,
|
||||
/* need a second descriptor so we can clean up
|
||||
* even after first descriptor is destroyed */
|
||||
liberasurecode_instance_create(be_id, args),
|
||||
available_fragments,
|
||||
num_avail_frags,
|
||||
encoded_fragment_len,
|
||||
0, /* missing fragment index */
|
||||
out_fragment
|
||||
};
|
||||
assert(s.desc2 > 0);
|
||||
|
||||
pthread_create(&tid2, NULL, reconstruct_in_thread, &s);
|
||||
pthread_create(&tid1, NULL, destroy_backend_in_thread, &desc);
|
||||
pthread_join(tid1, (void *) &rc1);
|
||||
pthread_join(tid2, (void *) &rc2);
|
||||
/* The threads race, but destroy always succeeds */
|
||||
assert(*rc1 == 0);
|
||||
|
||||
liberasurecode_encode_cleanup(s.desc2, encoded_data, encoded_parity);
|
||||
assert(liberasurecode_instance_destroy(s.desc2) == 0);
|
||||
|
||||
free(available_fragments);
|
||||
free(out_fragment);
|
||||
free(skip);
|
||||
free(rc1);
|
||||
free(rc2);
|
||||
free(orig_data);
|
||||
}
|
||||
|
||||
struct fragments_needed_state {
|
||||
int desc1;
|
||||
int desc2;
|
||||
int *fragments_to_reconstruct;
|
||||
int *fragments_to_exclude;
|
||||
int *fragments_needed;
|
||||
};
|
||||
|
||||
void* fragments_needed_in_thread(void* arg)
|
||||
{
|
||||
struct fragments_needed_state *s = arg;
|
||||
int *rc = malloc(sizeof(int));
|
||||
*rc = liberasurecode_fragments_needed(s->desc1, s->fragments_to_reconstruct,
|
||||
s->fragments_to_exclude, s->fragments_needed);
|
||||
assert(0 == *rc || -EBACKENDNOTAVAIL == *rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void test_multi_thread_fragments_needed_and_destroy_backend(
|
||||
ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
pthread_t tid1, tid2;
|
||||
int *rc1, *rc2;
|
||||
int desc = liberasurecode_instance_create(be_id, args);
|
||||
if (-EBACKENDNOTAVAIL == desc) {
|
||||
fprintf(stderr, "Backend library not available!\n");
|
||||
return;
|
||||
}
|
||||
assert(desc > 0);
|
||||
|
||||
int fragments_to_reconstruct[] = {0, -1};
|
||||
int fragments_to_exclude[] = {-1};
|
||||
int *fragments_needed = malloc(sizeof(int) * (args->k + args->m + 1));
|
||||
assert(fragments_needed != NULL);
|
||||
|
||||
struct fragments_needed_state s = {
|
||||
desc,
|
||||
/* need a second descriptor so we can clean up
|
||||
* even after first descriptor is destroyed */
|
||||
liberasurecode_instance_create(be_id, args),
|
||||
fragments_to_reconstruct,
|
||||
fragments_to_exclude,
|
||||
fragments_needed
|
||||
};
|
||||
assert(s.desc2 > 0);
|
||||
|
||||
pthread_create(&tid2, NULL, fragments_needed_in_thread, &s);
|
||||
pthread_create(&tid1, NULL, destroy_backend_in_thread, &desc);
|
||||
pthread_join(tid1, (void *) &rc1);
|
||||
pthread_join(tid2, (void *) &rc2);
|
||||
/* The threads race, but destroy always succeeds */
|
||||
assert(*rc1 == 0);
|
||||
|
||||
assert(liberasurecode_instance_destroy(s.desc2) == 0);
|
||||
free(fragments_needed);
|
||||
free(rc1);
|
||||
free(rc2);
|
||||
}
|
||||
|
||||
struct get_fragment_size_state {
|
||||
int desc1;
|
||||
int desc2;
|
||||
int data_len;
|
||||
};
|
||||
|
||||
void* get_fragment_size_in_thread(void* arg)
|
||||
{
|
||||
struct get_fragment_size_state *s = arg;
|
||||
int *rc = malloc(sizeof(int));
|
||||
*rc = liberasurecode_get_fragment_size(s->desc1, s->data_len);
|
||||
/* This function returns size on success or negative error code on failure */
|
||||
assert(*rc > 0 || *rc == -EBACKENDNOTAVAIL);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void test_multi_thread_get_fragment_size_and_destroy_backend(
|
||||
ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
pthread_t tid1, tid2;
|
||||
int *rc1, *rc2;
|
||||
int desc = liberasurecode_instance_create(be_id, args);
|
||||
if (-EBACKENDNOTAVAIL == desc) {
|
||||
fprintf(stderr, "Backend library not available!\n");
|
||||
return;
|
||||
}
|
||||
assert(desc > 0);
|
||||
|
||||
struct get_fragment_size_state s = {
|
||||
desc,
|
||||
/* need a second descriptor so we can clean up
|
||||
* even after first descriptor is destroyed */
|
||||
liberasurecode_instance_create(be_id, args),
|
||||
1024 * 1024 /* data length */
|
||||
};
|
||||
assert(s.desc2 > 0);
|
||||
|
||||
pthread_create(&tid2, NULL, get_fragment_size_in_thread, &s);
|
||||
pthread_create(&tid1, NULL, destroy_backend_in_thread, &desc);
|
||||
pthread_join(tid1, (void *) &rc1);
|
||||
pthread_join(tid2, (void *) &rc2);
|
||||
/* The threads race, but destroy always succeeds */
|
||||
assert(*rc1 == 0);
|
||||
|
||||
assert(liberasurecode_instance_destroy(s.desc2) == 0);
|
||||
free(rc1);
|
||||
free(rc2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void test_backend_available(void) {
|
||||
assert(1 == liberasurecode_backend_available(EC_BACKEND_NULL));
|
||||
}
|
||||
@@ -2566,14 +2147,7 @@ static void test_metadata_crcs_be(void)
|
||||
#define TEST_SUITE(backend) \
|
||||
TEST({.with_args = test_create_and_destroy_backend}, backend, CHKSUM_NONE), \
|
||||
TEST({.with_args = test_create_and_destroy_multiple_backends}, backend, CHKSUM_NONE), \
|
||||
TEST({.with_args = test_multi_thread_destroy_backend}, backend, CHKSUM_NONE), \
|
||||
TEST({.with_args = test_multi_thread_create_backend}, backend, CHKSUM_NONE), \
|
||||
TEST({.with_args = test_simple_encode_decode}, backend, CHKSUM_NONE), \
|
||||
TEST({.with_args = test_multi_thread_encode_and_destroy_backend}, backend, CHKSUM_NONE), \
|
||||
TEST({.with_args = test_multi_thread_decode_and_destroy_backend}, backend, CHKSUM_NONE), \
|
||||
TEST({.with_args = test_multi_thread_reconstruct_and_destroy_backend}, backend, CHKSUM_NONE), \
|
||||
TEST({.with_args = test_multi_thread_fragments_needed_and_destroy_backend}, backend, CHKSUM_NONE), \
|
||||
TEST({.with_args = test_multi_thread_get_fragment_size_and_destroy_backend}, backend, CHKSUM_NONE), \
|
||||
TEST({.with_args = test_decode_with_missing_data}, backend, CHKSUM_NONE), \
|
||||
TEST({.with_args = test_decode_with_missing_parity}, backend, CHKSUM_NONE), \
|
||||
TEST({.with_args = test_decode_with_missing_multi_data}, backend, CHKSUM_NONE), \
|
||||
|
||||
609
test/liberasurecode_threaded_test.c
Normal file
609
test/liberasurecode_threaded_test.c
Normal file
@@ -0,0 +1,609 @@
|
||||
/*
|
||||
* Copyright 2025 Tim Burke
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY
|
||||
* THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "erasurecode.h"
|
||||
#define NULL_BACKEND "null"
|
||||
#define FLAT_XOR_HD_BACKEND "flat_xor_hd"
|
||||
#define JERASURE_RS_VAND_BACKEND "jerasure_rs_vand"
|
||||
#define JERASURE_RS_CAUCHY_BACKEND "jerasure_rs_cauchy"
|
||||
#define ISA_L_RS_VAND_BACKEND "isa_l_rs_vand"
|
||||
#define ISA_L_RS_VAND_INV_BACKEND "isa_l_rs_vand_inv"
|
||||
#define ISA_L_RS_CAUCHY_BACKEND "isa_l_rs_cauchy"
|
||||
#define SHSS_BACKEND "shss"
|
||||
#define RS_VAND_BACKEND "liberasurecode_rs_vand"
|
||||
#define LIBPHAZR_BACKEND "libphazr"
|
||||
|
||||
typedef void (*TEST_FUNC_WITH_ARGS)(const ec_backend_id_t, struct ec_args *);
|
||||
struct testcase {
|
||||
const char *description;
|
||||
TEST_FUNC_WITH_ARGS function;
|
||||
ec_backend_id_t be_id;
|
||||
};
|
||||
|
||||
char *create_buffer(int size)
|
||||
{
|
||||
char *buf = malloc(size);
|
||||
if (buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
int urand = open("/dev/urandom", O_RDONLY);
|
||||
if (urand < 0 || read(urand, buf, size) != size) {
|
||||
for(size_t i = 0; i < size; i++)
|
||||
buf[i] = rand() % 256;
|
||||
}
|
||||
if (urand >= 0) {
|
||||
close(urand);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
int *create_skips_array(struct ec_args *args, int skip)
|
||||
{
|
||||
int num = args->k + args->m;
|
||||
size_t array_size = sizeof(int) * num;
|
||||
int *buf = malloc(array_size);
|
||||
if (buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(buf, 0, array_size);
|
||||
if (skip >= 0 && skip < num) {
|
||||
buf[skip] = 1;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int create_frags_array(char ***array,
|
||||
char **data,
|
||||
char **parity,
|
||||
struct ec_args *args,
|
||||
int *skips)
|
||||
{
|
||||
// N.B. this function sets pointer reference to the ***array
|
||||
// from **data and **parity so DO NOT free each value of
|
||||
// the array independently because the data and parity will
|
||||
// be expected to be cleanup via liberasurecode_encode_cleanup
|
||||
int num_frags = 0;
|
||||
int i = 0;
|
||||
char **ptr = NULL;
|
||||
*array = malloc((args->k + args->m) * sizeof(char *));
|
||||
if (array == NULL) {
|
||||
num_frags = -1;
|
||||
goto out;
|
||||
}
|
||||
//add data frags
|
||||
ptr = *array;
|
||||
for (i = 0; i < args->k; i++) {
|
||||
if (data[i] == NULL || skips[i] == 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*ptr++ = data[i];
|
||||
num_frags++;
|
||||
}
|
||||
//add parity frags
|
||||
for (i = 0; i < args->m; i++) {
|
||||
if (parity[i] == NULL || skips[i + args->k] == 1) {
|
||||
continue;
|
||||
}
|
||||
*ptr++ = parity[i];
|
||||
num_frags++;
|
||||
}
|
||||
out:
|
||||
return num_frags;
|
||||
}
|
||||
|
||||
void* destroy_backend_in_thread(void* arg)
|
||||
{
|
||||
int *desc = arg;
|
||||
int *rc = malloc(sizeof(int));
|
||||
*rc = liberasurecode_instance_destroy(*desc);
|
||||
assert(0 == *rc || -EBACKENDNOTAVAIL == *rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void test_multi_thread_destroy_backend(
|
||||
ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
pthread_t tid1, tid2;
|
||||
int *rc1, *rc2;
|
||||
int desc = liberasurecode_instance_create(be_id, args);
|
||||
if (-EBACKENDNOTAVAIL == desc) {
|
||||
fprintf(stderr, "Backend library not available!\n");
|
||||
return;
|
||||
}
|
||||
assert(desc > 0);
|
||||
pthread_create(&tid1, NULL, destroy_backend_in_thread, &desc);
|
||||
pthread_create(&tid2, NULL, destroy_backend_in_thread, &desc);
|
||||
pthread_join(tid1, (void *) &rc1);
|
||||
pthread_join(tid2, (void *) &rc2);
|
||||
/* The threads race; only one succeeds */
|
||||
assert(*rc1 == 0 || *rc2 == 0);
|
||||
/* The other fails with -EBACKENDNOTAVAIL */
|
||||
assert(*rc1 == -EBACKENDNOTAVAIL || *rc2 == -EBACKENDNOTAVAIL);
|
||||
free(rc1);
|
||||
free(rc2);
|
||||
}
|
||||
|
||||
struct create_state {
|
||||
ec_backend_id_t be_id;
|
||||
struct ec_args *args;
|
||||
};
|
||||
|
||||
void* create_backend_in_thread(void* arg)
|
||||
{
|
||||
struct create_state *s = arg;
|
||||
int *desc = malloc(sizeof(int));
|
||||
*desc = liberasurecode_instance_create(s->be_id, s->args);
|
||||
return desc;
|
||||
}
|
||||
|
||||
static void test_multi_thread_create_backend(
|
||||
ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
pthread_t tid1, tid2;
|
||||
int *desc1, *desc2;
|
||||
|
||||
struct create_state s = {
|
||||
be_id,
|
||||
args
|
||||
};
|
||||
if (!liberasurecode_backend_available(be_id)) {
|
||||
fprintf(stderr, "Backend library not available!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_create(&tid1, NULL, create_backend_in_thread, &s);
|
||||
pthread_create(&tid2, NULL, create_backend_in_thread, &s);
|
||||
pthread_join(tid1, (void *) &desc1);
|
||||
pthread_join(tid2, (void *) &desc2);
|
||||
assert(*desc1 > 0);
|
||||
assert(*desc2 > 0);
|
||||
assert(*desc1 != *desc2);
|
||||
/**
|
||||
* Each can be destroyed, showing that each was properly added to the
|
||||
* registry */
|
||||
assert(0 == liberasurecode_instance_destroy(*desc1));
|
||||
assert(0 == liberasurecode_instance_destroy(*desc2));
|
||||
free(desc1);
|
||||
free(desc2);
|
||||
}
|
||||
|
||||
struct encode_state {
|
||||
int desc1;
|
||||
int desc2;
|
||||
int data_sz;
|
||||
char *data;
|
||||
};
|
||||
|
||||
void* encode_in_thread(void* arg)
|
||||
{
|
||||
struct encode_state *s = arg;
|
||||
int *rc = malloc(sizeof(int));
|
||||
char **encoded_data = NULL, **encoded_parity = NULL;
|
||||
uint64_t encoded_fragment_len = 0;
|
||||
*rc = liberasurecode_encode(s->desc1, s->data, s->data_sz,
|
||||
&encoded_data, &encoded_parity, &encoded_fragment_len);
|
||||
assert(0 == *rc || -EBACKENDNOTAVAIL == *rc);
|
||||
if (*rc == 0) {
|
||||
assert(liberasurecode_encode_cleanup(s->desc2, encoded_data, encoded_parity) == 0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void test_multi_thread_encode_and_destroy_backend(
|
||||
ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
pthread_t tid1, tid2;
|
||||
int *rc1, *rc2;
|
||||
int desc = liberasurecode_instance_create(be_id, args);
|
||||
if (-EBACKENDNOTAVAIL == desc) {
|
||||
fprintf(stderr, "Backend library not available!\n");
|
||||
return;
|
||||
}
|
||||
assert(desc > 0);
|
||||
int orig_data_size = 1024 * 1024;
|
||||
struct encode_state s = {
|
||||
desc,
|
||||
/* need a second descriptor so we can clean up
|
||||
* even after first descriptor is destroyed */
|
||||
liberasurecode_instance_create(be_id, args),
|
||||
orig_data_size,
|
||||
create_buffer(orig_data_size)
|
||||
};
|
||||
assert(s.data != NULL);
|
||||
pthread_create(&tid2, NULL, encode_in_thread, &s);
|
||||
pthread_create(&tid1, NULL, destroy_backend_in_thread, &desc);
|
||||
pthread_join(tid1, (void *) &rc1);
|
||||
pthread_join(tid2, (void *) &rc2);
|
||||
/* The threads race, but destroy always succeeds */
|
||||
assert(*rc1 == 0);
|
||||
assert(liberasurecode_instance_destroy(s.desc2) == 0);
|
||||
free(rc1);
|
||||
free(rc2);
|
||||
free(s.data);
|
||||
}
|
||||
|
||||
struct decode_state {
|
||||
int desc1;
|
||||
int desc2;
|
||||
char **available_fragments;
|
||||
int num_fragments;
|
||||
uint64_t fragment_len;
|
||||
};
|
||||
|
||||
void* decode_in_thread(void* arg)
|
||||
{
|
||||
struct decode_state *s = arg;
|
||||
int *rc = malloc(sizeof(int));
|
||||
char *decoded_data = NULL;
|
||||
uint64_t decoded_data_len = 0;
|
||||
*rc = liberasurecode_decode(s->desc1, s->available_fragments,
|
||||
s->num_fragments, s->fragment_len, 0, /* force_metadata_checks */
|
||||
&decoded_data, &decoded_data_len);
|
||||
assert(0 == *rc || -EBACKENDNOTAVAIL == *rc);
|
||||
if (*rc == 0) {
|
||||
assert(liberasurecode_decode_cleanup(s->desc2, decoded_data) == 0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void test_multi_thread_decode_and_destroy_backend(
|
||||
ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
pthread_t tid1, tid2;
|
||||
int *rc1, *rc2;
|
||||
int desc = liberasurecode_instance_create(be_id, args);
|
||||
if (-EBACKENDNOTAVAIL == desc) {
|
||||
fprintf(stderr, "Backend library not available!\n");
|
||||
return;
|
||||
}
|
||||
assert(desc > 0);
|
||||
|
||||
int orig_data_size = 1024 * 1024;
|
||||
char *orig_data = create_buffer(orig_data_size);
|
||||
assert(orig_data != NULL);
|
||||
|
||||
char **encoded_data = NULL, **encoded_parity = NULL;
|
||||
uint64_t encoded_fragment_len = 0;
|
||||
int rc = liberasurecode_encode(desc, orig_data, orig_data_size,
|
||||
&encoded_data, &encoded_parity, &encoded_fragment_len);
|
||||
assert(rc == 0);
|
||||
|
||||
/* Create available fragments array using the same method as existing tests */
|
||||
char **available_fragments = NULL;
|
||||
int *skip = create_skips_array(args, -1);
|
||||
assert(skip != NULL);
|
||||
int num_avail_frags = create_frags_array(&available_fragments, encoded_data,
|
||||
encoded_parity, args, skip);
|
||||
assert(num_avail_frags > 0);
|
||||
|
||||
struct decode_state s = {
|
||||
desc,
|
||||
/* need a second descriptor so we can clean up
|
||||
* even after first descriptor is destroyed */
|
||||
liberasurecode_instance_create(be_id, args),
|
||||
available_fragments,
|
||||
num_avail_frags,
|
||||
encoded_fragment_len
|
||||
};
|
||||
assert(s.desc2 > 0);
|
||||
|
||||
pthread_create(&tid2, NULL, decode_in_thread, &s);
|
||||
pthread_create(&tid1, NULL, destroy_backend_in_thread, &desc);
|
||||
pthread_join(tid1, (void *) &rc1);
|
||||
pthread_join(tid2, (void *) &rc2);
|
||||
/* The threads race, but destroy always succeeds */
|
||||
assert(*rc1 == 0);
|
||||
|
||||
liberasurecode_encode_cleanup(s.desc2, encoded_data, encoded_parity);
|
||||
assert(liberasurecode_instance_destroy(s.desc2) == 0);
|
||||
|
||||
free(available_fragments);
|
||||
free(skip);
|
||||
free(rc1);
|
||||
free(rc2);
|
||||
free(orig_data);
|
||||
}
|
||||
|
||||
struct reconstruct_state {
|
||||
int desc1;
|
||||
int desc2;
|
||||
char **available_fragments;
|
||||
int num_fragments;
|
||||
uint64_t fragment_len;
|
||||
int missing_idx;
|
||||
char *out_fragment;
|
||||
};
|
||||
|
||||
void* reconstruct_in_thread(void* arg)
|
||||
{
|
||||
struct reconstruct_state *s = arg;
|
||||
int *rc = malloc(sizeof(int));
|
||||
*rc = liberasurecode_reconstruct_fragment(s->desc1, s->available_fragments,
|
||||
s->num_fragments, s->fragment_len, s->missing_idx, s->out_fragment);
|
||||
assert(0 == *rc || -EBACKENDNOTAVAIL == *rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void test_multi_thread_reconstruct_and_destroy_backend(
|
||||
ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
pthread_t tid1, tid2;
|
||||
int *rc1, *rc2;
|
||||
int desc = liberasurecode_instance_create(be_id, args);
|
||||
if (-EBACKENDNOTAVAIL == desc) {
|
||||
fprintf(stderr, "Backend library not available!\n");
|
||||
return;
|
||||
}
|
||||
assert(desc > 0);
|
||||
|
||||
int orig_data_size = 1024 * 1024;
|
||||
char *orig_data = create_buffer(orig_data_size);
|
||||
assert(orig_data != NULL);
|
||||
|
||||
char **encoded_data = NULL, **encoded_parity = NULL;
|
||||
uint64_t encoded_fragment_len = 0;
|
||||
int rc = liberasurecode_encode(desc, orig_data, orig_data_size,
|
||||
&encoded_data, &encoded_parity, &encoded_fragment_len);
|
||||
assert(rc == 0);
|
||||
|
||||
/* Create available fragments array with one missing fragment */
|
||||
char **available_fragments = NULL;
|
||||
int *skip = create_skips_array(args, -1);
|
||||
assert(skip != NULL);
|
||||
skip[0] = 1; /* skip first fragment */
|
||||
int num_avail_frags = create_frags_array(&available_fragments, encoded_data,
|
||||
encoded_parity, args, skip);
|
||||
assert(num_avail_frags > 0);
|
||||
|
||||
/* Allocate output fragment buffer */
|
||||
char *out_fragment = malloc(encoded_fragment_len);
|
||||
assert(out_fragment != NULL);
|
||||
|
||||
struct reconstruct_state s = {
|
||||
desc,
|
||||
/* need a second descriptor so we can clean up
|
||||
* even after first descriptor is destroyed */
|
||||
liberasurecode_instance_create(be_id, args),
|
||||
available_fragments,
|
||||
num_avail_frags,
|
||||
encoded_fragment_len,
|
||||
0, /* missing fragment index */
|
||||
out_fragment
|
||||
};
|
||||
assert(s.desc2 > 0);
|
||||
|
||||
pthread_create(&tid2, NULL, reconstruct_in_thread, &s);
|
||||
pthread_create(&tid1, NULL, destroy_backend_in_thread, &desc);
|
||||
pthread_join(tid1, (void *) &rc1);
|
||||
pthread_join(tid2, (void *) &rc2);
|
||||
/* The threads race, but destroy always succeeds */
|
||||
assert(*rc1 == 0);
|
||||
|
||||
liberasurecode_encode_cleanup(s.desc2, encoded_data, encoded_parity);
|
||||
assert(liberasurecode_instance_destroy(s.desc2) == 0);
|
||||
|
||||
free(available_fragments);
|
||||
free(out_fragment);
|
||||
free(skip);
|
||||
free(rc1);
|
||||
free(rc2);
|
||||
free(orig_data);
|
||||
}
|
||||
|
||||
struct fragments_needed_state {
|
||||
int desc1;
|
||||
int desc2;
|
||||
int *fragments_to_reconstruct;
|
||||
int *fragments_to_exclude;
|
||||
int *fragments_needed;
|
||||
};
|
||||
|
||||
void* fragments_needed_in_thread(void* arg)
|
||||
{
|
||||
struct fragments_needed_state *s = arg;
|
||||
int *rc = malloc(sizeof(int));
|
||||
*rc = liberasurecode_fragments_needed(s->desc1, s->fragments_to_reconstruct,
|
||||
s->fragments_to_exclude, s->fragments_needed);
|
||||
assert(0 == *rc || -EBACKENDNOTAVAIL == *rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void test_multi_thread_fragments_needed_and_destroy_backend(
|
||||
ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
pthread_t tid1, tid2;
|
||||
int *rc1, *rc2;
|
||||
int desc = liberasurecode_instance_create(be_id, args);
|
||||
if (-EBACKENDNOTAVAIL == desc) {
|
||||
fprintf(stderr, "Backend library not available!\n");
|
||||
return;
|
||||
}
|
||||
assert(desc > 0);
|
||||
|
||||
int fragments_to_reconstruct[] = {0, -1};
|
||||
int fragments_to_exclude[] = {-1};
|
||||
int *fragments_needed = malloc(sizeof(int) * (args->k + args->m + 1));
|
||||
assert(fragments_needed != NULL);
|
||||
|
||||
struct fragments_needed_state s = {
|
||||
desc,
|
||||
/* need a second descriptor so we can clean up
|
||||
* even after first descriptor is destroyed */
|
||||
liberasurecode_instance_create(be_id, args),
|
||||
fragments_to_reconstruct,
|
||||
fragments_to_exclude,
|
||||
fragments_needed
|
||||
};
|
||||
assert(s.desc2 > 0);
|
||||
|
||||
pthread_create(&tid2, NULL, fragments_needed_in_thread, &s);
|
||||
pthread_create(&tid1, NULL, destroy_backend_in_thread, &desc);
|
||||
pthread_join(tid1, (void *) &rc1);
|
||||
pthread_join(tid2, (void *) &rc2);
|
||||
/* The threads race, but destroy always succeeds */
|
||||
assert(*rc1 == 0);
|
||||
|
||||
assert(liberasurecode_instance_destroy(s.desc2) == 0);
|
||||
free(fragments_needed);
|
||||
free(rc1);
|
||||
free(rc2);
|
||||
}
|
||||
|
||||
struct get_fragment_size_state {
|
||||
int desc1;
|
||||
int desc2;
|
||||
int data_len;
|
||||
};
|
||||
|
||||
void* get_fragment_size_in_thread(void* arg)
|
||||
{
|
||||
struct get_fragment_size_state *s = arg;
|
||||
int *rc = malloc(sizeof(int));
|
||||
*rc = liberasurecode_get_fragment_size(s->desc1, s->data_len);
|
||||
/* This function returns size on success or negative error code on failure */
|
||||
assert(*rc > 0 || *rc == -EBACKENDNOTAVAIL);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void test_multi_thread_get_fragment_size_and_destroy_backend(
|
||||
ec_backend_id_t be_id,
|
||||
struct ec_args *args)
|
||||
{
|
||||
pthread_t tid1, tid2;
|
||||
int *rc1, *rc2;
|
||||
int desc = liberasurecode_instance_create(be_id, args);
|
||||
if (-EBACKENDNOTAVAIL == desc) {
|
||||
fprintf(stderr, "Backend library not available!\n");
|
||||
return;
|
||||
}
|
||||
assert(desc > 0);
|
||||
|
||||
struct get_fragment_size_state s = {
|
||||
desc,
|
||||
/* need a second descriptor so we can clean up
|
||||
* even after first descriptor is destroyed */
|
||||
liberasurecode_instance_create(be_id, args),
|
||||
1024 * 1024 /* data length */
|
||||
};
|
||||
assert(s.desc2 > 0);
|
||||
|
||||
pthread_create(&tid2, NULL, get_fragment_size_in_thread, &s);
|
||||
pthread_create(&tid1, NULL, destroy_backend_in_thread, &desc);
|
||||
pthread_join(tid1, (void *) &rc1);
|
||||
pthread_join(tid2, (void *) &rc2);
|
||||
/* The threads race, but destroy always succeeds */
|
||||
assert(*rc1 == 0);
|
||||
|
||||
assert(liberasurecode_instance_destroy(s.desc2) == 0);
|
||||
free(rc1);
|
||||
free(rc2);
|
||||
}
|
||||
|
||||
#define TEST(test, backend) {#test, test, backend}
|
||||
#define TEST_SUITE(backend) \
|
||||
TEST(test_multi_thread_destroy_backend, backend), \
|
||||
TEST(test_multi_thread_create_backend, backend), \
|
||||
TEST(test_multi_thread_encode_and_destroy_backend, backend), \
|
||||
TEST(test_multi_thread_decode_and_destroy_backend, backend), \
|
||||
TEST(test_multi_thread_reconstruct_and_destroy_backend, backend), \
|
||||
TEST(test_multi_thread_fragments_needed_and_destroy_backend, backend), \
|
||||
TEST(test_multi_thread_get_fragment_size_and_destroy_backend, backend)
|
||||
|
||||
struct testcase testcases[] = {
|
||||
TEST_SUITE(EC_BACKEND_FLAT_XOR_HD),
|
||||
TEST_SUITE(EC_BACKEND_LIBERASURECODE_RS_VAND),
|
||||
TEST_SUITE(EC_BACKEND_JERASURE_RS_VAND),
|
||||
TEST_SUITE(EC_BACKEND_JERASURE_RS_CAUCHY),
|
||||
TEST_SUITE(EC_BACKEND_ISA_L_RS_VAND),
|
||||
TEST_SUITE(EC_BACKEND_ISA_L_RS_CAUCHY),
|
||||
TEST_SUITE(EC_BACKEND_ISA_L_RS_VAND_INV),
|
||||
TEST_SUITE(EC_BACKEND_SHSS),
|
||||
TEST_SUITE(EC_BACKEND_LIBPHAZR),
|
||||
{ NULL, NULL, 0},
|
||||
};
|
||||
|
||||
char * get_name_from_backend_id(ec_backend_id_t be) {
|
||||
switch(be) {
|
||||
case EC_BACKEND_NULL:
|
||||
return NULL_BACKEND;
|
||||
case EC_BACKEND_JERASURE_RS_VAND:
|
||||
return JERASURE_RS_VAND_BACKEND;
|
||||
case EC_BACKEND_JERASURE_RS_CAUCHY:
|
||||
return JERASURE_RS_CAUCHY_BACKEND;
|
||||
case EC_BACKEND_FLAT_XOR_HD:
|
||||
return FLAT_XOR_HD_BACKEND;
|
||||
case EC_BACKEND_ISA_L_RS_VAND:
|
||||
return ISA_L_RS_VAND_BACKEND;
|
||||
case EC_BACKEND_ISA_L_RS_VAND_INV:
|
||||
return ISA_L_RS_VAND_INV_BACKEND;
|
||||
case EC_BACKEND_ISA_L_RS_CAUCHY:
|
||||
return ISA_L_RS_CAUCHY_BACKEND;
|
||||
case EC_BACKEND_SHSS:
|
||||
return SHSS_BACKEND;
|
||||
case EC_BACKEND_LIBERASURECODE_RS_VAND:
|
||||
return RS_VAND_BACKEND;
|
||||
case EC_BACKEND_LIBPHAZR:
|
||||
return LIBPHAZR_BACKEND;
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
struct ec_args args = {
|
||||
.k = 10,
|
||||
.m = 5,
|
||||
.w = 16,
|
||||
.hd = 4,
|
||||
.ct = CHKSUM_NONE,
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int n;
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
for (n = 0; testcases[n].description != NULL; ++n) {
|
||||
printf("%d - %s: %s ... ", n,
|
||||
testcases[n].description,
|
||||
get_name_from_backend_id(testcases[n].be_id));
|
||||
if (!liberasurecode_backend_available(testcases[n].be_id)) {
|
||||
printf("skip: backend not available\n");
|
||||
} else {
|
||||
testcases[n].function(testcases[n].be_id, &args);
|
||||
printf("ok\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user