summaryrefslogtreecommitdiff
path: root/tests/test-reconnect.py
blob: cea48eb5279d5f1a058b19eed65d718de1a6872d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# Copyright (c) 2009, 2010, 2012 Nicira, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import errno
import sys

import ovs.reconnect

now = 0
r = None


def do_enable(_):
    r.enable(now)


def do_disable(_):
    r.disable(now)


def do_force_reconnect(_):
    r.force_reconnect(now)


def error_from_string(s):
    if not s:
        return 0
    elif s == "ECONNREFUSED":
        return errno.ECONNREFUSED
    elif s == "EOF":
        return ovs.reconnect.EOF
    else:
        sys.stderr.write("unknown error '%s'\n" % s)
        sys.exit(1)


def do_disconnected(arg):
    r.disconnected(now, error_from_string(arg))


def do_connecting(_):
    r.connecting(now)


def do_connect_failed(arg):
    r.connect_failed(now, error_from_string(arg))


def do_connected(_):
    r.connected(now)


def do_activity(_):
    r.activity(now)


def do_run(arg):
    global now
    if arg is not None:
        now += int(arg)

    action = r.run(now)
    if action is None:
        pass
    elif action == ovs.reconnect.CONNECT:
        print("  should connect")
    elif action == ovs.reconnect.DISCONNECT:
        print("  should disconnect")
    elif action == ovs.reconnect.PROBE:
        print("  should send probe")
    else:
        assert False


def do_advance(arg):
    global now
    now += int(arg)


def do_timeout(_):
    global now
    timeout = r.timeout(now)
    if timeout is not None and timeout >= 0:
        print("  advance %d ms" % timeout)
        now += timeout
    else:
        print("  no timeout")


def do_set_max_tries(arg):
    r.set_max_tries(int(arg))


def do_set_backoff_free_tries(arg):
    r.set_backoff_free_tries(int(arg))


def diff_stats(old, new, delta):
    if (old.state != new.state or
        old.state_elapsed != new.state_elapsed or
        old.backoff != new.backoff):
        print("  in %s for %d ms (%d ms backoff)"
              % (new.state, new.state_elapsed, new.backoff))

    if (old.creation_time != new.creation_time or
        old.last_activity != new.last_activity or
        old.last_connected != new.last_connected):
        print("  created %d, last activity %d, last connected %d"
              % (new.creation_time, new.last_activity, new.last_connected))

    if (old.n_successful_connections != new.n_successful_connections or
        old.n_attempted_connections != new.n_attempted_connections or
        old.seqno != new.seqno):
        print("  %d successful connections out of %d attempts, seqno %d"
              % (new.n_successful_connections, new.n_attempted_connections,
                 new.seqno))

    if (old.is_connected != new.is_connected):
        if new.is_connected:
            negate = ""
        else:
            negate = "dis"
        print("  %sconnected" % negate)

    if (old.last_connected != new.last_connected or
        (new.msec_since_connect is not None and
         old.msec_since_connect != new.msec_since_connect - delta) or
        (old.total_connected_duration != new.total_connected_duration - delta
            and not (old.total_connected_duration == 0 and
                new.total_connected_duration == 0))):
        print("  last connected %d ms ago, connected %d ms total"
              % (new.msec_since_connect, new.total_connected_duration))

    if (old.last_disconnected != new.last_disconnected or
        (new.msec_since_disconnect is not None and
         old.msec_since_disconnect != new.msec_since_disconnect - delta)):
        print("  disconnected at %d ms (%d ms ago)"
              % (new.last_disconnected, new.msec_since_disconnect))


def do_set_passive(_):
    r.set_passive(True, now)


def do_listening(_):
    r.listening(now)


def do_listen_error(arg):
    r.listen_error(now, int(arg))


def do_receive_attempted(arg):
    if arg == "now":
        r.receive_attempted(now)
    elif arg == "LLONG_MAX":
        r.receive_attempted(None)
    else:
        sys.stderr.write("receive-attempted: bad argument %s\n" % arg)
        sys.exit(1)


def main():
    commands = {
        "enable": do_enable,
        "disable": do_disable,
        "force-reconnect": do_force_reconnect,
        "disconnected": do_disconnected,
        "connecting": do_connecting,
        "connect-failed": do_connect_failed,
        "connected": do_connected,
        "activity": do_activity,
        "run": do_run,
        "advance": do_advance,
        "timeout": do_timeout,
        "set-max-tries": do_set_max_tries,
        "set-backoff-free-tries": do_set_backoff_free_tries,
        "passive": do_set_passive,
        "listening": do_listening,
        "listen-error": do_listen_error,
        "receive-attempted": do_receive_attempted
    }

    global now
    global r

    now = 1000
    r = ovs.reconnect.Reconnect(now)
    r.set_name("remote")
    prev = r.get_stats(now)
    print("### t=%d ###" % now)
    old_time = now
    old_max_tries = r.get_max_tries()
    while True:
        line = sys.stdin.readline()
        if line == "":
            break

        print(line[:-1])
        if line[0] == "#":
            continue

        args = line.split()
        if len(args) == 0:
            continue

        command = args[0]
        if len(args) > 1:
            op = args[1]
        else:
            op = None
        commands[command](op)

        if old_time != now:
            print()
            print("### t=%d ###" % now)

        cur = r.get_stats(now)
        diff_stats(prev, cur, now - old_time)
        prev = cur
        if r.get_max_tries() != old_max_tries:
            old_max_tries = r.get_max_tries()
            print("  %d tries left" % old_max_tries)

        old_time = now


if __name__ == '__main__':
    main()