test/compress: add multi xform test
authorPablo de Lara <pablo.de.lara.guarch@intel.com>
Fri, 4 May 2018 10:22:17 +0000 (11:22 +0100)
committerPablo de Lara <pablo.de.lara.guarch@intel.com>
Thu, 10 May 2018 16:46:20 +0000 (17:46 +0100)
Add test that checks if multiple xforms can be
handled on a single enqueue call.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
Acked-by: Lee Daly <lee.daly@intel.com>
test/test/test_compressdev.c

index 1aa7d8a..6569450 100644 (file)
@@ -27,7 +27,7 @@
 #define COMPRESS_BUF_SIZE_RATIO 1.3
 #define NUM_MBUFS 16
 #define NUM_OPS 16
 #define COMPRESS_BUF_SIZE_RATIO 1.3
 #define NUM_MBUFS 16
 #define NUM_OPS 16
-#define NUM_MAX_XFORMS 1
+#define NUM_MAX_XFORMS 16
 #define NUM_MAX_INFLIGHT_OPS 128
 #define CACHE_SIZE 0
 
 #define NUM_MAX_INFLIGHT_OPS 128
 #define CACHE_SIZE 0
 
@@ -52,8 +52,8 @@ struct priv_op_data {
 struct comp_testsuite_params {
        struct rte_mempool *mbuf_pool;
        struct rte_mempool *op_pool;
 struct comp_testsuite_params {
        struct rte_mempool *mbuf_pool;
        struct rte_mempool *op_pool;
-       struct rte_comp_xform def_comp_xform;
-       struct rte_comp_xform def_decomp_xform;
+       struct rte_comp_xform *def_comp_xform;
+       struct rte_comp_xform *def_decomp_xform;
 };
 
 static struct comp_testsuite_params testsuite_params = { 0 };
 };
 
 static struct comp_testsuite_params testsuite_params = { 0 };
@@ -65,6 +65,8 @@ testsuite_teardown(void)
 
        rte_mempool_free(ts_params->mbuf_pool);
        rte_mempool_free(ts_params->op_pool);
 
        rte_mempool_free(ts_params->mbuf_pool);
        rte_mempool_free(ts_params->op_pool);
+       rte_free(ts_params->def_comp_xform);
+       rte_free(ts_params->def_decomp_xform);
 }
 
 static int
 }
 
 static int
@@ -108,19 +110,34 @@ testsuite_setup(void)
                goto exit;
        }
 
                goto exit;
        }
 
+       ts_params->def_comp_xform =
+                       rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);
+       if (ts_params->def_comp_xform == NULL) {
+               RTE_LOG(ERR, USER1,
+                       "Default compress xform could not be created\n");
+               goto exit;
+       }
+       ts_params->def_decomp_xform =
+                       rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);
+       if (ts_params->def_decomp_xform == NULL) {
+               RTE_LOG(ERR, USER1,
+                       "Default decompress xform could not be created\n");
+               goto exit;
+       }
+
        /* Initializes default values for compress/decompress xforms */
        /* Initializes default values for compress/decompress xforms */
-       ts_params->def_comp_xform.type = RTE_COMP_COMPRESS;
-       ts_params->def_comp_xform.compress.algo = RTE_COMP_ALGO_DEFLATE,
-       ts_params->def_comp_xform.compress.deflate.huffman =
+       ts_params->def_comp_xform->type = RTE_COMP_COMPRESS;
+       ts_params->def_comp_xform->compress.algo = RTE_COMP_ALGO_DEFLATE,
+       ts_params->def_comp_xform->compress.deflate.huffman =
                                                RTE_COMP_HUFFMAN_DEFAULT;
                                                RTE_COMP_HUFFMAN_DEFAULT;
