2 * Copyright (c) 2010, 2012, 2013, 2014 Nicira, Inc.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "multipath.h"
28 #include "ofp-actions.h"
33 test_multipath_main(int argc, char *argv[])
35 enum { MP_MAX_LINKS = 63 };
36 struct ofpact_multipath mp;
41 set_program_name(argv[0]);
44 ovs_fatal(0, "usage: %s multipath_action", program_name);
47 error = multipath_parse(&mp, argv[1]);
49 ovs_fatal(0, "%s", error);
52 for (n = 1; n <= MP_MAX_LINKS; n++) {
53 enum { N_FLOWS = 65536 };
54 double disruption, perfect, distribution;
55 int histogram[MP_MAX_LINKS];
56 double sum_dev2, stddev;
61 memset(histogram, 0, sizeof histogram);
62 for (i = 0; i < N_FLOWS; i++) {
63 int old_link, new_link;
64 struct flow_wildcards wc;
67 flow_random_hash_fields(&flow);
70 multipath_execute(&mp, &flow, &wc);
71 old_link = flow.regs[0];
74 multipath_execute(&mp, &flow, &wc);
75 new_link = flow.regs[0];
77 assert(old_link >= 0 && old_link < n);
78 assert(new_link >= 0 && new_link < n + 1);
80 histogram[old_link]++;
81 changed += old_link != new_link;
85 for (i = 0; i < n; i++) {
86 double mean = (double) N_FLOWS / n;
87 double deviation = histogram[i] - mean;
89 sum_dev2 += deviation * deviation;
91 stddev = sqrt(sum_dev2 / n);
93 disruption = (double) changed / N_FLOWS;
94 perfect = 1.0 / (n + 1);
95 distribution = stddev / ((double) N_FLOWS / n);
96 printf("%2d -> %2d: disruption=%.2f (perfect=%.2f); "
97 "stddev/expected=%.4f\n",
98 n, n + 1, disruption, perfect, distribution);
100 switch (mp.algorithm) {
101 case NX_MP_ALG_MODULO_N:
102 if (disruption < (n < 2 ? .25 : .5)) {
103 fprintf(stderr, "%d -> %d: disruption=%.2f < .5\n",
104 n, n + 1, disruption);
109 case NX_MP_ALG_HASH_THRESHOLD:
110 if (disruption < .48 || disruption > .52) {
111 fprintf(stderr, "%d -> %d: disruption=%.2f not approximately "
112 ".5\n", n, n + 1, disruption);
117 case NX_MP_ALG_ITER_HASH:
118 if (!(n & (n - 1))) {
123 if (fabs(disruption - perfect) >= .01) {
124 fprintf(stderr, "%d -> %d: disruption=%.5f differs from "
125 "perfect=%.5f by more than .01\n",
126 n, n + 1, disruption, perfect);
139 OVSTEST_REGISTER("test-multipath", test_multipath_main);