tests: Break single classifier test into multiple.
authorBen Pfaff <blp@nicira.com>
Mon, 22 Mar 2010 18:27:08 +0000 (11:27 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 1 Apr 2010 22:59:08 +0000 (15:59 -0700)
This should make it easier to tell what is failing, if anything does.

tests/automake.mk
tests/classifier.at [new file with mode: 0644]
tests/library.at
tests/test-classifier.c
tests/test-command-line.c [new file with mode: 0644]
tests/test-command-line.h [new file with mode: 0644]
tests/testsuite.at

index ebf2a01..639a23e 100644 (file)
@@ -8,6 +8,7 @@ TESTSUITE_AT = \
        tests/testsuite.at \
        tests/ovsdb-macros.at \
        tests/library.at \
+       tests/classifier.at \
        tests/check-structs.at \
        tests/daemon.at \
        tests/vconn.at \
@@ -170,7 +171,9 @@ tests_test_aes128_SOURCES = tests/test-aes128.c
 tests_test_aes128_LDADD = lib/libopenvswitch.a
 
 noinst_PROGRAMS += tests/test-classifier
-tests_test_classifier_SOURCES = tests/test-classifier.c
+tests_test_classifier_SOURCES = \
+       tests/test-classifier.c \
+       tests/test-command-line.c
 tests_test_classifier_LDADD = lib/libopenvswitch.a
 
 noinst_PROGRAMS += tests/test-csum
diff --git a/tests/classifier.at b/tests/classifier.at
new file mode 100644 (file)
index 0000000..a03ed45
--- /dev/null
@@ -0,0 +1,18 @@
+AT_BANNER([classifier unit tests])
+
+m4_define([CHECK_CLASSIFIER],
+  [AT_SETUP([m4_translit([$1], [-], [ ])])
+   AT_KEYWORDS([classifier $2])
+   AT_CHECK([test-classifier $1])
+   AT_CLEANUP])
+
+CHECK_CLASSIFIER([empty])
+CHECK_CLASSIFIER([destroy-null])
+CHECK_CLASSIFIER([single-rule], [slow])
+CHECK_CLASSIFIER([rule-replacement], [slow])
+CHECK_CLASSIFIER([two-rules-in-one-bucket])
+CHECK_CLASSIFIER([two-rules-in-one-table])
+CHECK_CLASSIFIER([two-rules-in-different-tables])
+CHECK_CLASSIFIER([many-rules-in-one-bucket], [slow])
+CHECK_CLASSIFIER([many-rules-in-one-table], [slow])
+CHECK_CLASSIFIER([many-rules-in-different-tables], [slow])
index 0e408f0..f9f97f1 100644 (file)
@@ -10,11 +10,6 @@ AT_SETUP([test TCP/IP checksumming])
 AT_CHECK([test-csum], [0], [ignore])
 AT_CLEANUP
 
-AT_SETUP([test flow classifier])
-AT_KEYWORDS([slow])
-AT_CHECK([test-classifier], [0], [ignore])
-AT_CLEANUP
-
 AT_SETUP([test hash functions])
 AT_CHECK([test-hash], [0], [ignore])
 AT_CLEANUP
index 3fb05b6..ce72cad 100644 (file)
 #include "classifier.h"
 #include <errno.h>
 #include <limits.h>
+#include "command-line.h"
 #include "flow.h"
 #include <limits.h>
 #include "packets.h"
+#include "test-command-line.h"
 
 #undef NDEBUG
 #include <assert.h>
@@ -479,7 +481,7 @@ shuffle(unsigned int *p, size_t n)
 \f
 /* Tests an empty classifier. */
 static void
-test_empty(void)
+test_empty(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 {
     struct classifier cls;
     struct tcls tcls;
@@ -495,14 +497,14 @@ test_empty(void)
 
 /* Destroys a null classifier. */
 static void
-test_destroy_null(void)
+test_destroy_null(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 {
     classifier_destroy(NULL);
 }
 
 /* Tests classification with one rule at a time. */
 static void
-test_single_rule(void)
+test_single_rule(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 {
     unsigned int wc_fields;     /* Hilarious. */
 
@@ -540,7 +542,7 @@ test_single_rule(void)
 
 /* Tests replacing one rule by another. */
 static void
-test_rule_replacement(void)
+test_rule_replacement(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 {
     unsigned int wc_fields;
 
@@ -591,7 +593,7 @@ random_wcf_in_table(int table, int seed)
 /* Tests classification with two rules at a time that fall into the same
  * bucket. */
 static void
-test_two_rules_in_one_bucket(void)
+test_two_rules_in_one_bucket(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 {
     int table, rel_pri, wcf_pat, value_pat;
 
@@ -680,7 +682,7 @@ test_two_rules_in_one_bucket(void)
 /* Tests classification with two rules at a time that fall into the same
  * table but different buckets. */
 static void
-test_two_rules_in_one_table(void)
+test_two_rules_in_one_table(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 {
     int table, rel_pri, wcf_pat;
 
@@ -756,7 +758,7 @@ test_two_rules_in_one_table(void)
 /* Tests classification with two rules at a time that fall into different
  * tables. */
 static void
-test_two_rules_in_different_tables(void)
+test_two_rules_in_different_tables(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 {
     int table1, table2, rel_pri, wcf_pat;
 
@@ -825,7 +827,7 @@ test_two_rules_in_different_tables(void)
 /* Tests classification with many rules at a time that fall into the same
  * bucket but have unique priorities (and various wildcards). */
 static void
-test_many_rules_in_one_bucket(void)
+test_many_rules_in_one_bucket(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 {
     enum { MAX_RULES = 50 };
     int iteration, table;
@@ -869,7 +871,7 @@ test_many_rules_in_one_bucket(void)
 /* Tests classification with many rules at a time that fall into the same
  * table but random buckets. */
 static void
-test_many_rules_in_one_table(void)
+test_many_rules_in_one_table(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 {
     enum { MAX_RULES = 50 };
     int iteration, table;
@@ -912,7 +914,8 @@ test_many_rules_in_one_table(void)
 /* Tests classification with many rules at a time that fall into random buckets
  * in random tables. */
 static void
-test_many_rules_in_different_tables(void)
+test_many_rules_in_different_tables(int argc OVS_UNUSED,
+                                    char *argv[] OVS_UNUSED)
 {
     enum { MAX_RULES = 50 };
     int iteration;
@@ -957,36 +960,35 @@ test_many_rules_in_different_tables(void)
             compare_classifiers(&cls, &tcls);
             free(rule);
         }
-        putchar('.');
-        fflush(stdout);
 
         destroy_classifier(&cls);
         tcls_destroy(&tcls);
     }
 }
 \f
-static void
-run_test(void (*function)(void))
-{
-    function();
-    putchar('.');
-    fflush(stdout);
-}
-
 int
-main(void)
-{
+main(int argc, char *argv[])
+{
+    static const struct command all_commands[] = {
+        { "empty", 0, 0, test_empty },
+        { "destroy-null", 0, 0, test_destroy_null },
+        { "single-rule", 0, 0, test_single_rule },
+        { "rule-replacement", 0, 0, test_rule_replacement },
+        { "two-rules-in-one-bucket", 0, 0, test_two_rules_in_one_bucket },
+        { "two-rules-in-one-table", 0, 0, test_two_rules_in_one_table },
+        { "two-rules-in-different-tables", 0, 0,
+          test_two_rules_in_different_tables },
+        { "many-rules-in-one-bucket", 0, 0,
+          test_many_rules_in_one_bucket },
+        { "many-rules-in-one-table", 0, 0, test_many_rules_in_one_table },
+        { "many-rules-in-different-tables", 0, 0,
+          test_many_rules_in_different_tables },
+        { NULL, 0, 0, NULL },
+    };
+
+    set_program_name(argv[0]);
     init_values();
-    run_test(test_empty);
-    run_test(test_destroy_null);
-    run_test(test_single_rule);
-    run_test(test_rule_replacement);
-    run_test(test_two_rules_in_one_bucket);
-    run_test(test_two_rules_in_one_table);
-    run_test(test_two_rules_in_different_tables);
-    run_test(test_many_rules_in_one_bucket);
-    run_test(test_many_rules_in_one_table);
-    run_test(test_many_rules_in_different_tables);
-    putchar('\n');
+    parse_test_options(argc, argv, all_commands);
+    run_command(argc - 1, argv + 1, all_commands);
     return 0;
 }
diff --git a/tests/test-command-line.c b/tests/test-command-line.c
new file mode 100644 (file)
index 0000000..369828f
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2010 Nicira Networks.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+#include "test-command-line.h"
+#include <getopt.h>
+#include <limits.h>
+#include <stdlib.h>
+#include "command-line.h"
+#include "timeval.h"
+#include "util.h"
+#include "vlog.h"
+
+static void
+test_usage(const struct command commands[])
+{
+    const struct command *p;
+
+    printf("%s: an Open vSwitch test utility\n"
+           "usage: %s [OPTIONS] COMMAND [ARG...]\n\n"
+           "Valid commands:\n" ,
+           program_name, program_name);
+
+    for (p = commands; p->name; p++) {
+        int i;
+
+        printf("  %s", p->name);
+        for (i = 0; i < p->min_args; i++) {
+            printf(" ARG%d", i + 1);
+        }
+        if (p->max_args == INT_MAX) {
+            printf(" [ARG...]");
+        } else if (p->max_args > p->min_args) {
+            for (i = p->min_args; i < p->max_args; i++) {
+                putchar(' ');
+                if (i == p->min_args) {
+                    putchar('[');
+                }
+                printf("ARG%d", i + 1);
+            }
+            putchar(']');
+        }
+        putchar('\n');
+    }
+    vlog_usage();
+    printf("\nOther options:\n"
+           "  -t, --timeout=SECS          give up after SECS seconds\n"
+           "  -h, --help                  display this help message\n");
+    exit(EXIT_SUCCESS);
+}
+
+/* Parses options for test programs that don't have any special needs.
+ * Prints --help output based on 'commands'. */
+void
+parse_test_options(int argc, char *argv[],
+                   const struct command commands[])
+{
+    static struct option long_options[] = {
+        {"timeout", required_argument, 0, 't'},
+        {"verbose", optional_argument, 0, 'v'},
+        {"help", no_argument, 0, 'h'},
+        {0, 0, 0, 0},
+    };
+    char *short_options = long_options_to_short_options(long_options);
+
+    for (;;) {
+        unsigned long int timeout;
+        int c;
+
+        c = getopt_long(argc, argv, short_options, long_options, NULL);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+        case 't':
+            timeout = strtoul(optarg, NULL, 10);
+            if (timeout <= 0) {
+                ovs_fatal(0, "value %s on -t or --timeout is not at least 1",
+                          optarg);
+            } else {
+                time_alarm(timeout);
+            }
+            break;
+
+        case 'h':
+            test_usage(commands);
+
+        case 'v':
+            vlog_set_verbosity(optarg);
+            break;
+
+        case '?':
+            exit(EXIT_FAILURE);
+
+        default:
+            abort();
+        }
+    }
+    free(short_options);
+}
+
diff --git a/tests/test-command-line.h b/tests/test-command-line.h
new file mode 100644 (file)
index 0000000..908ff76
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010 Nicira Networks.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TEST_COMMAND_LINE_H
+#define TEST_COMMAND_LINE_H 1
+
+/* Utilities for command-line parsing for test utilities. */
+
+#include "compiler.h"
+
+struct command;
+
+void parse_test_options(int argc, char *argv[], const struct command *);
+
+#endif /* command-line.h */
index f4e80ca..5699e3c 100644 (file)
@@ -38,6 +38,7 @@ m4_define([OVS_WAIT_WHILE], [OVS_WAIT([if $1; then :; else exit 0; fi], [$2])])
 m4_include([tests/ovsdb-macros.at])
 
 m4_include([tests/library.at])
+m4_include([tests/classifier.at])
 m4_include([tests/check-structs.at])
 m4_include([tests/daemon.at])
 m4_include([tests/vconn.at])