]> git.proxmox.com Git - mirror_ovs.git/blob - tests/test-jsonrpc.py
python: Resolve a deprecation warning.
[mirror_ovs.git] / tests / test-jsonrpc.py
1 # Copyright (c) 2009, 2010, 2011 Nicira, Inc.
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 argparse
16 import errno
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
27 def handle_rpc(rpc, msg):
28 done = False
29 reply = None
30
31 if msg.type == ovs.jsonrpc.Message.T_REQUEST:
32 if msg.method == "echo":
33 reply = ovs.jsonrpc.Message.create_reply(msg.params, msg.id)
34 else:
35 reply = ovs.jsonrpc.Message.create_error(
36 {"error": "unknown method"}, msg.id)
37 sys.stderr.write("unknown request %s" % msg.method)
38 elif msg.type == ovs.jsonrpc.Message.T_NOTIFY:
39 if msg.method == "shutdown":
40 done = True
41 else:
42 rpc.error(errno.ENOTTY)
43 sys.stderr.write("unknown notification %s" % msg.method)
44 else:
45 rpc.error(errno.EPROTO)
46 sys.stderr.write("unsolicited JSON-RPC reply or error\n")
47
48 if reply:
49 rpc.send(reply)
50 return done
51
52
53 def do_listen(name):
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 rpc not 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
104 def do_request(name, method, params_string):
105 params = ovs.json.from_string(params_string)
106 msg = ovs.jsonrpc.Message.create_request(method, params)
107 s = msg.is_valid()
108 if s:
109 sys.stderr.write("not a valid JSON-RPC request: %s\n" % s)
110 sys.exit(1)
111
112 error, stream = ovs.stream.Stream.open_block(ovs.stream.Stream.open(name))
113 if error:
114 sys.stderr.write("could not open \"%s\": %s\n"
115 % (name, os.strerror(error)))
116 sys.exit(1)
117
118 rpc = ovs.jsonrpc.Connection(stream)
119
120 error = rpc.send(msg)
121 if error:
122 sys.stderr.write("could not send request: %s\n" % os.strerror(error))
123 sys.exit(1)
124
125 error, msg = rpc.recv_block()
126 if error:
127 sys.stderr.write("error waiting for reply: %s\n" % os.strerror(error))
128 sys.exit(1)
129
130 print ovs.json.to_string(msg.to_json())
131
132 rpc.close()
133
134
135 def do_notify(name, method, params_string):
136 params = ovs.json.from_string(params_string)
137 msg = ovs.jsonrpc.Message.create_notify(method, params)
138 s = msg.is_valid()
139 if s:
140 sys.stderr.write("not a valid JSON-RPC notification: %s\n" % s)
141 sys.exit(1)
142
143 error, stream = ovs.stream.Stream.open_block(ovs.stream.Stream.open(name))
144 if error:
145 sys.stderr.write("could not open \"%s\": %s\n"
146 % (name, os.strerror(error)))
147 sys.exit(1)
148
149 rpc = ovs.jsonrpc.Connection(stream)
150
151 error = rpc.send_block(msg)
152 if error:
153 sys.stderr.write("could not send notification: %s\n"
154 % os.strerror(error))
155 sys.exit(1)
156
157 rpc.close()
158
159
160 def main(argv):
161
162 parser = argparse.ArgumentParser(
163 description="JSON-RPC test utility for Python.",
164 formatter_class=argparse.RawDescriptionHelpFormatter)
165
166 commands = {"listen": (do_listen, 1),
167 "request": (do_request, 3),
168 "notify": (do_notify, 3),
169 "help": (parser.print_help, (0,))}
170
171 group_description = """\
172 listen LOCAL listen for connections on LOCAL
173 request REMOTE METHOD PARAMS send request, print reply
174 notify REMOTE METHOD PARAMS send notification and exit
175 """ + ovs.stream.usage("JSON-RPC")
176
177 group = parser.add_argument_group(title="Commands",
178 description=group_description)
179 group.add_argument('command', metavar="COMMAND", nargs=1,
180 choices=commands, help="Command to use.")
181 group.add_argument('command_args', metavar="ARG", nargs='*',
182 help="Arguments to COMMAND.")
183
184 ovs.daemon.add_args(parser)
185 args = parser.parse_args()
186 ovs.daemon.handle_args(args)
187
188 command_name = args.command[0]
189 args = args.command_args
190 if command_name not in commands:
191 sys.stderr.write("%s: unknown command \"%s\" "
192 "(use --help for help)\n" % (argv[0], command_name))
193 sys.exit(1)
194
195 func, n_args = commands[command_name]
196 if type(n_args) == tuple:
197 if len(args) < n_args[0]:
198 sys.stderr.write("%s: \"%s\" requires at least %d arguments but "
199 "only %d provided\n"
200 % (argv[0], command_name, n_args, len(args)))
201 sys.exit(1)
202 elif type(n_args) == int:
203 if len(args) != n_args:
204 sys.stderr.write("%s: \"%s\" requires %d arguments but %d "
205 "provided\n"
206 % (argv[0], command_name, n_args, len(args)))
207 sys.exit(1)
208 else:
209 assert False
210
211 func(*args)
212
213
214 if __name__ == '__main__':
215 main(sys.argv)