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:
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
16 ovs test utility that allows to do tests between remote hosts
24 from ovstest import args, rpcserver
27 def 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"
33 return str(int(bwidth / 1000)) + "Kbps"
35 return str(int(bwidth)) + "bps"
38 def 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()
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]))
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],
55 print "Install ethtool on this host to get NIC driver information"
57 print "On this host %s has %s." % (interface_name, driver)
60 print "Unable to retrieve kernel information. Is this Linux?"
62 print "Running kernel %s." % uname
67 def 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]))
72 udpformat = '{0:>15} {1:>15} {2:>15} {3:>15} {4:>15}'
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")
80 for size in [8, sender_mtu - 100, sender_mtu - 28, sender_mtu]:
84 packetcnt = (tbwidth * duration) / size
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])
91 send_handle = server2.create_udp_sender(
92 (receiver[2], receiver[3]),
93 packetcnt, size, duration)
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)
99 rcv_packets = server1.get_udp_listener_results(listen_handle)
100 snt_packets = server2.get_udp_sender_results(send_handle)
102 loss = math.ceil(((snt_packets - rcv_packets) * 10000.0) /
104 bwidth = (rcv_packets * size) / duration
106 print udpformat.format(size, snt_packets, rcv_packets,
107 '%.2f%%' % loss, bandwidth_to_string(bwidth))
109 if listen_handle != -1:
110 server1.close_udp_listener(listen_handle)
111 if send_handle != -1:
112 server2.close_udp_sender(send_handle)
116 def 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]))
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")
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])
134 send_handle = server2.create_tcp_sender(receiver[2], receiver[3],
137 time.sleep(duration + 1)
139 rcv_bytes = long(server1.get_tcp_listener_results(listen_handle))
140 snt_bytes = long(server2.get_tcp_sender_results(send_handle))
142 bwidth = rcv_bytes / duration
144 print tcpformat.format(snt_bytes, rcv_bytes,
145 bandwidth_to_string(bwidth))
147 if listen_handle != -1:
148 server1.close_tcp_listener(listen_handle)
149 if send_handle != -1:
150 server2.close_tcp_sender(send_handle)
154 if __name__ == '__main__':
156 ovs_args = args.ovs_initialize_args()
158 if ovs_args.port is not None: # Start in server mode
159 print "Starting RPC server"
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
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
170 mtu_node1 = collect_information(node1)
171 mtu_node2 = collect_information(node2)
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:
180 print "Couldn't establish XMLRPC control channel"