]> git.proxmox.com Git - mirror_ovs.git/blame - tests/test-reconnect.c
classifier: Fix segfault iterating with rules that differ only in priority.
[mirror_ovs.git] / tests / test-reconnect.c
CommitLineData
3ed497fc 1/*
c69ee87c 2 * Copyright (c) 2009, 2010 Nicira Networks.
3ed497fc
BP
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 "reconnect.h"
20
21#include <errno.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include "command-line.h"
27#include "compiler.h"
28#include "svec.h"
29#include "util.h"
1e8cf0f7 30#include "vlog.h"
3ed497fc
BP
31
32static struct reconnect *reconnect;
33static int now;
34
35static const struct command commands[];
36
37static void diff_stats(const struct reconnect_stats *old,
38 const struct reconnect_stats *new);
39
40int
41main(void)
42{
480ce8ab 43 extern struct vlog_module VLM_reconnect;
3ed497fc 44 struct reconnect_stats prev;
a85c0bbc 45 unsigned int old_max_tries;
3ed497fc
BP
46 int old_time;
47 char line[128];
48
480ce8ab 49 vlog_set_levels(&VLM_reconnect, VLF_ANY_FACILITY, VLL_EMER);
1e8cf0f7 50
3ed497fc
BP
51 now = 1000;
52 reconnect = reconnect_create(now);
53 reconnect_set_name(reconnect, "remote");
54 reconnect_get_stats(reconnect, now, &prev);
55 printf("### t=%d ###\n", now);
56 old_time = now;
a85c0bbc 57 old_max_tries = reconnect_get_max_tries(reconnect);
3ed497fc
BP
58 while (fgets(line, sizeof line, stdin)) {
59 struct reconnect_stats cur;
60 struct svec args;
61
62 fputs(line, stdout);
63 if (line[0] == '#') {
64 continue;
65 }
66
67 svec_init(&args);
68 svec_parse_words(&args, line);
69 svec_terminate(&args);
70 if (!svec_is_empty(&args)) {
71 run_command(args.n, args.names, commands);
72 }
73 svec_destroy(&args);
74
75 if (old_time != now) {
76 printf("\n### t=%d ###\n", now);
77 old_time = now;
78 }
79
80 reconnect_get_stats(reconnect, now, &cur);
81 diff_stats(&prev, &cur);
82 prev = cur;
a85c0bbc
BP
83 if (reconnect_get_max_tries(reconnect) != old_max_tries) {
84 old_max_tries = reconnect_get_max_tries(reconnect);
85 printf(" %u tries left\n", old_max_tries);
86 }
3ed497fc
BP
87 }
88
89 return 0;
90}
91
92static void
c69ee87c 93do_enable(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
3ed497fc
BP
94{
95 reconnect_enable(reconnect, now);
96}
97
98static void
c69ee87c 99do_disable(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
3ed497fc
BP
100{
101 reconnect_disable(reconnect, now);
102}
103
104static void
c69ee87c 105do_force_reconnect(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
3ed497fc
BP
106{
107 reconnect_force_reconnect(reconnect, now);
108}
109
110static int
111error_from_string(const char *s)
112{
113 if (!s) {
114 return 0;
115 } else if (!strcmp(s, "ECONNREFUSED")) {
116 return ECONNREFUSED;
117 } else if (!strcmp(s, "EOF")) {
118 return EOF;
119 } else {
120 ovs_fatal(0, "unknown error '%s'", s);
121 }
122}
123
124static void
c69ee87c 125do_disconnected(int argc OVS_UNUSED, char *argv[])
3ed497fc
BP
126{
127 reconnect_disconnected(reconnect, now, error_from_string(argv[1]));
128}
129
130static void
c69ee87c 131do_connecting(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
3ed497fc
BP
132{
133 reconnect_connecting(reconnect, now);
134}
135
136static void
c69ee87c 137do_connect_failed(int argc OVS_UNUSED, char *argv[])
3ed497fc
BP
138{
139 reconnect_connect_failed(reconnect, now, error_from_string(argv[1]));
140}
141
142static void
c69ee87c 143do_connected(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
3ed497fc
BP
144{
145 reconnect_connected(reconnect, now);
146}
147
148static void
c69ee87c 149do_received(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
3ed497fc
BP
150{
151 reconnect_received(reconnect, now);
152}
153
154static void
155do_run(int argc, char *argv[])
156{
157 enum reconnect_action action;
158
159 if (argc > 1) {
160 now += atoi(argv[1]);
161 }
162
163 action = reconnect_run(reconnect, now);
164 switch (action) {
165 default:
166 if (action != 0) {
167 NOT_REACHED();
168 }
169 break;
170
171 case RECONNECT_CONNECT:
172 printf(" should connect\n");
173 break;
174
175 case RECONNECT_DISCONNECT:
176 printf(" should disconnect\n");
177 break;
178
179 case RECONNECT_PROBE:
180 printf(" should send probe\n");
181 break;
182 }
183}
184
185static void
c69ee87c 186do_advance(int argc OVS_UNUSED, char *argv[])
3ed497fc
BP
187{
188 now += atoi(argv[1]);
189}
190
191static void
c69ee87c 192do_timeout(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
3ed497fc
BP
193{
194 int timeout = reconnect_timeout(reconnect, now);
195 if (timeout >= 0) {
196 printf(" advance %d ms\n", timeout);
197 now += timeout;
198 } else {
199 printf(" no timeout\n");
200 }
201}
202
a85c0bbc 203static void
c69ee87c 204do_set_max_tries(int argc OVS_UNUSED, char *argv[])
a85c0bbc
BP
205{
206 reconnect_set_max_tries(reconnect, atoi(argv[1]));
207}
208
3ed497fc
BP
209static void
210diff_stats(const struct reconnect_stats *old,
211 const struct reconnect_stats *new)
212{
213 if (old->state != new->state
214 || old->state_elapsed != new->state_elapsed
215 || old->backoff != new->backoff) {
216 printf(" in %s for %u ms (%d ms backoff)\n",
217 new->state, new->state_elapsed, new->backoff);
218 }
219 if (old->creation_time != new->creation_time
220 || old->last_received != new->last_received
221 || old->last_connected != new->last_connected) {
222 printf(" created %lld, last received %lld, last connected %lld\n",
223 new->creation_time, new->last_received, new->last_connected);
224 }
225 if (old->n_successful_connections != new->n_successful_connections
226 || old->n_attempted_connections != new->n_attempted_connections
227 || old->seqno != new->seqno) {
228 printf(" %u successful connections out of %u attempts, seqno %u\n",
229 new->n_successful_connections, new->n_attempted_connections,
230 new->seqno);
231 }
232 if (old->is_connected != new->is_connected
233 || old->current_connection_duration != new->current_connection_duration
234 || old->total_connected_duration != new->total_connected_duration) {
235 printf(" %sconnected (%u ms), total %u ms connected\n",
236 new->is_connected ? "" : "not ",
237 new->current_connection_duration,
238 new->total_connected_duration);
239 }
240}
241
19df7f51
BP
242static void
243do_set_passive(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
244{
245 reconnect_set_passive(reconnect, true, now);
246}
247
248static void
249do_listening(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
250{
251 reconnect_listening(reconnect, now);
252}
253
254static void
255do_listen_error(int argc OVS_UNUSED, char *argv[])
256{
257 reconnect_listen_error(reconnect, now, atoi(argv[1]));
258}
259
3ed497fc
BP
260static const struct command commands[] = {
261 { "enable", 0, 0, do_enable },
262 { "disable", 0, 0, do_disable },
263 { "force-reconnect", 0, 0, do_force_reconnect },
264 { "disconnected", 0, 1, do_disconnected },
265 { "connecting", 0, 0, do_connecting },
266 { "connect-failed", 0, 1, do_connect_failed },
267 { "connected", 0, 0, do_connected },
268 { "received", 0, 0, do_received },
269 { "run", 0, 1, do_run },
270 { "advance", 1, 1, do_advance },
271 { "timeout", 0, 0, do_timeout },
a85c0bbc 272 { "set-max-tries", 1, 1, do_set_max_tries },
19df7f51
BP
273 { "passive", 0, 0, do_set_passive },
274 { "listening", 0, 0, do_listening },
275 { "listen-error", 1, 1, do_listen_error },
3ed497fc
BP
276 { NULL, 0, 0, NULL },
277};
278