-       ts_params->def_comp_xform.compress.level = RTE_COMP_LEVEL_PMD_DEFAULT;
-       ts_params->def_comp_xform.compress.chksum = RTE_COMP_CHECKSUM_NONE;
-       ts_params->def_comp_xform.compress.window_size = DEFAULT_WINDOW_SIZE;
+       ts_params->def_comp_xform->compress.level = RTE_COMP_LEVEL_PMD_DEFAULT;
+       ts_params->def_comp_xform->compress.chksum = RTE_COMP_CHECKSUM_NONE;
+       ts_params->def_comp_xform->compress.window_size = DEFAULT_WINDOW_SIZE;
 
 
-       ts_params->def_decomp_xform.type = RTE_COMP_DECOMPRESS;
-       ts_params->def_decomp_xform.decompress.algo = RTE_COMP_ALGO_DEFLATE,
-       ts_params->def_decomp_xform.decompress.chksum = RTE_COMP_CHECKSUM_NONE;
-       ts_params->def_decomp_xform.decompress.window_size = DEFAULT_WINDOW_SIZE;
+       ts_params->def_decomp_xform->type = RTE_COMP_DECOMPRESS;
+       ts_params->def_decomp_xform->decompress.algo = RTE_COMP_ALGO_DEFLATE,
+       ts_params->def_decomp_xform->decompress.chksum = RTE_COMP_CHECKSUM_NONE;
+       ts_params->def_decomp_xform->decompress.window_size = DEFAULT_WINDOW_SIZE;
 
        return TEST_SUCCESS;
 
 
        return TEST_SUCCESS;
 
