]> git.proxmox.com Git - mirror_ovs.git/blob - tests/test-jsonrpc.py
tests: Update interface-reconfigure tests.
[mirror_ovs.git] / tests / test-jsonrpc.py
1 # Copyright (c) 2009, 2010 Nicira Networks
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at:
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 import errno
16 import getopt
17 import os
18 import sys
19
20 import ovs.daemon
21 import ovs.json
22 import ovs.jsonrpc
23 import ovs.poller
24 import ovs.stream
25
26 def handle_rpc(rpc, msg):
27 done = False
28 reply = None
29
30 if msg.type == ovs.jsonrpc.Message.T_REQUEST:
31 if msg.method == "echo":
32 reply = ovs.jsonrpc.Message.create_reply(msg.params, msg.id)
33 else:
34 reply = ovs.jsonrpc.Message.create_error(
35 {"error": "unknown method"}, msg.id)
36 sys.stderr.write("unknown request %s" % msg.method)
37 elif msg.type == ovs.jsonrpc.Message.T_NOTIFY:
38 if msg.method == "shutdown":
39 done = True
40 else:
41 rpc.error(errno.ENOTTY)
42 sys.stderr.write("unknown notification %s" % msg.method)
43 else:
44 rpc.error(errno.EPROTO)
45 sys.stderr.write("unsolicited JSON-RPC reply or error\n")
46
47 if reply:
48 rpc.send(reply)
49 return done
50
51 def do_listen(name):
52 ovs.daemon.die_if_already_running()
53
54 error, pstream = ovs.stream.PassiveStream.open(name)
55 if error:
56 sys.stderr.write("could not listen on \"%s\": %s\n"
57 % (name, os.strerror(error)))
58 sys.exit(1)
59
60 ovs.daemon.daemonize()
61
62 rpcs = []
63 done = False
64 while True:
65 # Accept new connections.
66 error, stream = pstream.accept()
67 if stream:
68 rpcs.append(ovs.jsonrpc.Connection(stream))
69 elif error != errno.EAGAIN:
70 sys.stderr.write("PassiveStream.accept() failed\n")
71 sys.exit(1)
72
73 # Service existing connections.
74 dead_rpcs = []
75 for rpc in rpcs:
76 rpc.run()
77
78 error = 0
79 if not rpc.get_backlog():
80 error, msg = rpc.recv()
81 if not error:
82 if handle_rpc(rpc, msg):
83 done = True
84
85 error = rpc.get_status()
86 if error:
87 rpc.close()
88 dead_rpcs.append(rpc)
89 rpcs = [rpc for rpc in rpcs if not rpc in dead_rpcs]
90
91 if done and not rpcs:
92 break
93
94 poller = ovs.poller.Poller()
95 pstream.wait(poller)
96 for rpc in rpcs:
97 rpc.wait(poller)
98 if not rpc.get_backlog():
99 rpc.recv_wait(poller)
100 poller.block()
101 pstream.close()
102
103 def do_request(name, method, params_string):
104 params = ovs.json.from_string(params_string)
105 msg = ovs.jsonrpc.Message.create_request(method, params)
106 s = msg.is_valid()
107 if s:
108 sys.stderr.write("not a valid JSON-RPC request: %s\n" % s)
109 sys.exit(1)
110
111 error, stream = ovs.stream.Stream.open_block(ovs.stream.Stream.open(name))
112 if error:
113 sys.stderr.write("could not open \"%s\": %s\n"
114 % (name, os.strerror(error)))
115 sys.exit(1)
116
117 rpc = ovs.jsonrpc.Connection(stream)
118
119 error = rpc.send(msg)
120 if error:
121 sys.stderr.write("could not send request: %s\n" % os.strerror(error))
122 sys.exit(1)
123
124 error, msg = rpc.recv_block()
125 if error:
126 sys.stderr.write("error waiting for reply: %s\n" % os.strerror(error))
127 sys.exit(1)
128
129 print ovs.json.to_string(msg.to_json())
130
131 rpc.close()
132
133 def do_notify(name, method, params_string):
134 params = ovs.json.from_string(params_string)
135 msg = ovs.jsonrpc.Message.create_notify(method, params)
136 s = msg.is_valid()
137 if s:
138 sys.stderr.write("not a valid JSON-RPC notification: %s\n" % s)
139 sys.exit(1)
140
141 error, stream = ovs.stream.Stream.open_block(ovs.stream.Stream.open(name))
142 if error:
143 sys.stderr.write("could not open \"%s\": %s\n"
144 % (name, os.strerror(error)))
145 sys.exit(1)
146
147 rpc = ovs.jsonrpc.Connection(stream)
148
149 error = rpc.send_block(msg)
150 if error:
151 sys.stderr.write("could not send notification: %s\n"
152 % os.strerror(error))
153 sys.exit(1)
154
155 rpc.close()
156
157 def main(argv):
158 try:
159 options, args = getopt.gnu_getopt(
160 argv[1:], 'h', ["help"] + ovs.daemon.LONG_OPTIONS)
161 except getopt.GetoptError, geo:
162 sys.stderr.write("%s: %s\n" % (ovs.util.PROGRAM_NAME, geo.msg))
163 sys.exit(1)
164
165 for key, value in options:
166 if key in ['h', '--help']:
167 usage()
168 elif not ovs.daemon.parse_opt(key, value):
169 sys.stderr.write("%s: unhandled option %s\n"
170 % (ovs.util.PROGRAM_NAME, key))
171 sys.exit(1)
172
173 commands = {"listen": (do_listen, 1),
174 "request": (do_request, 3),
175 "notify": (do_notify, 3),
176 "help": (usage, (0,))}
177
178 command_name = args[0]
179 args = args[1:]
180 if not command_name in commands:
181 sys.stderr.write("%s: unknown command \"%s\" "
182 "(use --help for help)\n" % (argv0, command_name))
183 sys.exit(1)
184
185 func, n_args = commands[command_name]
186 if type(n_args) == tuple:
187 if len(args) < n_args[0]:
188 sys.stderr.write("%s: \"%s\" requires at least %d arguments but "
189 "only %d provided\n"
190 % (argv0, command_name, n_args, len(args)))
191 sys.exit(1)
192 elif type(n_args) == int:
193 if len(args) != n_args:
194 sys.stderr.write("%s: \"%s\" requires %d arguments but %d "
195 "provided\n"
196 % (argv0, command_name, n_args, len(args)))
197 sys.exit(1)
198 else:
199 assert False
200
201 func(*args)
202
203 def usage():
204 sys.stdout.write("""\
205 %s: JSON-RPC test utility for Python
206 usage: %s [OPTIONS] COMMAND [ARG...]
207 listen LOCAL listen for connections on LOCAL
208 request REMOTE METHOD PARAMS send request, print reply
209 notify REMOTE METHOD PARAMS send notification and exit
210 """ % (ovs.util.PROGRAM_NAME, ovs.util.PROGRAM_NAME))
211 ovs.stream.usage("JSON-RPC", True, True, True)
212 ovs.daemon.usage()
213 sys.stdout.write("""
214 Other options:
215 -h, --help display this help message
216 """)
217 sys.exit(0)
218
219 if __name__ == '__main__':
220 main(sys.argv)
221