There was no coverage for a device string with no driver arguments,
which is how Bugzilla 2049 went unnoticed: global device syntax with
no driver layer left args NULL and drivers crashed passing it to
rte_kvargs_parse().

Add a devargs case asserting args is non-NULL and empty for global
syntax without a driver layer, and that it parses as kvargs the way a
driver would use it.  Add a kvargs case for rte_kvargs_parse(NULL),
which must give an empty list.

Signed-off-by: Stephen Hemminger <[email protected]>
---
 app/test/test_devargs.c | 60 +++++++++++++++++++++++++++++++++++++++++
 app/test/test_kvargs.c  | 16 +++++++++++
 2 files changed, 76 insertions(+)

diff --git a/app/test/test_devargs.c b/app/test/test_devargs.c
index de0dd2364d..693bf362d4 100644
--- a/app/test/test_devargs.c
+++ b/app/test/test_devargs.c
@@ -193,6 +193,65 @@ test_invalid_devargs(void)
        return fail;
 }
 
+/*
+ * Global device syntax without a driver layer must still leave args set,
+ * as the legacy syntax does.  Drivers pass it straight to
+ * rte_kvargs_parse(), which used to crash on NULL.
+ */
+static int
+test_devargs_no_driver_layer(void)
+{
+       static const char * const list[] = {
+               "bus=vdev,name=net_null0",
+               "bus=vdev,name=net_null0/class=eth",
+               "class=eth",
+       };
+       struct rte_kvargs *kvlist;
+       struct rte_devargs da;
+       uint32_t i;
+       int ret;
+       int fail = TEST_SUCCESS;
+
+       if (rte_bus_find_by_name("vdev") == NULL ||
+           rte_class_find_by_name("eth") == NULL) {
+               printf("vdev bus or eth class missing, skipping\n");
+               return TEST_SKIPPED;
+       }
+
+       for (i = 0; i < RTE_DIM(list); i++) {
+               memset(&da, 0, sizeof(da));
+               ret = rte_devargs_parse(&da, list[i]);
+               if (ret < 0) {
+                       printf("rte_devargs_parse(%s) returned %d (but should 
not)\n",
+                              list[i], ret);
+                       fail = TEST_FAILED;
+                       goto cleanup;
+               }
+               if (da.args == NULL) {
+                       printf("rte_devargs_parse(%s) left args NULL\n", 
list[i]);
+                       fail = TEST_FAILED;
+                       goto cleanup;
+               }
+               if (da.args[0] != '\0') {
+                       printf("rte_devargs_parse(%s) args (%s) not empty\n",
+                              list[i], da.args);
+                       fail = TEST_FAILED;
+                       goto cleanup;
+               }
+               /* What a driver does with it. */
+               kvlist = rte_kvargs_parse(da.args, NULL);
+               if (kvlist == NULL) {
+                       printf("rte_kvargs_parse(%s args) failed\n", list[i]);
+                       fail = TEST_FAILED;
+                       goto cleanup;
+               }
+               rte_kvargs_free(kvlist);
+cleanup:
+               rte_devargs_reset(&da);
+       }
+       return fail;
+}
+
 struct devargs_parse_case {
        const char *devargs;
        uint8_t devargs_count;
@@ -300,6 +359,7 @@ static struct unit_test_suite devargs_test_suite = {
        .unit_test_cases = {
                TEST_CASE(test_valid_devargs),
                TEST_CASE(test_invalid_devargs),
+               TEST_CASE(test_devargs_no_driver_layer),
                TEST_CASE(test_valid_devargs_parsing),
                TEST_CASE(test_invalid_devargs_parsing),
                TEST_CASES_END() /**< NULL terminate unit test array */
diff --git a/app/test/test_kvargs.c b/app/test/test_kvargs.c
index a14b75948a..5dd74bec49 100644
--- a/app/test/test_kvargs.c
+++ b/app/test/test_kvargs.c
@@ -328,6 +328,21 @@ static int test_invalid_kvargs(void)
        return -1;
 }
 
+/* NULL means no arguments, and must give an empty list rather than crash. */
+static int
+test_parse_null_args(void)
+{
+       struct rte_kvargs *kvlist;
+
+       kvlist = rte_kvargs_parse(NULL, NULL);
+       TEST_ASSERT_NOT_NULL(kvlist, "rte_kvargs_parse(NULL) returned NULL");
+       TEST_ASSERT_EQUAL(kvlist->count, 0, "rte_kvargs_parse(NULL) count %u, 
not 0",
+                         kvlist->count);
+       rte_kvargs_free(kvlist);
+
+       return 0;
+}
+
 static struct unit_test_suite kvargs_test_suite  = {
        .suite_name = "Kvargs Unit Test Suite",
        .setup = NULL,
@@ -353,6 +368,7 @@ static struct unit_test_suite kvargs_test_suite  = {
                TEST_CASE(test_parse_list_value),
                TEST_CASE(test_parse_empty_elements),
                TEST_CASE(test_parse_with_only_key),
+               TEST_CASE(test_parse_null_args),
                TEST_CASE(test_invalid_kvargs),
                TEST_CASES_END() /**< NULL terminate unit test array */
        }
-- 
2.53.0

Reply via email to