Implement 802.1D Spanning Tree Protocol.
[sliver-openvswitch.git] / datapath / unit.c
1 /*
2  * Distributed under the terms of the GNU GPL version 2.
3  * Copyright (c) 2007, 2008 The Board of Trustees of The Leland 
4  * Stanford Junior University
5  */
6
7 #include <linux/autoconf.h>
8 #include <linux/init.h>
9 #include <linux/module.h>
10 #include <linux/string.h>
11 #include <linux/version.h>
12 #include <linux/errno.h>
13
14 #include "unit.h"
15
16 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
17 static char run[1024];
18 module_param_string(run, run, sizeof run, 0);
19 MODULE_PARM_DESC(run_tests, "run=\"test1,[test2,...]\"\n");
20 #else
21 static char *run;
22 MODULE_PARM(run, "s");
23 #endif
24
25 static int test_failed;
26 static const char *test_name;
27
28 void unit_fail_function(const char *function, const char *msg, ...) 
29 {
30         va_list args;
31
32         printk("%s: FAIL: %s: ", test_name, function);
33         va_start(args, msg);
34         vprintk(msg, args);
35         va_end(args);
36         printk("\n");
37         test_failed = 1;
38 }
39
40 int unit_failed(void) 
41 {
42         return test_failed;
43 }
44
45 static int run_test(const char *name, size_t len)
46 {
47         static const struct test {
48                 const char *name;
49                 void (*func)(void);
50         } tests[] = {
51 #define UNIT_TEST(NAME) {#NAME, run_##NAME},
52                 UNIT_TESTS
53 #undef UNIT_TEST
54         };
55
56         const struct test *p;
57
58         for (p = tests; p < &tests[ARRAY_SIZE(tests)]; p++)
59                 if (len == strlen(p->name)
60                         && !memcmp(name, p->name, len)) {
61                         test_name = p->name;
62                         test_failed = 0;
63                         p->func();
64                         printk("%s: %s\n", test_name,
65                                                 test_failed ? "FAIL" : "PASS");
66                         return !test_failed;
67                 }
68         printk("unknown unit test %.*s\n", (int) len, name);
69         return 0;
70 }
71
72 int unit_init(void)
73 {
74         int n_pass = 0, n_fail = 0;
75         char *p = run;
76
77         if (p == NULL) {
78                 p = "";
79         }
80         for (;;) {
81                 static const char white_space[] = " \t\r\n\v,";
82                 int len;
83
84                 p += strspn(p, white_space);
85                 if (!*p)
86                         break;
87
88                 len = strcspn(p, white_space);
89                 if (run_test(p, len))
90                         n_pass++;
91                 else
92                         n_fail++;
93                 p += len;
94         }
95
96         if (n_pass + n_fail == 0)
97                 printk("no tests specified (use run=\"test1 [test2...]\")\n");
98         else
99                 printk("%d tests passed, %d failed\n", n_pass, n_fail);
100
101         return -ENODEV;
102 }
103
104 module_init(unit_init);
105 MODULE_LICENSE("GPL");