vlog: Make vlog initialize itself when necessary.
[sliver-openvswitch.git] / tests / test-reconnect.c
1 /*
2  * Copyright (c) 2009, 2010 Nicira Networks.
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"
30 #include "vlog.h"
31
32 static struct reconnect *reconnect;
33 static int now;
34
35 static const struct command commands[];
36
37 static void diff_stats(const struct reconnect_stats *old,
38                        const struct reconnect_stats *new);
39
40 int
41 main(void)
42 {
43     struct reconnect_stats prev;
44     unsigned int old_max_tries;
45     int old_time;
46     char line[128];
47
48     vlog_set_levels(VLM_reconnect, VLF_ANY_FACILITY, VLL_EMER);
49
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;
56     old_max_tries = reconnect_get_max_tries(reconnect);
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)) {
70             run_command(args.n, args.names, commands);
71         }
72         svec_destroy(&args);
73
74         if (old_time != now) {
75             printf("\n### t=%d ###\n", now);
76             old_time = now;
77         }
78
79         reconnect_get_stats(reconnect, now, &cur);
80         diff_stats(&prev, &cur);
81         prev = cur;
82         if (reconnect_get_max_tries(reconnect) != old_max_tries) {
83             old_max_tries = reconnect_get_max_tries(reconnect);
84             printf("  %u tries left\n", old_max_tries);
85         }
86     }
87
88     return 0;
89 }
90
91 static void
92 do_enable(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
93 {
94     reconnect_enable(reconnect, now);
95 }
96
97 static void
98 do_disable(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
99 {
100     reconnect_disable(reconnect, now);
101 }
102
103 static void
104 do_force_reconnect(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
105 {
106     reconnect_force_reconnect(reconnect, now);
107 }
108
109 static int
110 error_from_string(const char *s)
111 {
112     if (!s) {
113         return 0;
114     } else if (!strcmp(s, "ECONNREFUSED")) {
115         return ECONNREFUSED;
116     } else if (!strcmp(s, "EOF")) {
117         return EOF;
118     } else {
119         ovs_fatal(0, "unknown error '%s'", s);
120     }
121 }
122
123 static void
124 do_disconnected(int argc OVS_UNUSED, char *argv[])
125 {
126     reconnect_disconnected(reconnect, now, error_from_string(argv[1]));
127 }
128
129 static void
130 do_connecting(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
131 {
132     reconnect_connecting(reconnect, now);
133 }
134
135 static void
136 do_connect_failed(int argc OVS_UNUSED, char *argv[])
137 {
138     reconnect_connect_failed(reconnect, now, error_from_string(argv[1]));
139 }
140
141 static void
142 do_connected(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
143 {
144     reconnect_connected(reconnect, now);
145 }
146
147 static void
148 do_received(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
149 {
150     reconnect_received(reconnect, now);
151 }
152
153 static void
154 do_run(int argc, char *argv[])
155 {
156     enum reconnect_action action;
157
158     if (argc > 1) {
159         now += atoi(argv[1]);
160     }
161
162     action = reconnect_run(reconnect, now);
163     switch (action) {
164     default:
165         if (action != 0) {
166             NOT_REACHED();
167         }
168         break;
169
170     case RECONNECT_CONNECT:
171         printf("  should connect\n");
172         break;
173
174     case RECONNECT_DISCONNECT:
175         printf("  should disconnect\n");
176         break;
177
178     case RECONNECT_PROBE:
179         printf("  should send probe\n");
180         break;
181     }
182 }
183
184 static void
185 do_advance(int argc OVS_UNUSED, char *argv[])
186 {
187     now += atoi(argv[1]);
188 }
189
190 static void
191 do_timeout(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
192 {
193     int timeout = reconnect_timeout(reconnect, now);
194     if (timeout >= 0) {
195         printf("  advance %d ms\n", timeout);
196         now += timeout;
197     } else {
198         printf("  no timeout\n");
199     }
200 }
201
202 static void
203 do_set_max_tries(int argc OVS_UNUSED, char *argv[])
204 {
205     reconnect_set_max_tries(reconnect, atoi(argv[1]));
206 }
207
208 static void
209 diff_stats(const struct reconnect_stats *old,
210            const struct reconnect_stats *new)
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
219         || old->last_received != new->last_received
220         || old->last_connected != new->last_connected) {
221         printf("  created %lld, last received %lld, last connected %lld\n",
222                new->creation_time, new->last_received, new->last_connected);
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     }
231     if (old->is_connected != new->is_connected
232         || old->current_connection_duration != new->current_connection_duration
233         || old->total_connected_duration != new->total_connected_duration) {
234         printf("  %sconnected (%u ms), total %u ms connected\n",
235                new->is_connected ? "" : "not ",
236                new->current_connection_duration,
237                new->total_connected_duration);
238     }
239 }
240
241 static void
242 do_set_passive(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
243 {
244     reconnect_set_passive(reconnect, true, now);
245 }
246
247 static void
248 do_listening(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
249 {
250     reconnect_listening(reconnect, now);
251 }
252
253 static void
254 do_listen_error(int argc OVS_UNUSED, char *argv[])
255 {
256     reconnect_listen_error(reconnect, now, atoi(argv[1]));
257 }
258
259 static const struct command commands[] = {
260     { "enable", 0, 0, do_enable },
261     { "disable", 0, 0, do_disable },
262     { "force-reconnect", 0, 0, do_force_reconnect },
263     { "disconnected", 0, 1, do_disconnected },
264     { "connecting", 0, 0, do_connecting },
265     { "connect-failed", 0, 1, do_connect_failed },
266     { "connected", 0, 0, do_connected },
267     { "received", 0, 0, do_received },
268     { "run", 0, 1, do_run },
269     { "advance", 1, 1, do_advance },
270     { "timeout", 0, 0, do_timeout },
271     { "set-max-tries", 1, 1, do_set_max_tries },
272     { "passive", 0, 0, do_set_passive },
273     { "listening", 0, 0, do_listening },
274     { "listen-error", 1, 1, do_listen_error },
275     { NULL, 0, 0, NULL },
276 };
277