test/compress: add stateful decompression

This patch adds two new tests that cover the stateful
decompression feature.

Signed-off-by: Adam Dybkowski <adamx.dybkowski@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
This commit is contained in:
Adam Dybkowski 2019-09-20 22:06:28 +02:00 committed by Akhil Goyal
parent 82822753bd
commit 07b810c57b

View File

@ -95,11 +95,15 @@ struct interim_data_params {
};
struct test_data_params {
enum rte_comp_op_type state;
enum rte_comp_op_type compress_state;
enum rte_comp_op_type decompress_state;
enum varied_buff buff_type;
enum zlib_direction zlib_dir;
unsigned int out_of_space;
unsigned int big_data;
/* stateful decompression specific parameters */
unsigned int decompress_output_block_size;
unsigned int decompress_steps_max;
};
static struct comp_testsuite_params testsuite_params = { 0 };
@ -237,7 +241,7 @@ generic_ut_setup(void)
.socket_id = rte_socket_id(),
.nb_queue_pairs = 1,
.max_nb_priv_xforms = NUM_MAX_XFORMS,
.max_nb_streams = 0
.max_nb_streams = 1
};
if (rte_compressdev_configure(0, &config) < 0) {
@ -275,7 +279,7 @@ test_compressdev_invalid_configuration(void)
.socket_id = rte_socket_id(),
.nb_queue_pairs = 1,
.max_nb_priv_xforms = NUM_MAX_XFORMS,
.max_nb_streams = 0
.max_nb_streams = 1
};
struct rte_compressdev_info dev_info;
@ -724,7 +728,8 @@ test_deflate_comp_decomp(const struct interim_data_params *int_data,
struct rte_comp_xform **compress_xforms = int_data->compress_xforms;
struct rte_comp_xform **decompress_xforms = int_data->decompress_xforms;
unsigned int num_xforms = int_data->num_xforms;
enum rte_comp_op_type state = test_data->state;
enum rte_comp_op_type compress_state = test_data->compress_state;
enum rte_comp_op_type decompress_state = test_data->decompress_state;
unsigned int buff_type = test_data->buff_type;
unsigned int out_of_space = test_data->out_of_space;
unsigned int big_data = test_data->big_data;
@ -754,6 +759,13 @@ test_deflate_comp_decomp(const struct interim_data_params *int_data,
rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);
char *contig_buf = NULL;
uint64_t compress_checksum[num_bufs];
void *stream = NULL;
char *all_decomp_data = NULL;
unsigned int decomp_produced_data_size = 0;
unsigned int step = 0;
TEST_ASSERT(decompress_state == RTE_COMP_OP_STATELESS || num_bufs == 1,
"Number of stateful operations in a step should be 1");
if (capa == NULL) {
RTE_LOG(ERR, USER1,
@ -768,6 +780,12 @@ test_deflate_comp_decomp(const struct interim_data_params *int_data,
memset(ops_processed, 0, sizeof(struct rte_comp_op *) * num_bufs);
memset(priv_xforms, 0, sizeof(void *) * num_bufs);
if (decompress_state == RTE_COMP_OP_STATEFUL) {
data_size = strlen(test_bufs[0]) + 1;
all_decomp_data = rte_malloc(NULL, data_size,
RTE_CACHE_LINE_SIZE);
}
if (big_data)
buf_pool = ts_params->big_mbuf_pool;
else if (buff_type == SGL_BOTH)
@ -859,9 +877,9 @@ test_deflate_comp_decomp(const struct interim_data_params *int_data,
ops[i]->src.offset = 0;
ops[i]->src.length = rte_pktmbuf_pkt_len(uncomp_bufs[i]);
ops[i]->dst.offset = 0;
if (state == RTE_COMP_OP_STATELESS) {
if (compress_state == RTE_COMP_OP_STATELESS)
ops[i]->flush_flag = RTE_COMP_FLUSH_FINAL;
} else {
else {
RTE_LOG(ERR, USER1,
"Stateful operations are not supported "
"in these tests yet\n");
@ -1046,6 +1064,9 @@ test_deflate_comp_decomp(const struct interim_data_params *int_data,
(ops_processed[i] + 1);
if (out_of_space == 1 && oos_zlib_compress)
data_size = OUT_OF_SPACE_BUF;
else if (test_data->decompress_output_block_size != 0)
data_size =
test_data->decompress_output_block_size;
else
data_size =
strlen(test_bufs[priv_data->orig_idx]) + 1;
@ -1066,6 +1087,9 @@ test_deflate_comp_decomp(const struct interim_data_params *int_data,
(ops_processed[i] + 1);
if (out_of_space == 1 && oos_zlib_compress)
data_size = OUT_OF_SPACE_BUF;
else if (test_data->decompress_output_block_size != 0)
data_size =
test_data->decompress_output_block_size;
else
data_size =
strlen(test_bufs[priv_data->orig_idx]) + 1;
@ -1093,9 +1117,14 @@ test_deflate_comp_decomp(const struct interim_data_params *int_data,
* number of bytes that were produced in the previous stage
*/
ops[i]->src.length = ops_processed[i]->produced;
ops[i]->dst.offset = 0;
if (state == RTE_COMP_OP_STATELESS) {
if (decompress_state == RTE_COMP_OP_STATELESS) {
ops[i]->flush_flag = RTE_COMP_FLUSH_FINAL;
ops[i]->op_type = RTE_COMP_OP_STATELESS;
} else if (zlib_dir == ZLIB_COMPRESS || zlib_dir == ZLIB_NONE) {
ops[i]->flush_flag = RTE_COMP_FLUSH_SYNC;
ops[i]->op_type = RTE_COMP_OP_STATEFUL;
} else {
RTE_LOG(ERR, USER1,
"Stateful operations are not supported "
@ -1132,33 +1161,12 @@ test_deflate_comp_decomp(const struct interim_data_params *int_data,
ops_processed[i] = ops[i];
}
} else {
/* Create decompress private xform data */
for (i = 0; i < num_xforms; i++) {
ret = rte_compressdev_private_xform_create(0,
(const struct rte_comp_xform *)decompress_xforms[i],
&priv_xforms[i]);
if (ret < 0) {
RTE_LOG(ERR, USER1,
"Decompression private xform "
"could not be created\n");
goto exit;
}
num_priv_xforms++;
}
if (capa->comp_feature_flags & RTE_COMP_FF_SHAREABLE_PRIV_XFORM) {
/* Attach shareable private xform data to ops */
for (i = 0; i < num_bufs; i++) {
priv_data = (struct priv_op_data *)(ops[i] + 1);
uint16_t xform_idx = priv_data->orig_idx %
num_xforms;
ops[i]->private_xform = priv_xforms[xform_idx];
}
} else {
/* Create rest of the private xforms for the other ops */
for (i = num_xforms; i < num_bufs; i++) {
if (decompress_state == RTE_COMP_OP_STATELESS) {
/* Create decompress private xform data */
for (i = 0; i < num_xforms; i++) {
ret = rte_compressdev_private_xform_create(0,
decompress_xforms[i % num_xforms],
(const struct rte_comp_xform *)
decompress_xforms[i],
&priv_xforms[i]);
if (ret < 0) {
RTE_LOG(ERR, USER1,
@ -1169,14 +1177,60 @@ test_deflate_comp_decomp(const struct interim_data_params *int_data,
num_priv_xforms++;
}
/* Attach non shareable private xform data to ops */
for (i = 0; i < num_bufs; i++) {
priv_data = (struct priv_op_data *)(ops[i] + 1);
uint16_t xform_idx = priv_data->orig_idx;
ops[i]->private_xform = priv_xforms[xform_idx];
if (capa->comp_feature_flags &
RTE_COMP_FF_SHAREABLE_PRIV_XFORM) {
/* Attach shareable private xform data to ops */
for (i = 0; i < num_bufs; i++) {
priv_data = (struct priv_op_data *)
(ops[i] + 1);
uint16_t xform_idx =
priv_data->orig_idx % num_xforms;
ops[i]->private_xform =
priv_xforms[xform_idx];
}
} else {
/* Create rest of the private xforms */
/* for the other ops */
for (i = num_xforms; i < num_bufs; i++) {
ret =
rte_compressdev_private_xform_create(0,
decompress_xforms[i % num_xforms],
&priv_xforms[i]);
if (ret < 0) {
RTE_LOG(ERR, USER1,
"Decompression private xform could not be created\n");
goto exit;
}
num_priv_xforms++;
}
/* Attach non shareable private xform data */
/* to ops */
for (i = 0; i < num_bufs; i++) {
priv_data = (struct priv_op_data *)
(ops[i] + 1);
uint16_t xform_idx =
priv_data->orig_idx;
ops[i]->private_xform =
priv_xforms[xform_idx];
}
}
} else {
/* Create a stream object for stateful decompression */
ret = rte_compressdev_stream_create(0,
decompress_xforms[0], &stream);
if (ret < 0) {
RTE_LOG(ERR, USER1,
"Decompression stream could not be created, error %d\n",
ret);
goto exit;
}
/* Attach stream to ops */
for (i = 0; i < num_bufs; i++)
ops[i]->stream = stream;
}
next_step:
/* Enqueue and dequeue all operations */
num_enqd = rte_compressdev_enqueue_burst(0, 0, ops, num_bufs);
if (num_enqd < num_bufs) {
@ -1242,7 +1296,75 @@ test_deflate_comp_decomp(const struct interim_data_params *int_data,
continue;
}
if (ops_processed[i]->status != RTE_COMP_OP_STATUS_SUCCESS) {
if (decompress_state == RTE_COMP_OP_STATEFUL
&& (ops_processed[i]->status ==
RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE
|| ops_processed[i]->status ==
RTE_COMP_OP_STATUS_SUCCESS)) {
/* collect the output into all_decomp_data */
const void *ptr = rte_pktmbuf_read(
ops_processed[i]->m_dst,
ops_processed[i]->dst.offset,
ops_processed[i]->produced,
all_decomp_data +
decomp_produced_data_size);
if (ptr != all_decomp_data + decomp_produced_data_size)
rte_memcpy(all_decomp_data +
decomp_produced_data_size,
ptr, ops_processed[i]->produced);
decomp_produced_data_size += ops_processed[i]->produced;
if (ops_processed[i]->src.length >
ops_processed[i]->consumed) {
if (ops_processed[i]->status ==
RTE_COMP_OP_STATUS_SUCCESS) {
ret_status = -1;
RTE_LOG(ERR, USER1,
"Operation finished too early\n");
goto exit;
}
step++;
if (step >= test_data->decompress_steps_max) {
ret_status = -1;
RTE_LOG(ERR, USER1,
"Operation exceeded maximum steps\n");
goto exit;
}
ops[i] = ops_processed[i];
ops[i]->status =
RTE_COMP_OP_STATUS_NOT_PROCESSED;
ops[i]->src.offset +=
ops_processed[i]->consumed;
ops[i]->src.length -=
ops_processed[i]->consumed;
goto next_step;
} else {
/* Compare the original stream with the */
/* decompressed stream (in size and the data) */
priv_data = (struct priv_op_data *)
(ops_processed[i] + 1);
const char *buf1 =
test_bufs[priv_data->orig_idx];
const char *buf2 = all_decomp_data;
if (compare_buffers(buf1, strlen(buf1) + 1,
buf2, decomp_produced_data_size) < 0)
goto exit;
/* Test checksums */
if (compress_xforms[0]->compress.chksum
!= RTE_COMP_CHECKSUM_NONE) {
if (ops_processed[i]->output_chksum
!= compress_checksum[i]) {
RTE_LOG(ERR, USER1,
"The checksums differ\n"
"Compression Checksum: %" PRIu64 "\tDecompression "
"Checksum: %" PRIu64 "\n", compress_checksum[i],
ops_processed[i]->output_chksum);
goto exit;
}
}
}
} else if (ops_processed[i]->status !=
RTE_COMP_OP_STATUS_SUCCESS) {
RTE_LOG(ERR, USER1,
"Some operations were not successful\n");
goto exit;
@ -1252,7 +1374,8 @@ test_deflate_comp_decomp(const struct interim_data_params *int_data,
comp_bufs[priv_data->orig_idx] = NULL;
}
if (out_of_space && oos_zlib_compress) {
if ((out_of_space && oos_zlib_compress)
|| (decompress_state == RTE_COMP_OP_STATEFUL)) {
ret_status = TEST_SUCCESS;
goto exit;
}
@ -1305,10 +1428,13 @@ exit:
rte_comp_op_free(ops[i]);
rte_comp_op_free(ops_processed[i]);
}
for (i = 0; i < num_priv_xforms; i++) {
for (i = 0; i < num_priv_xforms; i++)
if (priv_xforms[i] != NULL)
rte_compressdev_private_xform_free(0, priv_xforms[i]);
}
if (stream != NULL)
rte_compressdev_stream_free(0, stream);
if (all_decomp_data != NULL)
rte_free(all_decomp_data);
rte_free(contig_buf);
return ret_status;
@ -1352,10 +1478,13 @@ test_compressdev_deflate_stateless_fixed(void)
};
struct test_data_params test_data = {
RTE_COMP_OP_STATELESS,
RTE_COMP_OP_STATELESS,
LB_BOTH,
ZLIB_DECOMPRESS,
0,
0,
0,
0
};
@ -1421,10 +1550,13 @@ test_compressdev_deflate_stateless_dynamic(void)
};
struct test_data_params test_data = {
RTE_COMP_OP_STATELESS,
RTE_COMP_OP_STATELESS,
LB_BOTH,
ZLIB_DECOMPRESS,
0,
0,
0,
0
};
@ -1474,10 +1606,13 @@ test_compressdev_deflate_stateless_multi_op(void)
};
struct test_data_params test_data = {
RTE_COMP_OP_STATELESS,
RTE_COMP_OP_STATELESS,
LB_BOTH,
ZLIB_DECOMPRESS,
0,
0,
0,
0
};
@ -1526,10 +1661,13 @@ test_compressdev_deflate_stateless_multi_level(void)
};
struct test_data_params test_data = {
RTE_COMP_OP_STATELESS,
RTE_COMP_OP_STATELESS,
LB_BOTH,
ZLIB_DECOMPRESS,
0,
0,
0,
0
};
@ -1614,10 +1752,13 @@ test_compressdev_deflate_stateless_multi_xform(void)
};
struct test_data_params test_data = {
RTE_COMP_OP_STATELESS,
RTE_COMP_OP_STATELESS,
LB_BOTH,
ZLIB_DECOMPRESS,
0,
0,
0,
0
};
@ -1661,10 +1802,13 @@ test_compressdev_deflate_stateless_sgl(void)
};
struct test_data_params test_data = {
RTE_COMP_OP_STATELESS,
RTE_COMP_OP_STATELESS,
SGL_BOTH,
ZLIB_DECOMPRESS,
0,
0,
0,
0
};
@ -1770,10 +1914,13 @@ test_compressdev_deflate_stateless_checksum(void)
};
struct test_data_params test_data = {
RTE_COMP_OP_STATELESS,
RTE_COMP_OP_STATELESS,
LB_BOTH,
ZLIB_DECOMPRESS,
0,
0,
0,
0
};
@ -1868,7 +2015,7 @@ test_compressdev_out_of_space_buffer(void)
uint16_t i;
const struct rte_compressdev_capabilities *capab;
RTE_LOG(ERR, USER1, "This is a negative test errors are expected\n");
RTE_LOG(INFO, USER1, "This is a negative test, errors are expected\n");
capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);
TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities");
@ -1876,16 +2023,6 @@ test_compressdev_out_of_space_buffer(void)
if ((capab->comp_feature_flags & RTE_COMP_FF_HUFFMAN_FIXED) == 0)
return -ENOTSUP;
struct rte_comp_xform *compress_xform =
rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);
if (compress_xform == NULL) {
RTE_LOG(ERR, USER1,
"Compress xform could not be created\n");
ret = TEST_FAILED;
goto exit;
}
struct interim_data_params int_data = {
&compress_test_bufs[0],
1,
@ -1896,10 +2033,13 @@ test_compressdev_out_of_space_buffer(void)
};
struct test_data_params test_data = {
RTE_COMP_OP_STATELESS,
RTE_COMP_OP_STATELESS,
LB_BOTH,
ZLIB_DECOMPRESS,
1, /* run out-of-space test */
0,
0,
0
};
/* Compress with compressdev, decompress with Zlib */
@ -1933,7 +2073,6 @@ test_compressdev_out_of_space_buffer(void)
ret = TEST_SUCCESS;
exit:
rte_free(compress_xform);
return ret;
}
@ -1973,11 +2112,14 @@ test_compressdev_deflate_stateless_dynamic_big(void)
};
struct test_data_params test_data = {
RTE_COMP_OP_STATELESS,
RTE_COMP_OP_STATELESS,
SGL_BOTH,
ZLIB_DECOMPRESS,
0,
1
1,
0,
0
};
ts_params->def_comp_xform->compress.deflate.huffman =
@ -2010,6 +2152,199 @@ exit:
return ret;
}
static int
test_compressdev_deflate_stateful_decomp(void)
{
struct comp_testsuite_params *ts_params = &testsuite_params;
int ret;
uint16_t i;
const struct rte_compressdev_capabilities *capab;
capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);
TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities");
if (!(capab->comp_feature_flags & RTE_COMP_FF_STATEFUL_DECOMPRESSION))
return -ENOTSUP;
struct interim_data_params int_data = {
&compress_test_bufs[0],
1,
&i,
&ts_params->def_comp_xform,
&ts_params->def_decomp_xform,
1
};
struct test_data_params test_data = {
RTE_COMP_OP_STATELESS,
RTE_COMP_OP_STATEFUL,
LB_BOTH,
ZLIB_COMPRESS,
0,
0,
2000,
4
};
/* Compress with Zlib, decompress with compressdev */
if (test_deflate_comp_decomp(&int_data, &test_data) < 0) {
ret = TEST_FAILED;
goto exit;
}
if (capab->comp_feature_flags & RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) {
/* Now test with SGL buffers */
test_data.buff_type = SGL_BOTH;
if (test_deflate_comp_decomp(&int_data, &test_data) < 0) {
ret = TEST_FAILED;
goto exit;
}
}
ret = TEST_SUCCESS;
exit:
return ret;
}
static int
test_compressdev_deflate_stateful_decomp_checksum(void)
{
struct comp_testsuite_params *ts_params = &testsuite_params;
int ret;
uint16_t i;
const struct rte_compressdev_capabilities *capab;
capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);
TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities");
if (!(capab->comp_feature_flags & RTE_COMP_FF_STATEFUL_DECOMPRESSION))
return -ENOTSUP;
/* Check if driver supports any checksum */
if (!(capab->comp_feature_flags &
(RTE_COMP_FF_CRC32_CHECKSUM | RTE_COMP_FF_ADLER32_CHECKSUM |
RTE_COMP_FF_CRC32_ADLER32_CHECKSUM)))
return -ENOTSUP;
struct rte_comp_xform *compress_xform =
rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);
if (compress_xform == NULL) {
RTE_LOG(ERR, USER1, "Compress xform could not be created\n");
return TEST_FAILED;
}
memcpy(compress_xform, ts_params->def_comp_xform,
sizeof(struct rte_comp_xform));
struct rte_comp_xform *decompress_xform =
rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);
if (decompress_xform == NULL) {
RTE_LOG(ERR, USER1, "Decompress xform could not be created\n");
rte_free(compress_xform);
return TEST_FAILED;
}
memcpy(decompress_xform, ts_params->def_decomp_xform,
sizeof(struct rte_comp_xform));
struct interim_data_params int_data = {
&compress_test_bufs[0],
1,
&i,
&compress_xform,
&decompress_xform,
1
};
struct test_data_params test_data = {
RTE_COMP_OP_STATELESS,
RTE_COMP_OP_STATEFUL,
LB_BOTH,
ZLIB_COMPRESS,
0,
0,
2000,
4
};
/* Check if driver supports crc32 checksum and test */
if (capab->comp_feature_flags & RTE_COMP_FF_CRC32_CHECKSUM) {
compress_xform->compress.chksum = RTE_COMP_CHECKSUM_CRC32;
decompress_xform->decompress.chksum = RTE_COMP_CHECKSUM_CRC32;
/* Compress with Zlib, decompress with compressdev */
test_data.buff_type = LB_BOTH;
if (test_deflate_comp_decomp(&int_data, &test_data) < 0) {
ret = TEST_FAILED;
goto exit;
}
if (capab->comp_feature_flags &
RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) {
/* Now test with SGL buffers */
test_data.buff_type = SGL_BOTH;
if (test_deflate_comp_decomp(&int_data,
&test_data) < 0) {
ret = TEST_FAILED;
goto exit;
}
}
}
/* Check if driver supports adler32 checksum and test */
if (capab->comp_feature_flags & RTE_COMP_FF_ADLER32_CHECKSUM) {
compress_xform->compress.chksum = RTE_COMP_CHECKSUM_ADLER32;
decompress_xform->decompress.chksum = RTE_COMP_CHECKSUM_ADLER32;
/* Compress with Zlib, decompress with compressdev */
test_data.buff_type = LB_BOTH;
if (test_deflate_comp_decomp(&int_data, &test_data) < 0) {
ret = TEST_FAILED;
goto exit;
}
if (capab->comp_feature_flags &
RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) {
/* Now test with SGL buffers */
test_data.buff_type = SGL_BOTH;
if (test_deflate_comp_decomp(&int_data,
&test_data) < 0) {
ret = TEST_FAILED;
goto exit;
}
}
}
/* Check if driver supports combined crc and adler checksum and test */
if (capab->comp_feature_flags & RTE_COMP_FF_CRC32_ADLER32_CHECKSUM) {
compress_xform->compress.chksum =
RTE_COMP_CHECKSUM_CRC32_ADLER32;
decompress_xform->decompress.chksum =
RTE_COMP_CHECKSUM_CRC32_ADLER32;
/* Zlib doesn't support combined checksum */
test_data.zlib_dir = ZLIB_NONE;
/* Compress stateless, decompress stateful with compressdev */
test_data.buff_type = LB_BOTH;
if (test_deflate_comp_decomp(&int_data, &test_data) < 0) {
ret = TEST_FAILED;
goto exit;
}
if (capab->comp_feature_flags &
RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) {
/* Now test with SGL buffers */
test_data.buff_type = SGL_BOTH;
if (test_deflate_comp_decomp(&int_data,
&test_data) < 0) {
ret = TEST_FAILED;
goto exit;
}
}
}
ret = TEST_SUCCESS;
exit:
rte_free(compress_xform);
rte_free(decompress_xform);
return ret;
}
static struct unit_test_suite compressdev_testsuite = {
.suite_name = "compressdev unit test suite",
@ -2036,6 +2371,10 @@ static struct unit_test_suite compressdev_testsuite = {
test_compressdev_deflate_stateless_checksum),
TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
test_compressdev_out_of_space_buffer),
TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
test_compressdev_deflate_stateful_decomp),
TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
test_compressdev_deflate_stateful_decomp_checksum),
TEST_CASES_END() /**< NULL terminate unit test array */
}
};