]> git.proxmox.com Git - mirror_ovs.git/blob - tests/test-multipath.c
Introduce ofpacts, an abstraction of OpenFlow actions.
[mirror_ovs.git] / tests / test-multipath.c
1 /*
2 * Copyright (c) 2010, 2012 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
19 #include "multipath.h"
20
21 #include <assert.h>
22 #include <getopt.h>
23 #include <math.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26
27 #include "flow.h"
28 #include "ofp-actions.h"
29 #include "random.h"
30 #include "util.h"
31
32 int
33 main(int argc, char *argv[])
34 {
35 enum { MP_MAX_LINKS = 63 };
36 struct ofpact_multipath mp;
37 bool ok = true;
38 int n;
39
40 set_program_name(argv[0]);
41 random_init();
42
43 if (argc != 2) {
44 ovs_fatal(0, "usage: %s multipath_action", program_name);
45 }
46
47 multipath_parse(&mp, argv[1]);
48 for (n = 1; n <= MP_MAX_LINKS; n++) {
49 enum { N_FLOWS = 65536 };
50 double disruption, perfect, distribution;
51 int histogram[MP_MAX_LINKS];
52 double sum_dev2, stddev;
53 int changed;
54 int i;
55
56 changed = 0;
57 memset(histogram, 0, sizeof histogram);
58 for (i = 0; i < N_FLOWS; i++) {
59 int old_link, new_link;
60 struct flow flow;
61
62 random_bytes(&flow, sizeof flow);
63
64 mp.max_link = n - 1;
65 multipath_execute(&mp, &flow);
66 old_link = flow.regs[0];
67
68 mp.max_link = n;
69 multipath_execute(&mp, &flow);
70 new_link = flow.regs[0];
71
72 assert(old_link >= 0 && old_link < n);
73 assert(new_link >= 0 && new_link < n + 1);
74
75 histogram[old_link]++;
76 changed += old_link != new_link;
77 }
78
79 sum_dev2 = 0.0;
80 for (i = 0; i < n; i++) {
81 double mean = (double) N_FLOWS / n;
82 double deviation = histogram[i] - mean;
83
84 sum_dev2 += deviation * deviation;
85 }
86 stddev = sqrt(sum_dev2 / n);
87
88 disruption = (double) changed / N_FLOWS;
89 perfect = 1.0 / (n + 1);
90 distribution = stddev / ((double) N_FLOWS / n);
91 printf("%2d -> %2d: disruption=%.2f (perfect=%.2f); "
92 "stddev/expected=%.4f\n",
93 n, n + 1, disruption, perfect, distribution);
94
95 switch (mp.algorithm) {
96 case NX_MP_ALG_MODULO_N:
97 if (disruption < (n < 2 ? .25 : .5)) {
98 fprintf(stderr, "%d -> %d: disruption=%.2f < .5\n",
99 n, n + 1, disruption);
100 ok = false;
101 }
102 break;
103
104 case NX_MP_ALG_HASH_THRESHOLD:
105 if (disruption < .48 || disruption > .52) {
106 fprintf(stderr, "%d -> %d: disruption=%.2f not approximately "
107 ".5\n", n, n + 1, disruption);
108 ok = false;
109 }
110 break;
111
112 case NX_MP_ALG_ITER_HASH:
113 if (!(n & (n - 1))) {
114 break;
115 }
116 /* Fall through. */
117 case NX_MP_ALG_HRW:
118 if (fabs(disruption - perfect) >= .01) {
119 fprintf(stderr, "%d -> %d: disruption=%.5f differs from "
120 "perfect=%.5f by more than .01\n",
121 n, n + 1, disruption, perfect);
122 ok = false;
123 }
124 break;
125
126 default:
127 NOT_REACHED();
128 }
129 }
130
131 return ok ? 0 : 1;
132 }