Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
app/testbbdev: add test application for bbdev
- full test suite for bbdev - test App works seamlessly on all PMDs registered with bbdev framework - a python script is provided to make our life easier - supports execution of tests by parsing Test Vector files - test Vectors can be added/deleted/modified with no need for re-compilation - various tests can be executed: (a) Throughput test (b) Offload latency test (c) Operation latency test (d) Validation test (c) Sanity checks Signed-off-by: Amr Mokhtar <amr.mokhtar@intel.com>
- Loading branch information
1 parent
b8cfe2c
commit f714a18
Showing
16 changed files
with
5,742 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# SPDX-License-Identifier: BSD-3-Clause | ||
# Copyright(c) 2017 Intel Corporation | ||
|
||
include $(RTE_SDK)/mk/rte.vars.mk | ||
|
||
# | ||
# library name | ||
# | ||
APP = testbbdev | ||
|
||
CFLAGS += -O3 | ||
CFLAGS += $(WERROR_FLAGS) | ||
|
||
# | ||
# all sources are stored in SRCS-y | ||
# | ||
SRCS-$(CONFIG_RTE_TEST_BBDEV) += main.c | ||
SRCS-$(CONFIG_RTE_TEST_BBDEV) += test_bbdev.c | ||
SRCS-$(CONFIG_RTE_TEST_BBDEV) += test_bbdev_perf.c | ||
SRCS-$(CONFIG_RTE_TEST_BBDEV) += test_bbdev_vector.c | ||
|
||
include $(RTE_SDK)/mk/rte.app.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,325 @@ | ||
/* SPDX-License-Identifier: BSD-3-Clause | ||
* Copyright(c) 2017 Intel Corporation | ||
*/ | ||
|
||
#include <getopt.h> | ||
#include <inttypes.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <stdbool.h> | ||
|
||
#include <rte_eal.h> | ||
#include <rte_common.h> | ||
#include <rte_string_fns.h> | ||
#include <rte_cycles.h> | ||
#include <rte_lcore.h> | ||
|
||
#include "main.h" | ||
|
||
/* Defines how many testcases can be specified as cmdline args */ | ||
#define MAX_CMDLINE_TESTCASES 8 | ||
|
||
static const char tc_sep = ','; | ||
|
||
static struct test_params { | ||
struct test_command *test_to_run[MAX_CMDLINE_TESTCASES]; | ||
unsigned int num_tests; | ||
unsigned int num_ops; | ||
unsigned int burst_sz; | ||
unsigned int num_lcores; | ||
char test_vector_filename[PATH_MAX]; | ||
} test_params; | ||
|
||
static struct test_commands_list commands_list = | ||
TAILQ_HEAD_INITIALIZER(commands_list); | ||
|
||
void | ||
add_test_command(struct test_command *t) | ||
{ | ||
TAILQ_INSERT_TAIL(&commands_list, t, next); | ||
} | ||
|
||
int | ||
unit_test_suite_runner(struct unit_test_suite *suite) | ||
{ | ||
int test_result = TEST_SUCCESS; | ||
unsigned int total = 0, skipped = 0, succeeded = 0, failed = 0; | ||
uint64_t start, end; | ||
|
||
printf( | ||
"\n + ------------------------------------------------------- +\n"); | ||
printf(" + Starting Test Suite : %s\n", suite->suite_name); | ||
|
||
start = rte_rdtsc_precise(); | ||
|
||
if (suite->setup) { | ||
test_result = suite->setup(); | ||
if (test_result == TEST_FAILED) { | ||
printf(" + Test suite setup %s failed!\n", | ||
suite->suite_name); | ||
printf( | ||
" + ------------------------------------------------------- +\n"); | ||
return 1; | ||
} | ||
if (test_result == TEST_SKIPPED) { | ||
printf(" + Test suite setup %s skipped!\n", | ||
suite->suite_name); | ||
printf( | ||
" + ------------------------------------------------------- +\n"); | ||
return 0; | ||
} | ||
} | ||
|
||
while (suite->unit_test_cases[total].testcase) { | ||
if (suite->unit_test_cases[total].setup) | ||
test_result = suite->unit_test_cases[total].setup(); | ||
|
||
if (test_result == TEST_SUCCESS) | ||
test_result = suite->unit_test_cases[total].testcase(); | ||
|
||
if (suite->unit_test_cases[total].teardown) | ||
suite->unit_test_cases[total].teardown(); | ||
|
||
if (test_result == TEST_SUCCESS) { | ||
succeeded++; | ||
printf(" + TestCase [%2d] : %s passed\n", total, | ||
suite->unit_test_cases[total].name); | ||
} else if (test_result == TEST_SKIPPED) { | ||
skipped++; | ||
printf(" + TestCase [%2d] : %s skipped\n", total, | ||
suite->unit_test_cases[total].name); | ||
} else { | ||
failed++; | ||
printf(" + TestCase [%2d] : %s failed\n", total, | ||
suite->unit_test_cases[total].name); | ||
} | ||
|
||
total++; | ||
} | ||
|
||
/* Run test suite teardown */ | ||
if (suite->teardown) | ||
suite->teardown(); | ||
|
||
end = rte_rdtsc_precise(); | ||
|
||
printf(" + ------------------------------------------------------- +\n"); | ||
printf(" + Test Suite Summary : %s\n", suite->suite_name); | ||
printf(" + Tests Total : %2d\n", total); | ||
printf(" + Tests Skipped : %2d\n", skipped); | ||
printf(" + Tests Passed : %2d\n", succeeded); | ||
printf(" + Tests Failed : %2d\n", failed); | ||
printf(" + Tests Lasted : %lg ms\n", | ||
((end - start) * 1000) / (double)rte_get_tsc_hz()); | ||
printf(" + ------------------------------------------------------- +\n"); | ||
|
||
return (failed > 0) ? 1 : 0; | ||
} | ||
|
||
const char * | ||
get_vector_filename(void) | ||
{ | ||
return test_params.test_vector_filename; | ||
} | ||
|
||
unsigned int | ||
get_num_ops(void) | ||
{ | ||
return test_params.num_ops; | ||
} | ||
|
||
unsigned int | ||
get_burst_sz(void) | ||
{ | ||
return test_params.burst_sz; | ||
} | ||
|
||
unsigned int | ||
get_num_lcores(void) | ||
{ | ||
return test_params.num_lcores; | ||
} | ||
|
||
static void | ||
print_usage(const char *prog_name) | ||
{ | ||
struct test_command *t; | ||
|
||
printf("Usage: %s [EAL params] [-- [-n/--num-ops NUM_OPS]\n" | ||
"\t[-b/--burst-size BURST_SIZE]\n" | ||
"\t[-v/--test-vector VECTOR_FILE]\n" | ||
"\t[-c/--test-cases TEST_CASE[,TEST_CASE,...]]]\n", | ||
prog_name); | ||
|
||
printf("Available testcases: "); | ||
TAILQ_FOREACH(t, &commands_list, next) | ||
printf("%s ", t->command); | ||
printf("\n"); | ||
} | ||
|
||
static int | ||
parse_args(int argc, char **argv, struct test_params *tp) | ||
{ | ||
int opt, option_index; | ||
unsigned int num_tests = 0; | ||
bool test_cases_present = false; | ||
bool test_vector_present = false; | ||
struct test_command *t; | ||
char *tokens[MAX_CMDLINE_TESTCASES]; | ||
int tc, ret; | ||
|
||
static struct option lgopts[] = { | ||
{ "num-ops", 1, 0, 'n' }, | ||
{ "burst-size", 1, 0, 'b' }, | ||
{ "test-cases", 1, 0, 'c' }, | ||
{ "test-vector", 1, 0, 'v' }, | ||
{ "lcores", 1, 0, 'l' }, | ||
{ "help", 0, 0, 'h' }, | ||
{ NULL, 0, 0, 0 } | ||
}; | ||
|
||
while ((opt = getopt_long(argc, argv, "hn:b:c:v:l:", lgopts, | ||
&option_index)) != EOF) | ||
switch (opt) { | ||
case 'n': | ||
TEST_ASSERT(strlen(optarg) > 0, | ||
"Num of operations is not provided"); | ||
tp->num_ops = strtol(optarg, NULL, 10); | ||
break; | ||
case 'b': | ||
TEST_ASSERT(strlen(optarg) > 0, | ||
"Burst size is not provided"); | ||
tp->burst_sz = strtol(optarg, NULL, 10); | ||
TEST_ASSERT(tp->burst_sz <= MAX_BURST, | ||
"Burst size mustn't be greater than %u", | ||
MAX_BURST); | ||
break; | ||
case 'c': | ||
TEST_ASSERT(test_cases_present == false, | ||
"Test cases provided more than once"); | ||
test_cases_present = true; | ||
|
||
ret = rte_strsplit(optarg, strlen(optarg), | ||
tokens, MAX_CMDLINE_TESTCASES, tc_sep); | ||
|
||
TEST_ASSERT(ret <= MAX_CMDLINE_TESTCASES, | ||
"Too many test cases (max=%d)", | ||
MAX_CMDLINE_TESTCASES); | ||
|
||
for (tc = 0; tc < ret; ++tc) { | ||
/* Find matching test case */ | ||
TAILQ_FOREACH(t, &commands_list, next) | ||
if (!strcmp(tokens[tc], t->command)) | ||
tp->test_to_run[num_tests] = t; | ||
|
||
TEST_ASSERT(tp->test_to_run[num_tests] != NULL, | ||
"Unknown test case: %s", | ||
tokens[tc]); | ||
++num_tests; | ||
} | ||
break; | ||
case 'v': | ||
TEST_ASSERT(test_vector_present == false, | ||
"Test vector provided more than once"); | ||
test_vector_present = true; | ||
|
||
TEST_ASSERT(strlen(optarg) > 0, | ||
"Config file name is null"); | ||
|
||
strncpy(tp->test_vector_filename, optarg, | ||
sizeof(tp->test_vector_filename)); | ||
break; | ||
case 'l': | ||
TEST_ASSERT(strlen(optarg) > 0, | ||
"Num of lcores is not provided"); | ||
tp->num_lcores = strtol(optarg, NULL, 10); | ||
TEST_ASSERT(tp->num_lcores <= RTE_MAX_LCORE, | ||
"Num of lcores mustn't be greater than %u", | ||
RTE_MAX_LCORE); | ||
break; | ||
case 'h': | ||
print_usage(argv[0]); | ||
return 0; | ||
default: | ||
printf("ERROR: Unknown option: -%c\n", opt); | ||
return -1; | ||
} | ||
|
||
if (tp->num_ops == 0) { | ||
printf( | ||
"WARNING: Num of operations was not provided or was set 0. Set to default (%u)\n", | ||
DEFAULT_OPS); | ||
tp->num_ops = DEFAULT_OPS; | ||
} | ||
if (tp->burst_sz == 0) { | ||
printf( | ||
"WARNING: Burst size was not provided or was set 0. Set to default (%u)\n", | ||
DEFAULT_BURST); | ||
tp->burst_sz = DEFAULT_BURST; | ||
} | ||
if (tp->num_lcores == 0) { | ||
printf( | ||
"WARNING: Num of lcores was not provided or was set 0. Set to value from RTE config (%u)\n", | ||
rte_lcore_count()); | ||
tp->num_lcores = rte_lcore_count(); | ||
} | ||
|
||
TEST_ASSERT(tp->burst_sz <= tp->num_ops, | ||
"Burst size (%u) mustn't be greater than num ops (%u)", | ||
tp->burst_sz, tp->num_ops); | ||
|
||
tp->num_tests = num_tests; | ||
return 0; | ||
} | ||
|
||
static int | ||
run_all_tests(void) | ||
{ | ||
int ret = TEST_SUCCESS; | ||
struct test_command *t; | ||
|
||
TAILQ_FOREACH(t, &commands_list, next) | ||
ret |= t->callback(); | ||
|
||
return ret; | ||
} | ||
|
||
static int | ||
run_parsed_tests(struct test_params *tp) | ||
{ | ||
int ret = TEST_SUCCESS; | ||
unsigned int i; | ||
|
||
for (i = 0; i < tp->num_tests; ++i) | ||
ret |= tp->test_to_run[i]->callback(); | ||
|
||
return ret; | ||
} | ||
|
||
int | ||
main(int argc, char **argv) | ||
{ | ||
int ret; | ||
|
||
/* Init EAL */ | ||
ret = rte_eal_init(argc, argv); | ||
if (ret < 0) | ||
return 1; | ||
argc -= ret; | ||
argv += ret; | ||
|
||
/* Parse application arguments (after the EAL ones) */ | ||
ret = parse_args(argc, argv, &test_params); | ||
if (ret < 0) { | ||
print_usage(argv[0]); | ||
return 1; | ||
} | ||
|
||
rte_log_set_global_level(RTE_LOG_INFO); | ||
|
||
/* If no argument provided - run all tests */ | ||
if (test_params.num_tests == 0) | ||
return run_all_tests(); | ||
else | ||
return run_parsed_tests(&test_params); | ||
} |
Oops, something went wrong.