]> git.proxmox.com Git - ovs.git/blob - tests/test-multipath.c
raft: Fix the problem of stuck in candidate role forever.
[ovs.git] / tests / test-multipath.c
1 /*
2 * Copyright (c) 2010, 2012, 2013, 2014 Nicira, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <config.h>
18 #undef NDEBUG
19 #include <assert.h>
20 #include <getopt.h>
21 #include <math.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include "flow.h"
25 #include "multipath.h"
26 #include "openvswitch/ofp-actions.h"
27 #include "ovstest.h"
28 #include "util.h"
29
30 static void
31 test_multipath_main(int argc, char *argv[])
32 {
33 enum { MP_MAX_LINKS = 63 };
34 struct ofpact_multipath mp;
35 bool ok = true;
36 char *error;
37 int n;
38
39 set_program_name(argv[0]);
40
41 if (argc != 2) {
42 ovs_fatal(0, "usage: %s multipath_action", program_name);
43 }
44
45 error = multipath_parse(&mp, argv[1]);
46 if (error) {
47 ovs_fatal(0, "%s", error);
48 }
49
50 for (n = 1; n <= MP_MAX_LINKS; n++) {
51 enum { N_FLOWS = 65536 };
52 double disruption, perfect, distribution;
53 int histogram[MP_MAX_LINKS];
54 double sum_dev2, stddev;
55 int changed;
56 int i;
57
58 changed = 0;
59 memset(histogram, 0, sizeof histogram);
60 for (i = 0; i < N_FLOWS; i++) {
61 int old_link, new_link;
62 struct flow_wildcards wc;
63 struct flow flow;
64
65 flow_random_hash_fields(&flow);
66
67 mp.max_link = n - 1;
68 multipath_execute(&mp, &flow, &wc);
69 old_link = flow.regs[0];
70
71 mp.max_link = n;
72 multipath_execute(&mp, &flow, &wc);
73 new_link = flow.regs[0];
74
75 assert(old_link >= 0 && old_link < n);
76 assert(new_link >= 0 && new_link < n + 1);
77
78 histogram[old_link]++;
79 changed += old_link != new_link;
80 }
81
82 sum_dev2 = 0.0;
83 for (i = 0; i < n; i++) {
84 double mean = (double) N_FLOWS / n;
85 double deviation = histogram[i] - mean;
86
87 sum_dev2 += deviation * deviation;
88 }
89 stddev = sqrt(sum_dev2 / n);
90
91 disruption = (double) changed / N_FLOWS;
92 perfect = 1.0 / (n + 1);
93 distribution = stddev / ((double) N_FLOWS / n);
94 printf("%2d -> %2d: disruption=%.2f (perfect=%.2f); "
95 "stddev/expected=%.4f\n",
96 n, n + 1, disruption, perfect, distribution);
97
98 switch (mp.algorithm) {
99 case NX_MP_ALG_MODULO_N:
100 if (disruption < (n < 2 ? .25 : .5)) {
101 fprintf(stderr, "%d -> %d: disruption=%.2f < .5\n",
102 n, n + 1, disruption);
103 ok = false;
104 }
105 break;
106
107 case NX_MP_ALG_HASH_THRESHOLD:
108 if (disruption < .48 || disruption > .52) {
109 fprintf(stderr, "%d -> %d: disruption=%.2f not approximately "
110 ".5\n", n, n + 1, disruption);
111 ok = false;
112 }
113 break;
114
115 case NX_MP_ALG_ITER_HASH:
116 if (!(n & (n - 1))) {
117 break;
118 }
119 /* Fall through. */
120 case NX_MP_ALG_HRW:
121 if (fabs(disruption - perfect) >= .01) {
122 fprintf(stderr, "%d -> %d: disruption=%.5f differs from "
123 "perfect=%.5f by more than .01\n",
124 n, n + 1, disruption, perfect);
125 ok = false;
126 }
127 break;
128
129 default:
130 OVS_NOT_REACHED();
131 }
132 }
133
134 exit(ok ? 0 : 1);
135 }
136
137 OVSTEST_REGISTER("test-multipath", test_multipath_main);