@@ -343,8 +360,9 @@ static int
 test_deflate_comp_decomp(const char * const test_bufs[],
                unsigned int num_bufs,
                uint16_t buf_idx[],
 test_deflate_comp_decomp(const char * const test_bufs[],
                unsigned int num_bufs,
                uint16_t buf_idx[],
-               struct rte_comp_xform *compress_xform,
-               struct rte_comp_xform *decompress_xform,
+               struct rte_comp_xform *compress_xforms[],
+               struct rte_comp_xform *decompress_xforms[],
+               unsigned int num_xforms,
                enum rte_comp_op_type state,
                enum zlib_direction zlib_dir)
 {
                enum rte_comp_op_type state,
                enum zlib_direction zlib_dir)
 {
@@ -438,8 +456,9 @@ test_deflate_comp_decomp(const char * const test_bufs[],
        /* Compress data (either with Zlib API or compressdev API */
        if (zlib_dir == ZLIB_COMPRESS || zlib_dir == ZLIB_ALL) {
                for (i = 0; i < num_bufs; i++) {
        /* Compress data (either with Zlib API or compressdev API */
        if (zlib_dir == ZLIB_COMPRESS || zlib_dir == ZLIB_ALL) {
                for (i = 0; i < num_bufs; i++) {
-                       ret = compress_zlib(ops[i],
-                               (const struct rte_comp_xform *)compress_xform,
+                       const struct rte_comp_xform *compress_xform =
+                               compress_xforms[i % num_xforms];
+                       ret = compress_zlib(ops[i], compress_xform,
                                        DEFAULT_MEM_LEVEL);
                        if (ret < 0)
                                goto exit;
                                        DEFAULT_MEM_LEVEL);
                        if (ret < 0)
                                goto exit;
@@ -447,11 +466,11 @@ test_deflate_comp_decomp(const char * const test_bufs[],
                        ops_processed[i] = ops[i];
                }
        } else {
                        ops_processed[i] = ops[i];
                }
        } else {
-               if (capa->comp_feature_flags & RTE_COMP_FF_SHAREABLE_PRIV_XFORM) {
-                       /* Create single compress private xform data */
+               /* Create compress private xform data */
+               for (i = 0; i < num_xforms; i++) {
                        ret = rte_compressdev_private_xform_create(0,
                        ret = rte_compressdev_private_xform_create(0,
-                               (const struct rte_comp_xform *)compress_xform,
-                               &priv_xforms[0]);
+                               (const struct rte_comp_xform *)compress_xforms[i],
+                               &priv_xforms[i]);
                        if (ret < 0) {
                                RTE_LOG(ERR, USER1,
                                        "Compression private xform "
                        if (ret < 0) {
                                RTE_LOG(ERR, USER1,
                                        "Compression private xform "
@@ -459,14 +478,18 @@ test_deflate_comp_decomp(const char * const test_bufs[],
                                goto exit;
                        }
                        num_priv_xforms++;
                                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++)
                        /* Attach shareable private xform data to ops */
                        for (i = 0; i < num_bufs; i++)
-                               ops[i]->private_xform = priv_xforms[0];
+                               ops[i]->private_xform = priv_xforms[i % num_xforms];
                } else {
                } else {
-                       /* Create compress private xform data per op */
-                       for (i = 0; i < num_bufs; i++) {
+                       /* 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,
                                ret = rte_compressdev_private_xform_create(0,
-                                       compress_xform, &priv_xforms[i]);
+                                       compress_xforms[i % num_xforms],
+                                       &priv_xforms[i]);
                                if (ret < 0) {
                                        RTE_LOG(ERR, USER1,
                                                "Compression private xform "
                                if (ret < 0) {
                                        RTE_LOG(ERR, USER1,
                                                "Compression private xform "
@@ -524,15 +547,18 @@ test_deflate_comp_decomp(const char * const test_bufs[],
                num_priv_xforms = 0;
        }
 
                num_priv_xforms = 0;
        }
 
-       enum rte_comp_huffman huffman_type =
-               compress_xform->compress.deflate.huffman;
        for (i = 0; i < num_bufs; i++) {
                priv_data = (struct priv_op_data *)(ops_processed[i] + 1);
        for (i = 0; i < num_bufs; i++) {
                priv_data = (struct priv_op_data *)(ops_processed[i] + 1);
+               uint16_t xform_idx = priv_data->orig_idx % num_xforms;
+               const struct rte_comp_compress_xform *compress_xform =
+                               &compress_xforms[xform_idx]->compress;
+               enum rte_comp_huffman huffman_type =
+                       compress_xform->deflate.huffman;
                RTE_LOG(DEBUG, USER1, "Buffer %u compressed from %u to %u bytes "
                RTE_LOG(DEBUG, USER1, "Buffer %u compressed from %u to %u bytes "
-                       "(level = %u, huffman = %s)\n",
+                       "(level = %d, huffman = %s)\n",
                        buf_idx[priv_data->orig_idx],
                        ops_processed[i]->consumed, ops_processed[i]->produced,
                        buf_idx[priv_data->orig_idx],
                        ops_processed[i]->consumed, ops_processed[i]->produced,
-                       compress_xform->compress.level,
+                       compress_xform->level,
                        huffman_type_strings[huffman_type]);
                RTE_LOG(DEBUG, USER1, "Compression ratio = %.2f",
                        (float)ops_processed[i]->produced /
                        huffman_type_strings[huffman_type]);
                RTE_LOG(DEBUG, USER1, "Compression ratio = %.2f",
                        (float)ops_processed[i]->produced /
@@ -619,19 +645,23 @@ test_deflate_comp_decomp(const char * const test_bufs[],
        /* Decompress data (either with Zlib API or compressdev API */
        if (zlib_dir == ZLIB_DECOMPRESS || zlib_dir == ZLIB_ALL) {
                for (i = 0; i < num_bufs; i++) {
        /* Decompress data (either with Zlib API or compressdev API */
        if (zlib_dir == ZLIB_DECOMPRESS || zlib_dir == ZLIB_ALL) {
                for (i = 0; i < num_bufs; i++) {
-                       ret = decompress_zlib(ops[i],
-                               (const struct rte_comp_xform *)decompress_xform);
+                       priv_data = (struct priv_op_data *)(ops[i] + 1);
+                       uint16_t xform_idx = priv_data->orig_idx % num_xforms;
+                       const struct rte_comp_xform *decompress_xform =
+                               decompress_xforms[xform_idx];
+
+                       ret = decompress_zlib(ops[i], decompress_xform);
                        if (ret < 0)
                                goto exit;
 
                        ops_processed[i] = ops[i];
                }
        } else {
                        if (ret < 0)
                                goto exit;
 
                        ops_processed[i] = ops[i];
                }
        } else {
-               if (capa->comp_feature_flags & RTE_COMP_FF_SHAREABLE_PRIV_XFORM) {
-                       /* Create single decompress private xform data */
+               /* Create decompress private xform data */
+               for (i = 0; i < num_xforms; i++) {
                        ret = rte_compressdev_private_xform_create(0,
                        ret = rte_compressdev_private_xform_create(0,
-                               (const struct rte_comp_xform *)decompress_xform,
-                               &priv_xforms[0]);
+                               (const struct rte_comp_xform *)decompress_xforms[i],
+                               &priv_xforms[i]);
                        if (ret < 0) {
                                RTE_LOG(ERR, USER1,
                                        "Decompression private xform "
                        if (ret < 0) {
                                RTE_LOG(ERR, USER1,
                                        "Decompression private xform "
@@ -639,17 +669,25 @@ test_deflate_comp_decomp(const char * const test_bufs[],
                                goto exit;
                        }
                        num_priv_xforms++;
                                goto exit;
                        }
                        num_priv_xforms++;
+               }
+
+               if (capa->comp_feature_flags & RTE_COMP_FF_SHAREABLE_PRIV_XFORM) {
                        /* Attach shareable private xform data to ops */
                        /* Attach shareable private xform data to ops */
-                       for (i = 0; i < num_bufs; i++)
-                               ops[i]->private_xform = priv_xforms[0];
-               } else {
-                       /* Create decompress private xform data per op */
                        for (i = 0; i < num_bufs; i++) {
                        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,
                                ret = rte_compressdev_private_xform_create(0,
-                                       decompress_xform, &priv_xforms[i]);
+                                       decompress_xforms[i % num_xforms],
+                                       &priv_xforms[i]);
                                if (ret < 0) {
                                        RTE_LOG(ERR, USER1,
                                if (ret < 0) {
                                        RTE_LOG(ERR, USER1,
-                                               "Deompression private xform "
+                                               "Decompression private xform "
                                                "could not be created\n");
                                        goto exit;
                                }
                                                "could not be created\n");
                                        goto exit;
                                }
@@ -657,8 +695,11 @@ test_deflate_comp_decomp(const char * const test_bufs[],
                        }
 
                        /* Attach non shareable private xform data to ops */
                        }
 
                        /* Attach non shareable private xform data to ops */
-                       for (i = 0; i < num_bufs; i++)
-                               ops[i]->private_xform = priv_xforms[i];
+                       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];
+                       }
                }
 
                /* Enqueue and dequeue all operations */
                }
 
                /* Enqueue and dequeue all operations */
@@ -759,11 +800,20 @@ test_compressdev_deflate_stateless_fixed(void)
        struct comp_testsuite_params *ts_params = &testsuite_params;
        const char *test_buffer;
        uint16_t i;
        struct comp_testsuite_params *ts_params = &testsuite_params;
        const char *test_buffer;
        uint16_t i;
-       struct rte_comp_xform compress_xform;
+       int ret;
+       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;
+       }
 
 
-       memcpy(&compress_xform, &ts_params->def_comp_xform,
+       memcpy(compress_xform, ts_params->def_comp_xform,
                        sizeof(struct rte_comp_xform));
                        sizeof(struct rte_comp_xform));
-       compress_xform.compress.deflate.huffman = RTE_COMP_HUFFMAN_FIXED;
+       compress_xform->compress.deflate.huffman = RTE_COMP_HUFFMAN_FIXED;
 
        for (i = 0; i < RTE_DIM(compress_test_bufs); i++) {
                test_buffer = compress_test_bufs[i];
 
        for (i = 0; i < RTE_DIM(compress_test_bufs); i++) {
                test_buffer = compress_test_bufs[i];
@@ -773,21 +823,31 @@ test_compressdev_deflate_stateless_fixed(void)
                                &i,
                                &compress_xform,
                                &ts_params->def_decomp_xform,
                                &i,
                                &compress_xform,
                                &ts_params->def_decomp_xform,
+                               1,
                                RTE_COMP_OP_STATELESS,
                                RTE_COMP_OP_STATELESS,
-                               ZLIB_DECOMPRESS) < 0)
-                       return TEST_FAILED;
+                               ZLIB_DECOMPRESS) < 0) {
+                       ret = TEST_FAILED;
+                       goto exit;
+               }
 
                /* Compress with Zlib, decompress with compressdev */
                if (test_deflate_comp_decomp(&test_buffer, 1,
                                &i,
                                &compress_xform,
                                &ts_params->def_decomp_xform,
 
                /* Compress with Zlib, decompress with compressdev */
                if (test_deflate_comp_decomp(&test_buffer, 1,
                                &i,
                                &compress_xform,
                                &ts_params->def_decomp_xform,
+                               1,
                                RTE_COMP_OP_STATELESS,
                                RTE_COMP_OP_STATELESS,
-                               ZLIB_COMPRESS) < 0)
-                       return TEST_FAILED;
+                               ZLIB_COMPRESS) < 0) {
+                       ret = TEST_FAILED;
+                       goto exit;
+               }
        }
 
        }
 
-       return TEST_SUCCESS;
+       ret = TEST_SUCCESS;
+
+exit:
+       rte_free(compress_xform);
+       return ret;
 }
 
 static int
 }
 
 static int
@@ -796,11 +856,20 @@ test_compressdev_deflate_stateless_dynamic(void)
        struct comp_testsuite_params *ts_params = &testsuite_params;
        const char *test_buffer;
        uint16_t i;
        struct comp_testsuite_params *ts_params = &testsuite_params;
        const char *test_buffer;
        uint16_t i;
-       struct rte_comp_xform compress_xform;
+       int ret;
+       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;
+       }
 
 
-       memcpy(&compress_xform, &ts_params->def_comp_xform,
+       memcpy(compress_xform, ts_params->def_comp_xform,
                        sizeof(struct rte_comp_xform));
                        sizeof(struct rte_comp_xform));
-       compress_xform.compress.deflate.huffman = RTE_COMP_HUFFMAN_DYNAMIC;
+       compress_xform->compress.deflate.huffman = RTE_COMP_HUFFMAN_DYNAMIC;
 
        for (i = 0; i < RTE_DIM(compress_test_bufs); i++) {
                test_buffer = compress_test_bufs[i];
 
        for (i = 0; i < RTE_DIM(compress_test_bufs); i++) {
                test_buffer = compress_test_bufs[i];
@@ -810,21 +879,31 @@ test_compressdev_deflate_stateless_dynamic(void)
                                &i,
                                &compress_xform,
                                &ts_params->def_decomp_xform,
                                &i,
                                &compress_xform,
                                &ts_params->def_decomp_xform,
+                               1,
                                RTE_COMP_OP_STATELESS,
                                RTE_COMP_OP_STATELESS,
-                               ZLIB_DECOMPRESS) < 0)
-                       return TEST_FAILED;
+                               ZLIB_DECOMPRESS) < 0) {
+                       ret = TEST_FAILED;
+                       goto exit;
+               }
 
                /* Compress with Zlib, decompress with compressdev */
                if (test_deflate_comp_decomp(&test_buffer, 1,
                                &i,
                                &compress_xform,
                                &ts_params->def_decomp_xform,
 
                /* Compress with Zlib, decompress with compressdev */
                if (test_deflate_comp_decomp(&test_buffer, 1,
                                &i,
                                &compress_xform,
                                &ts_params->def_decomp_xform,
+                               1,
                                RTE_COMP_OP_STATELESS,
                                RTE_COMP_OP_STATELESS,
-                               ZLIB_COMPRESS) < 0)
-                       return TEST_FAILED;
+                               ZLIB_COMPRESS) < 0) {
+                       ret = TEST_FAILED;
+                       goto exit;
+               }
        }
 
        }
 
-       return TEST_SUCCESS;
+       ret = TEST_SUCCESS;
+
+exit:
+       rte_free(compress_xform);
+       return ret;
 }
 
 static int
 }
 
 static int
