]> git.proxmox.com Git - mirror_ovs.git/blob - tests/test-jsonrpc.py
tests: test-jsonrpc references nonexistent variable.
[mirror_ovs.git] / tests / test-jsonrpc.py
1 # Copyright (c) 2009, 2010, 2011 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 error, pstream = ovs.stream.PassiveStream.open(name)
53 if error:
54 sys.stderr.write("could not listen on \"%s\": %s\n"
55 % (name, os.strerror(error)))
56 sys.exit(1)
57
58 ovs.daemon.daemonize()
59
60 rpcs = []
61 done = False
62 while True:
63 # Accept new connections.
64 error, stream = pstream.accept()
65 if stream:
66 rpcs.append(ovs.jsonrpc.Connection(stream))
67 elif error != errno.EAGAIN:
68 sys.stderr.write("PassiveStream.accept() failed\n")
69 sys.exit(1)
70
71 # Service existing connections.
72 dead_rpcs = []
73 for rpc in rpcs:
74 rpc.run()
75
76 error = 0
77 if not rpc.get_backlog():
78 error, msg = rpc.recv()
79 if not error:
80 if handle_rpc(rpc, msg):
81 done = True
82
83 error = rpc.get_status()
84 if error:
85 rpc.close()
86 dead_rpcs.append(rpc)
87 rpcs = [rpc for rpc in rpcs if not rpc in dead_rpcs]
88
89 if done and not rpcs:
90 break
91
92 poller = ovs.poller.Poller()
93 pstream.wait(poller)
94 for rpc in rpcs:
95 rpc.wait(poller)
96 if not rpc.get_backlog():
97 rpc.recv_wait(poller)
98 poller.block()
99 pstream.close()
100
101 def do_request(name, method, params_string):
102 params = ovs.json.from_string(params_string)
103 msg = ovs.jsonrpc.Message.create_request(method, params)
104 s = msg.is_valid()
105 if s:
106 sys.stderr.write("not a valid JSON-RPC request: %s\n" % s)
107 sys.exit(1)
108
109 error, stream = ovs.stream.Stream.open_block(ovs.stream.Stream.open(name))
110 if error:
111 sys.stderr.write("could not open \"%s\": %s\n"
112 % (name, os.strerror(error)))
113 sys.exit(1)
114
115 rpc = ovs.jsonrpc.Connection(stream)
116
117 error = rpc.send(msg)
118 if error:
119 sys.stderr.write("could not send request: %s\n" % os.strerror(error))
120 sys.exit(1)
121
122 error, msg = rpc.recv_block()
123 if error:
124 sys.stderr.write("error waiting for reply: %s\n" % os.strerror(error))
125 sys.exit(1)
126
127 print ovs.json.to_string(msg.to_json())
128
129 rpc.close()
130
131 def do_notify(name, method, params_string):
132 params = ovs.json.from_string(params_string)
133 msg = ovs.jsonrpc.Message.create_notify(method, params)
134 s = msg.is_valid()
135 if s:
136 sys.stderr.write("not a valid JSON-RPC notification: %s\n" % s)
137 sys.exit(1)
138
139 error, stream = ovs.stream.Stream.open_block(ovs.stream.Stream.open(name))
140 if error:
141 sys.stderr.write("could not open \"%s\": %s\n"
142 % (name, os.strerror(error)))
143 sys.exit(1)
144
145 rpc = ovs.jsonrpc.Connection(stream)
146
147 error = rpc.send_block(msg)
148 if error:
149 sys.stderr.write("could not send notification: %s\n"
150 % os.strerror(error))
151 sys.exit(1)
152
153 rpc.close()
154
155 def main(argv):
156 try:
157 options, args = getopt.gnu_getopt(
158 argv[1:], 'h', ["help"] + ovs.daemon.LONG_OPTIONS)
159 except getopt.GetoptError, geo:
160 sys.stderr.write("%s: %s\n" % (ovs.util.PROGRAM_NAME, geo.msg))
161 sys.exit(1)
162
163 for key, value in options:
164 if key in ['h', '--help']:
165 usage()
166 elif not ovs.daemon.parse_opt(key, value):
167 sys.stderr.write("%s: unhandled option %s\n"
168 % (ovs.util.PROGRAM_NAME, key))
169 sys.exit(1)
170
171 commands = {"listen": (do_listen, 1),
172 "request": (do_request, 3),
173 "notify": (do_notify, 3),
174 "help": (usage, (0,))}
175
176 command_name = args[0]
177 args = args[1:]
178 if not command_name in commands:
179 sys.stderr.write("%s: unknown command \"%s\" "
180 "(use --help for help)\n" % (argv[0], command_name))
181 sys.exit(1)
182
183 func, n_args = commands[command_name]
184 if type(n_args) == tuple:
185 if len(args) < n_args[0]:
186 sys.stderr.write("%s: \"%s\" requires at least %d arguments but "
187 "only %d provided\n"
188 % (argv[0], command_name, n_args, len(args)))
189 sys.exit(1)
190 elif type(n_args) == int:
191 if len(args) != n_args:
192 sys.stderr.write("%s: \"%s\" requires %d arguments but %d "
193 "provided\n"
194 % (argv[0], command_name, n_args, len(args)))
195 sys.exit(1)
196 else:
197 assert False
198
199 func(*args)
200
201 def usage():
202 sys.stdout.write("""\
203 %s: JSON-RPC test utility for Python
204 usage: %s [OPTIONS] COMMAND [ARG...]
205 listen LOCAL listen for connections on LOCAL
206 request REMOTE METHOD PARAMS send request, print reply
207 notify REMOTE METHOD PARAMS send notification and exit
208 """ % (ovs.util.PROGRAM_NAME, ovs.util.PROGRAM_NAME))
209 ovs.stream.usage("JSON-RPC", True, True, True)
210 ovs.daemon.usage()
211 sys.stdout.write("""
212 Other options:
213 -h, --help display this help message
214 """)
215 sys.exit(0)
216
217 if __name__ == '__main__':
218 main(sys.argv)
219