]> git.proxmox.com Git - ovs.git/blame - utilities/ovs-test.in
ovs-test: A new tool that allows to diagnose connectivity and performance issues
[ovs.git] / utilities / ovs-test.in
CommitLineData
0be6140a
AA
1#! @PYTHON@
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"""
16ovs test utility that allows to do tests between remote hosts
17"""
18
19import twisted
20import xmlrpclib
21import time
22import socket
23import math
24from ovstest import args, rpcserver
25
26
27def bandwidth_to_string(bwidth):
28 """Convert bandwidth from long to string and add units"""
29 bwidth = bwidth * 8 # Convert back to bits/second
30 if bwidth >= 10000000:
31 return str(int(bwidth / 1000000)) + "Mbps"
32 elif bwidth > 10000:
33 return str(int(bwidth / 1000)) + "Kbps"
34 else:
35 return str(int(bwidth)) + "bps"
36
37
38def collect_information(node):
39 """Print information about hosts that will do testing"""
40 print "Node %s:%u " % (node[0], node[1])
41 server1 = xmlrpclib.Server("http://%s:%u/" % (node[0], node[1]))
42 interface_name = server1.get_interface(node[2])
43 uname = server1.uname()
44 mtu = 1500
45
46 if interface_name == "":
47 print ("Could not find interface that has %s IP address."
48 "Make sure that you specified correct Test IP." % (node[2]))
49 else:
50 mtu = server1.get_interface_mtu(interface_name)
51 driver = server1.get_driver(interface_name)
52 print "Will be using %s(%s) with MTU %u" % (interface_name, node[2],
53 mtu)
54 if driver == "":
55 print "Install ethtool on this host to get NIC driver information"
56 else:
57 print "On this host %s has %s." % (interface_name, driver)
58
59 if uname == "":
60 print "Unable to retrieve kernel information. Is this Linux?"
61 else:
62 print "Running kernel %s." % uname
63 print "\n"
64 return mtu
65
66
67def do_udp_tests(receiver, sender, tbwidth, duration, sender_mtu):
68 """Schedule UDP tests between receiver and sender"""
69 server1 = xmlrpclib.Server("http://%s:%u/" % (receiver[0], receiver[1]))
70 server2 = xmlrpclib.Server("http://%s:%u/" % (sender[0], sender[1]))
71
72 udpformat = '{0:>15} {1:>15} {2:>15} {3:>15} {4:>15}'
73
74 print ("UDP test from %s:%u to %s:%u with target bandwidth %s" %
75 (sender[0], sender[1], receiver[0], receiver[1],
76 bandwidth_to_string(tbwidth)))
77 print udpformat.format("Datagram Size", "Snt Datagrams", "Rcv Datagrams",
78 "Datagram Loss", "Bandwidth")
79
80 for size in [8, sender_mtu - 100, sender_mtu - 28, sender_mtu]:
81 listen_handle = -1
82 send_handle = -1
83 try:
84 packetcnt = (tbwidth * duration) / size
85
86 listen_handle = server1.create_udp_listener(receiver[3])
87 if listen_handle == -1:
88 print ("Server could not open UDP listening socket on port"
89 " %u. Try to restart the server.\n" % receiver[3])
90 return
91 send_handle = server2.create_udp_sender(
92 (receiver[2], receiver[3]),
93 packetcnt, size, duration)
94
95 #Using sleep here because there is no other synchronization source
96 #that would notify us when all sent packets were received
97 time.sleep(duration + 1)
98
99 rcv_packets = server1.get_udp_listener_results(listen_handle)
100 snt_packets = server2.get_udp_sender_results(send_handle)
101
102 loss = math.ceil(((snt_packets - rcv_packets) * 10000.0) /
103 snt_packets) / 100
104 bwidth = (rcv_packets * size) / duration
105
106 print udpformat.format(size, snt_packets, rcv_packets,
107 '%.2f%%' % loss, bandwidth_to_string(bwidth))
108 finally:
109 if listen_handle != -1:
110 server1.close_udp_listener(listen_handle)
111 if send_handle != -1:
112 server2.close_udp_sender(send_handle)
113 print "\n"
114
115
116def do_tcp_tests(receiver, sender, duration):
117 """Schedule TCP tests between receiver and sender"""
118 server1 = xmlrpclib.Server("http://%s:%u/" % (receiver[0], receiver[1]))
119 server2 = xmlrpclib.Server("http://%s:%u/" % (sender[0], sender[1]))
120
121 tcpformat = '{0:>15} {1:>15} {2:>15}'
122 print "TCP test from %s:%u to %s:%u (full speed)" % (sender[0], sender[1],
123 receiver[0], receiver[1])
124 print tcpformat.format("Snt Bytes", "Rcv Bytes", "Bandwidth")
125
126 listen_handle = -1
127 send_handle = -1
128 try:
129 listen_handle = server1.create_tcp_listener(receiver[3])
130 if listen_handle == -1:
131 print ("Server was unable to open TCP listening socket on port"
132 " %u. Try to restart the server.\n" % receiver[3])
133 return
134 send_handle = server2.create_tcp_sender(receiver[2], receiver[3],
135 duration)
136
137 time.sleep(duration + 1)
138
139 rcv_bytes = long(server1.get_tcp_listener_results(listen_handle))
140 snt_bytes = long(server2.get_tcp_sender_results(send_handle))
141
142 bwidth = rcv_bytes / duration
143
144 print tcpformat.format(snt_bytes, rcv_bytes,
145 bandwidth_to_string(bwidth))
146 finally:
147 if listen_handle != -1:
148 server1.close_tcp_listener(listen_handle)
149 if send_handle != -1:
150 server2.close_tcp_sender(send_handle)
151 print "\n"
152
153
154if __name__ == '__main__':
155 try:
156 ovs_args = args.ovs_initialize_args()
157
158 if ovs_args.port is not None: # Start in server mode
159 print "Starting RPC server"
160 try:
161 rpcserver.start_rpc_server(ovs_args.port)
162 except twisted.internet.error.CannotListenError:
163 print "Couldn't start XMLRPC server on port %u" % ovs_args.port
164
165 elif ovs_args.servers is not None: # Run in client mode
166 node1 = ovs_args.servers[0]
167 node2 = ovs_args.servers[1]
168 bandwidth = ovs_args.targetBandwidth
169
170 mtu_node1 = collect_information(node1)
171 mtu_node2 = collect_information(node2)
172
173 do_udp_tests(node1, node2, bandwidth, 5, mtu_node1)
174 do_udp_tests(node2, node1, bandwidth, 5, mtu_node2)
175 do_tcp_tests(node1, node2, 5)
176 do_tcp_tests(node2, node1, 5)
177 except KeyboardInterrupt:
178 pass
179 except socket.error:
180 print "Couldn't establish XMLRPC control channel"