@@ -843,6 +922,7 @@ test_compressdev_deflate_stateless_multi_op(void)
                        buf_idx,
                        &ts_params->def_comp_xform,
                        &ts_params->def_decomp_xform,
                        buf_idx,
                        &ts_params->def_comp_xform,
                        &ts_params->def_decomp_xform,
+                       1,
                        RTE_COMP_OP_STATELESS,
                        ZLIB_DECOMPRESS) < 0)
                return TEST_FAILED;
                        RTE_COMP_OP_STATELESS,
                        ZLIB_DECOMPRESS) < 0)
                return TEST_FAILED;
@@ -852,6 +932,7 @@ test_compressdev_deflate_stateless_multi_op(void)
                        buf_idx,
                        &ts_params->def_comp_xform,
                        &ts_params->def_decomp_xform,
                        buf_idx,
                        &ts_params->def_comp_xform,
                        &ts_params->def_decomp_xform,
+                       1,
                        RTE_COMP_OP_STATELESS,
                        ZLIB_COMPRESS) < 0)
                return TEST_FAILED;
                        RTE_COMP_OP_STATELESS,
                        ZLIB_COMPRESS) < 0)
                return TEST_FAILED;
@@ -859,7 +940,6 @@ test_compressdev_deflate_stateless_multi_op(void)
        return TEST_SUCCESS;
 }
 
        return TEST_SUCCESS;
 }
 
