dpdk/app/test-bbdev/main.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2017 Intel Corporation
   3 */
   4
   5#include <getopt.h>
   6#include <inttypes.h>
   7#include <stdio.h>
   8#include <string.h>
   9#include <stdbool.h>
  10
  11#include <rte_eal.h>
  12#include <rte_common.h>
  13#include <rte_string_fns.h>
  14#include <rte_cycles.h>
  15#include <rte_lcore.h>
  16
  17#include "main.h"
  18
  19
  20/* Defines how many testcases can be specified as cmdline args */
  21#define MAX_CMDLINE_TESTCASES 8
  22
  23static const char tc_sep = ',';
  24
  25/* Declare structure for command line test parameters and options */
  26static struct test_params {
  27        struct test_command *test_to_run[MAX_CMDLINE_TESTCASES];
  28        unsigned int num_tests;
  29        unsigned int num_ops;
  30        unsigned int burst_sz;
  31        unsigned int num_lcores;
  32        double snr;
  33        unsigned int iter_max;
  34        char test_vector_filename[PATH_MAX];
  35        bool init_device;
  36} test_params;
  37
  38static struct test_commands_list commands_list =
  39        TAILQ_HEAD_INITIALIZER(commands_list);
  40
  41void
  42add_test_command(struct test_command *t)
  43{
  44        TAILQ_INSERT_TAIL(&commands_list, t, next);
  45}
  46
  47int
  48unit_test_suite_runner(struct unit_test_suite *suite)
  49{
  50        int test_result = TEST_SUCCESS;
  51        unsigned int total = 0, skipped = 0, succeeded = 0, failed = 0;
  52        uint64_t start, end;
  53
  54        printf("\n===========================================================\n");
  55        printf("Starting Test Suite : %s\n", suite->suite_name);
  56
  57        start = rte_rdtsc_precise();
  58
  59        if (suite->setup) {
  60                test_result = suite->setup();
  61                if (test_result == TEST_FAILED) {
  62                        printf(" + Test suite setup %s failed!\n",
  63                                        suite->suite_name);
  64                        printf(" + ------------------------------------------------------- +\n");
  65                        return 1;
  66                }
  67                if (test_result == TEST_SKIPPED) {
  68                        printf(" + Test suite setup %s skipped!\n",
  69                                        suite->suite_name);
  70                        printf(" + ------------------------------------------------------- +\n");
  71                        return 0;
  72                }
  73        }
  74
  75        while (suite->unit_test_cases[total].testcase) {
  76                if (suite->unit_test_cases[total].setup)
  77                        test_result = suite->unit_test_cases[total].setup();
  78
  79                if (test_result == TEST_SUCCESS)
  80                        test_result = suite->unit_test_cases[total].testcase();
  81
  82                if (suite->unit_test_cases[total].teardown)
  83                        suite->unit_test_cases[total].teardown();
  84
  85                if (test_result == TEST_SUCCESS) {
  86                        succeeded++;
  87                        printf("TestCase [%2d] : %s passed\n", total,
  88                                        suite->unit_test_cases[total].name);
  89                } else if (test_result == TEST_SKIPPED) {
  90                        skipped++;
  91                        printf("TestCase [%2d] : %s skipped\n", total,
  92                                        suite->unit_test_cases[total].name);
  93                } else {
  94                        failed++;
  95                        printf("TestCase [%2d] : %s failed\n", total,
  96                                        suite->unit_test_cases[total].name);
  97                }
  98
  99                total++;
 100        }
 101
 102        /* Run test suite teardown */
 103        if (suite->teardown)
 104                suite->teardown();
 105
 106        end = rte_rdtsc_precise();
 107
 108        printf(" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +\n");
 109        printf(" + Test Suite Summary : %s\n", suite->suite_name);
 110        printf(" + Tests Total :       %2d\n", total);
 111        printf(" + Tests Skipped :     %2d\n", skipped);
 112        printf(" + Tests Passed :      %2d\n", succeeded);
 113        printf(" + Tests Failed :      %2d\n", failed);
 114        printf(" + Tests Lasted :       %lg ms\n",
 115                        ((end - start) * 1000) / (double)rte_get_tsc_hz());
 116        printf(" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +\n");
 117
 118        return (failed > 0) ? 1 : 0;
 119}
 120
 121const char *
 122get_vector_filename(void)
 123{
 124        return test_params.test_vector_filename;
 125}
 126
 127unsigned int
 128get_num_ops(void)
 129{
 130        return test_params.num_ops;
 131}
 132
 133unsigned int
 134get_burst_sz(void)
 135{
 136        return test_params.burst_sz;
 137}
 138
 139unsigned int
 140get_num_lcores(void)
 141{
 142        return test_params.num_lcores;
 143}
 144
 145double
 146get_snr(void)
 147{
 148        return test_params.snr;
 149}
 150
 151unsigned int
 152get_iter_max(void)
 153{
 154        return test_params.iter_max;
 155}
 156
 157bool
 158get_init_device(void)
 159{
 160        return test_params.init_device;
 161}
 162
 163static void
 164print_usage(const char *prog_name)
 165{
 166        struct test_command *t;
 167
 168        printf("***Usage: %s [EAL params] [-- [-n/--num-ops NUM_OPS]\n"
 169                        "\t[-b/--burst-size BURST_SIZE]\n"
 170                        "\t[-v/--test-vector VECTOR_FILE]\n"
 171                        "\t[-c/--test-cases TEST_CASE[,TEST_CASE,...]]]\n",
 172                        prog_name);
 173
 174        printf("Available testcases: ");
 175        TAILQ_FOREACH(t, &commands_list, next)
 176                printf("%s ", t->command);
 177        printf("\n");
 178}
 179
 180static int
 181parse_args(int argc, char **argv, struct test_params *tp)
 182{
 183        int opt, option_index;
 184        unsigned int num_tests = 0;
 185        bool test_cases_present = false;
 186        bool test_vector_present = false;
 187        struct test_command *t;
 188        char *tokens[MAX_CMDLINE_TESTCASES];
 189        int tc, ret;
 190
 191        static struct option lgopts[] = {
 192                { "num-ops", 1, 0, 'n' },
 193                { "burst-size", 1, 0, 'b' },
 194                { "test-cases", 1, 0, 'c' },
 195                { "test-vector", 1, 0, 'v' },
 196                { "lcores", 1, 0, 'l' },
 197                { "snr", 1, 0, 's' },
 198                { "iter_max", 6, 0, 't' },
 199                { "init-device", 0, 0, 'i'},
 200                { "help", 0, 0, 'h' },
 201                { NULL,  0, 0, 0 }
 202        };
 203        tp->iter_max = DEFAULT_ITER;
 204
 205        while ((opt = getopt_long(argc, argv, "hin:b:c:v:l:s:t:", lgopts,
 206                        &option_index)) != EOF)
 207                switch (opt) {
 208                case 'n':
 209                        TEST_ASSERT(strlen(optarg) > 0,
 210                                        "Num of operations is not provided");
 211                        tp->num_ops = strtol(optarg, NULL, 10);
 212                        break;
 213                case 'b':
 214                        TEST_ASSERT(strlen(optarg) > 0,
 215                                        "Burst size is not provided");
 216                        tp->burst_sz = strtol(optarg, NULL, 10);
 217                        TEST_ASSERT(tp->burst_sz <= MAX_BURST,
 218                                        "Burst size mustn't be greater than %u",
 219                                        MAX_BURST);
 220                        break;
 221                case 'c':
 222                        TEST_ASSERT(test_cases_present == false,
 223                                        "Test cases provided more than once");
 224                        test_cases_present = true;
 225
 226                        ret = rte_strsplit(optarg, strlen(optarg),
 227                                        tokens, MAX_CMDLINE_TESTCASES, tc_sep);
 228
 229                        TEST_ASSERT(ret <= MAX_CMDLINE_TESTCASES,
 230                                        "Too many test cases (max=%d)",
 231                                        MAX_CMDLINE_TESTCASES);
 232
 233                        for (tc = 0; tc < ret; ++tc) {
 234                                /* Find matching test case */
 235                                TAILQ_FOREACH(t, &commands_list, next)
 236                                        if (!strcmp(tokens[tc], t->command))
 237                                                tp->test_to_run[num_tests] = t;
 238
 239                                TEST_ASSERT(tp->test_to_run[num_tests] != NULL,
 240                                                "Unknown test case: %s",
 241                                                tokens[tc]);
 242                                ++num_tests;
 243                        }
 244                        break;
 245                case 'v':
 246                        TEST_ASSERT(test_vector_present == false,
 247                                        "Test vector provided more than once");
 248                        test_vector_present = true;
 249
 250                        TEST_ASSERT(strlen(optarg) > 0,
 251                                        "Config file name is null");
 252
 253                        snprintf(tp->test_vector_filename,
 254                                        sizeof(tp->test_vector_filename),
 255                                        "%s", optarg);
 256                        break;
 257                case 's':
 258                        TEST_ASSERT(strlen(optarg) > 0,
 259                                        "SNR is not provided");
 260                        tp->snr = strtod(optarg, NULL);
 261                        break;
 262                case 't':
 263                        TEST_ASSERT(strlen(optarg) > 0,
 264                                        "Iter_max is not provided");
 265                        tp->iter_max = strtol(optarg, NULL, 10);
 266                        break;
 267                case 'l':
 268                        TEST_ASSERT(strlen(optarg) > 0,
 269                                        "Num of lcores is not provided");
 270                        tp->num_lcores = strtol(optarg, NULL, 10);
 271                        TEST_ASSERT(tp->num_lcores <= RTE_MAX_LCORE,
 272                                        "Num of lcores mustn't be greater than %u",
 273                                        RTE_MAX_LCORE);
 274                        break;
 275                case 'i':
 276                        /* indicate fpga fec config required */
 277                        tp->init_device = true;
 278                        break;
 279                case 'h':
 280                        print_usage(argv[0]);
 281                        return 0;
 282                default:
 283                        printf("ERROR: Unknown option: -%c\n", opt);
 284                        return -1;
 285                }
 286
 287        if (tp->num_ops == 0) {
 288                printf(
 289                        "WARNING: Num of operations was not provided or was set 0. Set to default (%u)\n",
 290                        DEFAULT_OPS);
 291                tp->num_ops = DEFAULT_OPS;
 292        }
 293        if (tp->burst_sz == 0) {
 294                printf(
 295                        "WARNING: Burst size was not provided or was set 0. Set to default (%u)\n",
 296                        DEFAULT_BURST);
 297                tp->burst_sz = DEFAULT_BURST;
 298        }
 299        if (tp->num_lcores == 0) {
 300                printf(
 301                        "WARNING: Num of lcores was not provided or was set 0. Set to value from RTE config (%u)\n",
 302                        rte_lcore_count());
 303                tp->num_lcores = rte_lcore_count();
 304        }
 305
 306        TEST_ASSERT(tp->burst_sz <= tp->num_ops,
 307                        "Burst size (%u) mustn't be greater than num ops (%u)",
 308                        tp->burst_sz, tp->num_ops);
 309
 310        tp->num_tests = num_tests;
 311        return 0;
 312}
 313
 314static int
 315run_all_tests(void)
 316{
 317        int ret = TEST_SUCCESS;
 318        struct test_command *t;
 319
 320        TAILQ_FOREACH(t, &commands_list, next)
 321                ret |= (int) t->callback();
 322
 323        return ret;
 324}
 325
 326static int
 327run_parsed_tests(struct test_params *tp)
 328{
 329        int ret = TEST_SUCCESS;
 330        unsigned int i;
 331
 332        for (i = 0; i < tp->num_tests; ++i)
 333                ret |= (int) tp->test_to_run[i]->callback();
 334
 335        return ret;
 336}
 337
 338int
 339main(int argc, char **argv)
 340{
 341        int ret;
 342
 343        /* Init EAL */
 344        ret = rte_eal_init(argc, argv);
 345        if (ret < 0)
 346                return 1;
 347        argc -= ret;
 348        argv += ret;
 349
 350        /* Parse application arguments (after the EAL ones) */
 351        ret = parse_args(argc, argv, &test_params);
 352        if (ret < 0) {
 353                print_usage(argv[0]);
 354                return 1;
 355        }
 356
 357        /* If no argument provided - run all tests */
 358        if (test_params.num_tests == 0)
 359                return run_all_tests();
 360        else
 361                return run_parsed_tests(&test_params);
 362}
 363