ovs-l3ping: A new test utility that allows to detect L3 tunneling issues
[sliver-openvswitch.git] / python / ovstest / tests.py
1 import math
2 import time
3
4 import ovstest.util as util
5
6 DEFAULT_TEST_BRIDGE = "ovstestbr0"
7 DEFAULT_TEST_PORT = "ovstestport0"
8 DEFAULT_TEST_TUN = "ovstestport1"
9 NO_HANDLE = -1
10
11
12 def do_udp_tests(receiver, sender, tbwidth, duration, port_sizes):
13     """Schedule UDP tests between receiver and sender"""
14     server1 = util.rpc_client(receiver[0], receiver[1])
15     server2 = util.rpc_client(sender[0], sender[1])
16
17     udpformat = '{0:>15} {1:>15} {2:>15} {3:>15} {4:>15}'
18
19     print ("UDP test from %s:%u to %s:%u with target bandwidth %s" %
20                             (sender[0], sender[1], receiver[0], receiver[1],
21                              util.bandwidth_to_string(tbwidth)))
22     print udpformat.format("Datagram Size", "Snt Datagrams", "Rcv Datagrams",
23                             "Datagram Loss", "Bandwidth")
24
25     for size in port_sizes:
26         listen_handle = NO_HANDLE
27         send_handle = NO_HANDLE
28         try:
29             packetcnt = (tbwidth * duration) / size
30
31             listen_handle = server1.create_udp_listener(receiver[3])
32             if listen_handle == NO_HANDLE:
33                 print ("Server could not open UDP listening socket on port"
34                         " %u. Try to restart the server.\n" % receiver[3])
35                 return
36             send_handle = server2.create_udp_sender(
37                                             (util.ip_from_cidr(receiver[2]),
38                                              receiver[3]), packetcnt, size,
39                                              duration)
40
41             # Using sleep here because there is no other synchronization
42             # source that would notify us when all sent packets were received
43             time.sleep(duration + 1)
44
45             rcv_packets = server1.get_udp_listener_results(listen_handle)
46             snt_packets = server2.get_udp_sender_results(send_handle)
47
48             loss = math.ceil(((snt_packets - rcv_packets) * 10000.0) /
49                                                         snt_packets) / 100
50             bwidth = (rcv_packets * size) / duration
51
52             print udpformat.format(size, snt_packets, rcv_packets,
53                           '%.2f%%' % loss, util.bandwidth_to_string(bwidth))
54         finally:
55             if listen_handle != NO_HANDLE:
56                 server1.close_udp_listener(listen_handle)
57             if send_handle != NO_HANDLE:
58                 server2.close_udp_sender(send_handle)
59     print "\n"
60
61
62 def do_tcp_tests(receiver, sender, duration):
63     """Schedule TCP tests between receiver and sender"""
64     server1 = util.rpc_client(receiver[0], receiver[1])
65     server2 = util.rpc_client(sender[0], sender[1])
66
67     tcpformat = '{0:>15} {1:>15} {2:>15}'
68     print "TCP test from %s:%u to %s:%u (full speed)" % (sender[0], sender[1],
69                                                     receiver[0], receiver[1])
70     print tcpformat.format("Snt Bytes", "Rcv Bytes", "Bandwidth")
71
72     listen_handle = NO_HANDLE
73     send_handle = NO_HANDLE
74     try:
75         listen_handle = server1.create_tcp_listener(receiver[3])
76         if listen_handle == NO_HANDLE:
77             print ("Server was unable to open TCP listening socket on port"
78                     " %u. Try to restart the server.\n" % receiver[3])
79             return
80         send_handle = server2.create_tcp_sender(util.ip_from_cidr(receiver[2]),
81                                                 receiver[3], duration)
82
83         time.sleep(duration + 1)
84
85         rcv_bytes = long(server1.get_tcp_listener_results(listen_handle))
86         snt_bytes = long(server2.get_tcp_sender_results(send_handle))
87
88         bwidth = rcv_bytes / duration
89
90         print tcpformat.format(snt_bytes, rcv_bytes,
91                                util.bandwidth_to_string(bwidth))
92     finally:
93         if listen_handle != NO_HANDLE:
94             server1.close_tcp_listener(listen_handle)
95         if send_handle != NO_HANDLE:
96             server2.close_tcp_sender(send_handle)
97     print "\n"
98
99
100 def do_l3_tests(node1, node2, bandwidth, duration, ps, type):
101     """
102     Do L3 tunneling tests. Each node is given as 4 tuple - physical
103     interface IP, control port, test IP and test port.
104     """
105     server1 = util.rpc_client(node1[0], node1[1])
106     server2 = util.rpc_client(node2[0], node2[1])
107     servers_with_bridges = []
108     try:
109         server1.create_bridge(DEFAULT_TEST_BRIDGE)
110         servers_with_bridges.append(server1)
111         server2.create_bridge(DEFAULT_TEST_BRIDGE)
112         servers_with_bridges.append(server2)
113
114         server1.interface_up(DEFAULT_TEST_BRIDGE)
115         server2.interface_up(DEFAULT_TEST_BRIDGE)
116
117         server1.interface_assign_ip(DEFAULT_TEST_BRIDGE, node1[2], None)
118         server2.interface_assign_ip(DEFAULT_TEST_BRIDGE, node2[2], None)
119
120         server1.add_port_to_bridge(DEFAULT_TEST_BRIDGE, DEFAULT_TEST_TUN)
121         server2.add_port_to_bridge(DEFAULT_TEST_BRIDGE, DEFAULT_TEST_TUN)
122
123         server1.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "type",
124                               None, type)
125         server2.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "type",
126                               None, type)
127         server1.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "options",
128                               "remote_ip", node2[0])
129         server2.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "options",
130                               "remote_ip", node1[0])
131
132         do_udp_tests(node1, node2, bandwidth, duration, ps)
133         do_udp_tests(node2, node1, bandwidth, duration, ps)
134         do_tcp_tests(node1, node2, duration)
135         do_tcp_tests(node2, node1, duration)
136
137     finally:
138         for server in servers_with_bridges:
139             server.del_bridge(DEFAULT_TEST_BRIDGE)
140
141
142
143 def do_vlan_tests(node1, node2, bandwidth, duration, ps, tag):
144     """
145     Do VLAN tests between node1 and node2. Each node is given
146     as 4 tuple - physical interface IP, control port, test IP and
147     test port.
148     """
149     server1 = util.rpc_client(node1[0], node1[1])
150     server2 = util.rpc_client(node2[0], node2[1])
151
152     br_name1 = None
153     br_name2 = None
154
155     servers_with_test_ports = []
156
157     try:
158         interface_node1 = server1.get_interface(node1[0])
159         interface_node2 = server2.get_interface(node2[0])
160
161         if server1.is_ovs_bridge(interface_node1):
162             br_name1 = interface_node1
163         else:
164             br_name1 = DEFAULT_TEST_BRIDGE
165             server1.create_test_bridge(br_name1, interface_node1)
166
167         if server2.is_ovs_bridge(interface_node2):
168             br_name2 = interface_node2
169         else:
170             br_name2 = DEFAULT_TEST_BRIDGE
171             server2.create_test_bridge(br_name2, interface_node2)
172
173         server1.add_port_to_bridge(br_name1, DEFAULT_TEST_PORT)
174         servers_with_test_ports.append(server1)
175         server2.add_port_to_bridge(br_name2, DEFAULT_TEST_PORT)
176         servers_with_test_ports.append(server2)
177
178         server1.ovs_vsctl_set("Port", DEFAULT_TEST_PORT, "tag", None, tag)
179         server2.ovs_vsctl_set("Port", DEFAULT_TEST_PORT, "tag", None, tag)
180
181         server1.ovs_vsctl_set("Interface", DEFAULT_TEST_PORT, "type", None,
182                               "internal")
183         server2.ovs_vsctl_set("Interface", DEFAULT_TEST_PORT, "type", None,
184                               "internal")
185
186         server1.interface_assign_ip(DEFAULT_TEST_PORT, node1[2], None)
187         server2.interface_assign_ip(DEFAULT_TEST_PORT, node2[2], None)
188
189         server1.interface_up(DEFAULT_TEST_PORT)
190         server2.interface_up(DEFAULT_TEST_PORT)
191
192         do_udp_tests(node1, node2, bandwidth, duration, ps)
193         do_udp_tests(node2, node1, bandwidth, duration, ps)
194         do_tcp_tests(node1, node2, duration)
195         do_tcp_tests(node2, node1, duration)
196
197     finally:
198         for server in servers_with_test_ports:
199             server.del_port_from_bridge(DEFAULT_TEST_PORT)
200         if br_name1 == DEFAULT_TEST_BRIDGE:
201             server1.del_test_bridge(br_name1, interface_node1)
202         if br_name2 == DEFAULT_TEST_BRIDGE:
203             server2.del_test_bridge(br_name2, interface_node2)
204
205
206 def do_direct_tests(node1, node2, bandwidth, duration, ps):
207     """
208     Do tests between outer IPs without involving Open vSwitch. Each
209     node is given as 4 tuple - physical interface IP, control port,
210     test IP and test port. Direct tests will use physical interface
211     IP as the test IP address.
212     """
213     n1 = (node1[0], node1[1], node1[0], node1[3])
214     n2 = (node2[0], node2[1], node2[0], node2[3])
215
216     do_udp_tests(n1, n2, bandwidth, duration, ps)
217     do_udp_tests(n2, n1, bandwidth, duration, ps)
218     do_tcp_tests(n1, n2, duration)
219     do_tcp_tests(n2, n1, duration)
220
221
222 def configure_l3(conf, tunnel_mode):
223     """
224     This function creates a temporary test bridge and adds an L3 tunnel.
225     """
226     s = util.start_local_server(conf[1][1])
227     server = util.rpc_client("127.0.0.1", conf[1][1])
228     server.create_bridge(DEFAULT_TEST_BRIDGE)
229     server.add_port_to_bridge(DEFAULT_TEST_BRIDGE, DEFAULT_TEST_PORT)
230     server.interface_up(DEFAULT_TEST_BRIDGE)
231     server.interface_assign_ip(DEFAULT_TEST_BRIDGE, conf[1][0],
232                                None)
233     server.ovs_vsctl_set("Interface", DEFAULT_TEST_PORT, "type",
234                          None, tunnel_mode)
235     server.ovs_vsctl_set("Interface", DEFAULT_TEST_PORT, "options",
236                          "remote_ip", conf[0])
237     return s