ovs-test: A new tool that allows to diagnose connectivity and performance issues
[openvswitch] / python / ovstest / rpcserver.py
1 # Copyright (c) 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 """
16 rpcserver is an XML RPC server that allows RPC client to initiate tests
17 """
18
19 from twisted.internet import reactor
20 from twisted.web import xmlrpc, server
21 from twisted.internet.error import CannotListenError
22 import udp
23 import tcp
24 import args
25 import util
26
27
28 class TestArena(xmlrpc.XMLRPC):
29     """
30     This class contains all the functions that ovstest will call
31     remotely. The caller is responsible to use designated handleIds
32     for designated methods (e.g. do not mix UDP and TCP handles).
33     """
34
35     def __init__(self):
36         xmlrpc.XMLRPC.__init__(self)
37         self.handle_id = 1
38         self.handle_map = {}
39
40     def __acquire_handle(self, value):
41         """
42         Allocates new handle and assigns value object to it
43         """
44         handle = self.handle_id
45         self.handle_map[handle] = value
46         self.handle_id += 1
47         return handle
48
49     def __get_handle_resources(self, handle):
50         """
51         Return resources that were assigned to handle
52         """
53         return self.handle_map[handle]
54
55     def __delete_handle(self, handle):
56         """
57         Releases handle from handle_map
58         """
59         del self.handle_map[handle]
60
61
62     def xmlrpc_create_udp_listener(self, port):
63         """
64         Creates a UDP listener that will receive packets from UDP sender
65         """
66         try:
67             listener = udp.UdpListener()
68             reactor.listenUDP(port, listener)
69             handle_id = self.__acquire_handle(listener)
70         except CannotListenError:
71             return -1
72         return handle_id
73
74     def xmlrpc_create_udp_sender(self, host, count, size, duration):
75         """
76         Send UDP datagrams to UDP listener
77         """
78         sender = udp.UdpSender(tuple(host), count, size, duration)
79         reactor.listenUDP(0, sender)
80         handle_id = self.__acquire_handle(sender)
81         return handle_id
82
83     def xmlrpc_get_udp_listener_results(self, handle):
84         """
85         Returns number of datagrams that were received
86         """
87         listener = self.__get_handle_resources(handle)
88         return listener.getResults()
89
90     def xmlrpc_get_udp_sender_results(self, handle):
91         """
92         Returns number of datagrams that were sent
93         """
94         sender = self.__get_handle_resources(handle)
95         return sender.getResults()
96
97     def xmlrpc_close_udp_listener(self, handle):
98         """
99         Releases UdpListener and all its resources
100         """
101         listener = self.__get_handle_resources(handle)
102         listener.transport.stopListening()
103         self.__delete_handle(handle)
104         return 0
105
106     def xmlrpc_close_udp_sender(self, handle):
107         """
108         Releases UdpSender and all its resources
109         """
110         sender = self.__get_handle_resources(handle)
111         sender.transport.stopListening()
112         self.__delete_handle(handle)
113         return 0
114
115     def xmlrpc_create_tcp_listener(self, port):
116         """
117         Creates a TcpListener that will accept connection from TcpSender
118         """
119         try:
120             listener = tcp.TcpListenerFactory()
121             port = reactor.listenTCP(port, listener)
122             handle_id = self.__acquire_handle((listener, port))
123             return handle_id
124         except CannotListenError:
125             return -1
126
127     def xmlrpc_create_tcp_sender(self, his_ip, his_port, duration):
128         """
129         Creates a TcpSender that will connect to TcpListener
130         """
131         sender = tcp.TcpSenderFactory(duration)
132         connector = reactor.connectTCP(his_ip, his_port, sender)
133         handle_id = self.__acquire_handle((sender, connector))
134         return handle_id
135
136     def xmlrpc_get_tcp_listener_results(self, handle):
137         """
138         Returns number of bytes received
139         """
140         (listener, _) = self.__get_handle_resources(handle)
141         return listener.getResults()
142
143     def xmlrpc_get_tcp_sender_results(self, handle):
144         """
145         Returns number of bytes sent
146         """
147         (sender, _) = self.__get_handle_resources(handle)
148         return sender.getResults()
149
150     def xmlrpc_close_tcp_listener(self, handle):
151         """
152         Releases TcpListener and all its resources
153         """
154         try:
155             (_, port) = self.__get_handle_resources(handle)
156             port.loseConnection()
157             self.__delete_handle(handle)
158         except exceptions.KeyError:
159             return -1
160         return 0
161
162     def xmlrpc_close_tcp_sender(self, handle):
163         """
164         Releases TcpSender and all its resources
165         """
166         try:
167             (_, connector) = self.__get_handle_resources(handle)
168             connector.disconnect()
169             self.__delete_handle(handle)
170         except exceptions.KeyError:
171             return -1
172         return 0
173
174
175     def xmlrpc_get_interface(self, address):
176         """
177         Finds first interface that has given address
178         """
179         return util.get_interface(address)
180
181     def xmlrpc_get_interface_mtu(self, iface):
182         """
183         Returns MTU of the given interface
184         """
185         return util.get_interface_mtu(iface)
186
187     def xmlrpc_uname(self):
188         """
189         Return information about running kernel
190         """
191         return util.uname()
192
193     def xmlrpc_get_driver(self, iface):
194         """
195         Returns driver version
196         """
197         return util.get_driver(iface)
198
199
200 def start_rpc_server(port):
201     RPC_SERVER = TestArena()
202     reactor.listenTCP(port, server.Site(RPC_SERVER))
203     reactor.run()