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