testing/vsock: add parameters to list and skip tests
authorStefano Garzarella <sgarzare@redhat.com>
Wed, 18 Dec 2019 18:07:06 +0000 (19:07 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sat, 21 Dec 2019 05:09:21 +0000 (21:09 -0800)
Some tests can fail with transports that have a slightly
different behavior, so let's add the possibility to specify
which tests to skip.

Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
tools/testing/vsock/control.c
tools/testing/vsock/control.h
tools/testing/vsock/util.c
tools/testing/vsock/util.h
tools/testing/vsock/vsock_diag_test.c
tools/testing/vsock/vsock_test.c

index 45f328c..4874872 100644 (file)
@@ -205,11 +205,22 @@ void control_expectln(const char *str)
        char *line;
 
        line = control_readln();
-       if (strcmp(str, line) != 0) {
+
+       control_cmpln(line, str, true);
+
+       free(line);
+}
+
+bool control_cmpln(char *line, const char *str, bool fail)
+{
+       if (strcmp(str, line) == 0)
+               return true;
+
+       if (fail) {
                fprintf(stderr, "expected \"%s\" on control socket, got \"%s\"\n",
                        str, line);
                exit(EXIT_FAILURE);
        }
 
-       free(line);
+       return false;
 }
index dac3964..51814b4 100644 (file)
@@ -10,5 +10,6 @@ void control_cleanup(void);
 void control_writeln(const char *str);
 char *control_readln(void);
 void control_expectln(const char *str);
+bool control_cmpln(char *line, const char *str, bool fail);
 
 #endif /* CONTROL_H */
index b132c96..93cbd6f 100644 (file)
@@ -299,32 +299,77 @@ void run_tests(const struct test_case *test_cases,
 
        for (i = 0; test_cases[i].name; i++) {
                void (*run)(const struct test_opts *opts);
+               char *line;
 
-               printf("%s...", test_cases[i].name);
+               printf("%d - %s...", i, test_cases[i].name);
                fflush(stdout);
 
-               if (opts->mode == TEST_MODE_CLIENT) {
-                       /* Full barrier before executing the next test.  This
-                        * ensures that client and server are executing the
-                        * same test case.  In particular, it means whoever is
-                        * faster will not see the peer still executing the
-                        * last test.  This is important because port numbers
-                        * can be used by multiple test cases.
-                        */
-                       control_expectln("NEXT");
+               /* Full barrier before executing the next test.  This
+                * ensures that client and server are executing the
+                * same test case.  In particular, it means whoever is
+                * faster will not see the peer still executing the
+                * last test.  This is important because port numbers
+                * can be used by multiple test cases.
+                */
+               if (test_cases[i].skip)
+                       control_writeln("SKIP");
+               else
                        control_writeln("NEXT");
 
-                       run = test_cases[i].run_client;
-               } else {
-                       control_writeln("NEXT");
-                       control_expectln("NEXT");
+               line = control_readln();
+               if (control_cmpln(line, "SKIP", false) || test_cases[i].skip) {
 
-                       run = test_cases[i].run_server;
+                       printf("skipped\n");
+
+                       free(line);
+                       continue;
                }
 
+               control_cmpln(line, "NEXT", true);
+               free(line);
+
+               if (opts->mode == TEST_MODE_CLIENT)
+                       run = test_cases[i].run_client;
+               else
+                       run = test_cases[i].run_server;
+
                if (run)
                        run(opts);
 
                printf("ok\n");
        }
 }
+
+void list_tests(const struct test_case *test_cases)
+{
+       int i;
+
+       printf("ID\tTest name\n");
+
+       for (i = 0; test_cases[i].name; i++)
+               printf("%d\t%s\n", i, test_cases[i].name);
+
+       exit(EXIT_FAILURE);
+}
+
+void skip_test(struct test_case *test_cases, size_t test_cases_len,
+              const char *test_id_str)
+{
+       unsigned long test_id;
+       char *endptr = NULL;
+
+       errno = 0;
+       test_id = strtoul(test_id_str, &endptr, 10);
+       if (errno || *endptr != '\0') {
+               fprintf(stderr, "malformed test ID \"%s\"\n", test_id_str);
+               exit(EXIT_FAILURE);
+       }
+
+       if (test_id >= test_cases_len) {
+               fprintf(stderr, "test ID (%lu) larger than the max allowed (%lu)\n",
+                       test_id, test_cases_len - 1);
+               exit(EXIT_FAILURE);
+       }
+
+       test_cases[test_id].skip = true;
+}
index 331e945..e53dd09 100644 (file)
@@ -29,6 +29,8 @@ struct test_case {
 
        /* Called when test mode is TEST_MODE_SERVER */
        void (*run_server)(const struct test_opts *opts);
+
+       bool skip;
 };
 
 void init_signals(void);
@@ -41,5 +43,7 @@ void send_byte(int fd, int expected_ret, int flags);
 void recv_byte(int fd, int expected_ret, int flags);
 void run_tests(const struct test_case *test_cases,
               const struct test_opts *opts);
-
+void list_tests(const struct test_case *test_cases);
+void skip_test(struct test_case *test_cases, size_t test_cases_len,
+              const char *test_id_str);
 #endif /* UTIL_H */
index abd7dc2..b824836 100644 (file)
@@ -463,6 +463,16 @@ static const struct option longopts[] = {
                .has_arg = required_argument,
                .val = 'p',
        },
+       {
+               .name = "list",
+               .has_arg = no_argument,
+               .val = 'l',
+       },
+       {
+               .name = "skip",
+               .has_arg = required_argument,
+               .val = 's',
+       },
        {
                .name = "help",
                .has_arg = no_argument,
@@ -473,7 +483,7 @@ static const struct option longopts[] = {
 
 static void usage(void)
 {
-       fprintf(stderr, "Usage: vsock_diag_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid>\n"
+       fprintf(stderr, "Usage: vsock_diag_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid> [--list] [--skip=<test_id>]\n"
                "\n"
                "  Server: vsock_diag_test --control-port=1234 --mode=server --peer-cid=3\n"
                "  Client: vsock_diag_test --control-host=192.168.0.1 --control-port=1234 --mode=client --peer-cid=2\n"
@@ -528,6 +538,13 @@ int main(int argc, char **argv)
                case 'P':
                        control_port = optarg;
                        break;
+               case 'l':
+                       list_tests(test_cases);
+                       break;
+               case 's':
+                       skip_test(test_cases, ARRAY_SIZE(test_cases) - 1,
+                                 optarg);
+                       break;
                case '?':
                default:
                        usage();
index 629d7ce..3ac5665 100644 (file)
@@ -13,6 +13,7 @@
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
+#include <linux/kernel.h>
 
 #include "timeout.h"
 #include "control.h"
@@ -222,6 +223,16 @@ static const struct option longopts[] = {
                .has_arg = required_argument,
                .val = 'p',
        },
+       {
+               .name = "list",
+               .has_arg = no_argument,
+               .val = 'l',
+       },
+       {
+               .name = "skip",
+               .has_arg = required_argument,
+               .val = 's',
+       },
        {
                .name = "help",
                .has_arg = no_argument,
@@ -232,7 +243,7 @@ static const struct option longopts[] = {
 
 static void usage(void)
 {
-       fprintf(stderr, "Usage: vsock_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid>\n"
+       fprintf(stderr, "Usage: vsock_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid> [--list] [--skip=<test_id>]\n"
                "\n"
                "  Server: vsock_test --control-port=1234 --mode=server --peer-cid=3\n"
                "  Client: vsock_test --control-host=192.168.0.1 --control-port=1234 --mode=client --peer-cid=2\n"
@@ -287,6 +298,13 @@ int main(int argc, char **argv)
                case 'P':
                        control_port = optarg;
                        break;
+               case 'l':
+                       list_tests(test_cases);
+                       break;
+               case 's':
+                       skip_test(test_cases, ARRAY_SIZE(test_cases) - 1,
+                                 optarg);
+                       break;
                case '?':
                default:
                        usage();