-
 static int
 test_compressdev_deflate_stateless_multi_level(void)
 {
 static int
 test_compressdev_deflate_stateless_multi_level(void)
 {
@@ -867,29 +947,117 @@ test_compressdev_deflate_stateless_multi_level(void)
        const char *test_buffer;
        unsigned int level;
        uint16_t i;
        const char *test_buffer;
        unsigned int level;
        uint16_t i;
-       struct rte_comp_xform compress_xform;
+       int ret;
+       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;
+       }
 
 
-       memcpy(&compress_xform, &ts_params->def_comp_xform,
+       memcpy(compress_xform, ts_params->def_comp_xform,
                        sizeof(struct rte_comp_xform));
 
        for (i = 0; i < RTE_DIM(compress_test_bufs); i++) {
                test_buffer = compress_test_bufs[i];
                for (level = RTE_COMP_LEVEL_MIN; level <= RTE_COMP_LEVEL_MAX;
                                level++) {
                        sizeof(struct rte_comp_xform));
 
        for (i = 0; i < RTE_DIM(compress_test_bufs); i++) {
                test_buffer = compress_test_bufs[i];
                for (level = RTE_COMP_LEVEL_MIN; level <= RTE_COMP_LEVEL_MAX;
                                level++) {
-                       compress_xform.compress.level = level;
+                       compress_xform->compress.level = level;
                        /* Compress with compressdev, decompress with Zlib */
                        if (test_deflate_comp_decomp(&test_buffer, 1,
                                        &i,
                                        &compress_xform,
                                        &ts_params->def_decomp_xform,
                        /* Compress with compressdev, decompress with Zlib */
                        if (test_deflate_comp_decomp(&test_buffer, 1,
                                        &i,
                                        &compress_xform,
                                        &ts_params->def_decomp_xform,
+                                       1,
                                        RTE_COMP_OP_STATELESS,
                                        RTE_COMP_OP_STATELESS,
-                                       ZLIB_DECOMPRESS) < 0)
-                               return TEST_FAILED;
+                                       ZLIB_DECOMPRESS) < 0) {
+                               ret = TEST_FAILED;
+                               goto exit;
+                       }
                }
        }
 
                }
        }
 
-       return TEST_SUCCESS;
+       ret = TEST_SUCCESS;
+
+exit:
+       rte_free(compress_xform);
+       return ret;
+}
+
+#define NUM_XFORMS 3
+static int
+test_compressdev_deflate_stateless_multi_xform(void)
+{
+       struct comp_testsuite_params *ts_params = &testsuite_params;
+       uint16_t num_bufs = NUM_XFORMS;
+       struct rte_comp_xform *compress_xforms[NUM_XFORMS] = {NULL};
+       struct rte_comp_xform *decompress_xforms[NUM_XFORMS] = {NULL};
+       const char *test_buffers[NUM_XFORMS];
+       uint16_t i;
+       unsigned int level = RTE_COMP_LEVEL_MIN;
+       uint16_t buf_idx[num_bufs];
+
+       int ret;
+
+       /* Create multiple xforms with various levels */
+       for (i = 0; i < NUM_XFORMS; i++) {
+               compress_xforms[i] = rte_malloc(NULL,
+                               sizeof(struct rte_comp_xform), 0);
+               if (compress_xforms[i] == NULL) {
+                       RTE_LOG(ERR, USER1,
+                               "Compress xform could not be created\n");
+                       ret = TEST_FAILED;
+                       goto exit;
+               }
+
+               memcpy(compress_xforms[i], ts_params->def_comp_xform,
+                               sizeof(struct rte_comp_xform));
+               compress_xforms[i]->compress.level = level;
+               level++;
+
+               decompress_xforms[i] = rte_malloc(NULL,
+                               sizeof(struct rte_comp_xform), 0);
+               if (decompress_xforms[i] == NULL) {
+                       RTE_LOG(ERR, USER1,
+                               "Decompress xform could not be created\n");
+                       ret = TEST_FAILED;
+                       goto exit;
+               }
+
+               memcpy(decompress_xforms[i], ts_params->def_decomp_xform,
+                               sizeof(struct rte_comp_xform));
+       }
+
+       for (i = 0; i < NUM_XFORMS; i++) {
+               buf_idx[i] = 0;
+               /* Use the same buffer in all sessions */
+               test_buffers[i] = compress_test_bufs[0];
+       }
+       /* Compress with compressdev, decompress with Zlib */
+       if (test_deflate_comp_decomp(test_buffers, num_bufs,
+                       buf_idx,
+                       compress_xforms,
+                       decompress_xforms,
+                       NUM_XFORMS,
+                       RTE_COMP_OP_STATELESS,
+                       ZLIB_DECOMPRESS) < 0) {
+               ret = TEST_FAILED;
+               goto exit;
+       }
+
+       ret = TEST_SUCCESS;
+exit:
+       for (i = 0; i < NUM_XFORMS; i++) {
+               rte_free(compress_xforms[i]);
+               rte_free(decompress_xforms[i]);
+       }
+
+       return ret;
 }
 }
+
 static struct unit_test_suite compressdev_testsuite  = {
        .suite_name = "compressdev unit test suite",
        .setup = testsuite_setup,
 static struct unit_test_suite compressdev_testsuite  = {
        .suite_name = "compressdev unit test suite",
        .setup = testsuite_setup,
@@ -903,6 +1071,8 @@ static struct unit_test_suite compressdev_testsuite  = {
                        test_compressdev_deflate_stateless_multi_op),
                TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
                        test_compressdev_deflate_stateless_multi_level),
                        test_compressdev_deflate_stateless_multi_op),
                TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
                        test_compressdev_deflate_stateless_multi_level),
+               TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
+                       test_compressdev_deflate_stateless_multi_xform),
                TEST_CASES_END() /**< NULL terminate unit test array */
        }
 };
                TEST_CASES_END() /**< NULL terminate unit test array */
        }
 };