ovs-l3ping: A new test utility that allows to detect L3 tunneling issues
[sliver-openvswitch.git] / utilities / ovs-test.in
index b53302f..fb1f9ad 100644 (file)
@@ -32,80 +32,18 @@ import twisted
 
 import ovstest.args as args
 import ovstest.rpcserver as rpcserver
+import ovstest.tests as tests
+import ovstest.util as util
 
 DEFAULT_TEST_BRIDGE = "ovstestbr0"
 DEFAULT_TEST_PORT = "ovstestport0"
 DEFAULT_TEST_TUN = "ovstestport1"
 
 
-def rpc_client(ip, port):
-    return xmlrpclib.Server("http://%s:%u/" % (ip, port), allow_none=True)
-
-
-def sigint_intercept():
-    """
-    Intercept SIGINT from child (the local ovs-test server process).
-    """
-    signal.signal(signal.SIGINT, signal.SIG_IGN)
-
-
-def start_local_server(port):
-    """
-    This function spawns an ovs-test server that listens on specified port
-    and blocks till the spawned ovs-test server is ready to accept XML RPC
-    connections.
-    """
-    p = subprocess.Popen(["ovs-test", "-s", str(port)],
-                         stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-                         preexec_fn = sigint_intercept)
-    fcntl.fcntl( p.stdout.fileno(),fcntl.F_SETFL,
-        fcntl.fcntl(p.stdout.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK)
-
-    while p.poll() is None:
-        fd = select.select([p.stdout.fileno()], [], [])[0]
-        if fd:
-            out = p.stdout.readline()
-            if out.startswith("Starting RPC server"):
-                break
-    if p.poll() is not None:
-        raise RuntimeError("Couldn't start local instance of ovs-test server")
-    return p
-
-
-def get_datagram_sizes(mtu1, mtu2):
-    """
-    This function calculates all the "interesting" datagram sizes so that
-    we test both - receive and send side with different packets sizes.
-    """
-    s1 = set([8, mtu1 - 100, mtu1 - 28, mtu1])
-    s2 = set([8, mtu2 - 100, mtu2 - 28, mtu2])
-    return sorted(s1.union(s2))
-
-
-def ip_from_cidr(string):
-    """
-    This function removes the netmask (if present) from the given string and
-    returns the IP address.
-    """
-    token = string.split("/")
-    return token[0]
-
-
-def bandwidth_to_string(bwidth):
-    """Convert bandwidth from long to string and add units."""
-    bwidth = bwidth * 8  # Convert back to bits/second
-    if bwidth >= 10000000:
-        return str(int(bwidth / 1000000)) + "Mbps"
-    elif bwidth > 10000:
-        return str(int(bwidth / 1000)) + "Kbps"
-    else:
-        return str(int(bwidth)) + "bps"
-
-
 def collect_information(node):
     """Print information about hosts that will do testing"""
     print "Node %s:%u " % (node[0], node[1])
-    server = rpc_client(node[0], node[1])
+    server = util.rpc_client(node[0], node[1])
     interface_name = server.get_interface(node[0])
     phys_iface = None
     uname = server.uname()
@@ -140,210 +78,6 @@ def collect_information(node):
     return mtu
 
 
-def do_udp_tests(receiver, sender, tbwidth, duration, port_sizes):
-    """Schedule UDP tests between receiver and sender"""
-    server1 = rpc_client(receiver[0], receiver[1])
-    server2 = rpc_client(sender[0], sender[1])
-
-    udpformat = '{0:>15} {1:>15} {2:>15} {3:>15} {4:>15}'
-
-    print ("UDP test from %s:%u to %s:%u with target bandwidth %s" %
-                            (sender[0], sender[1], receiver[0], receiver[1],
-                             bandwidth_to_string(tbwidth)))
-    print udpformat.format("Datagram Size", "Snt Datagrams", "Rcv Datagrams",
-                            "Datagram Loss", "Bandwidth")
-
-    for size in port_sizes:
-        listen_handle = -1
-        send_handle = -1
-        try:
-            packetcnt = (tbwidth * duration) / size
-
-            listen_handle = server1.create_udp_listener(receiver[3])
-            if listen_handle == -1:
-                print ("Server could not open UDP listening socket on port"
-                        " %u. Try to restart the server.\n" % receiver[3])
-                return
-            send_handle = server2.create_udp_sender(
-                                            (ip_from_cidr(receiver[2]),
-                                             receiver[3]), packetcnt, size,
-                                             duration)
-
-            # Using sleep here because there is no other synchronization source
-            # that would notify us when all sent packets were received
-            time.sleep(duration + 1)
-
-            rcv_packets = server1.get_udp_listener_results(listen_handle)
-            snt_packets = server2.get_udp_sender_results(send_handle)
-
-            loss = math.ceil(((snt_packets - rcv_packets) * 10000.0) /
-                                                        snt_packets) / 100
-            bwidth = (rcv_packets * size) / duration
-
-            print udpformat.format(size, snt_packets, rcv_packets,
-                                '%.2f%%' % loss, bandwidth_to_string(bwidth))
-        finally:
-            if listen_handle != -1:
-                server1.close_udp_listener(listen_handle)
-            if send_handle != -1:
-                server2.close_udp_sender(send_handle)
-    print "\n"
-
-
-def do_tcp_tests(receiver, sender, duration):
-    """Schedule TCP tests between receiver and sender"""
-    server1 = rpc_client(receiver[0], receiver[1])
-    server2 = rpc_client(sender[0], sender[1])
-
-    tcpformat = '{0:>15} {1:>15} {2:>15}'
-    print "TCP test from %s:%u to %s:%u (full speed)" % (sender[0], sender[1],
-                                                    receiver[0], receiver[1])
-    print tcpformat.format("Snt Bytes", "Rcv Bytes", "Bandwidth")
-
-    listen_handle = -1
-    send_handle = -1
-    try:
-        listen_handle = server1.create_tcp_listener(receiver[3])
-        if listen_handle == -1:
-            print ("Server was unable to open TCP listening socket on port"
-                    " %u. Try to restart the server.\n" % receiver[3])
-            return
-        send_handle = server2.create_tcp_sender(ip_from_cidr(receiver[2]),
-                                                receiver[3], duration)
-
-        time.sleep(duration + 1)
-
-        rcv_bytes = long(server1.get_tcp_listener_results(listen_handle))
-        snt_bytes = long(server2.get_tcp_sender_results(send_handle))
-
-        bwidth = rcv_bytes / duration
-
-        print tcpformat.format(snt_bytes, rcv_bytes,
-                               bandwidth_to_string(bwidth))
-    finally:
-        if listen_handle != -1:
-            server1.close_tcp_listener(listen_handle)
-        if send_handle != -1:
-            server2.close_tcp_sender(send_handle)
-    print "\n"
-
-
-def do_l3_tests(node1, node2, bandwidth, duration, ps, type):
-    """
-    Do L3 tunneling tests.
-    """
-    server1 = rpc_client(node1[0], node1[1])
-    server2 = rpc_client(node2[0], node2[1])
-    servers_with_bridges = []
-    try:
-        server1.create_bridge(DEFAULT_TEST_BRIDGE)
-        servers_with_bridges.append(server1)
-        server2.create_bridge(DEFAULT_TEST_BRIDGE)
-        servers_with_bridges.append(server2)
-
-        server1.interface_up(DEFAULT_TEST_BRIDGE)
-        server2.interface_up(DEFAULT_TEST_BRIDGE)
-
-        server1.interface_assign_ip(DEFAULT_TEST_BRIDGE, node1[2], None)
-        server2.interface_assign_ip(DEFAULT_TEST_BRIDGE, node2[2], None)
-
-        server1.add_port_to_bridge(DEFAULT_TEST_BRIDGE, DEFAULT_TEST_TUN)
-        server2.add_port_to_bridge(DEFAULT_TEST_BRIDGE, DEFAULT_TEST_TUN)
-
-        server1.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "type",
-                              None, type)
-        server2.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "type",
-                              None, type)
-        server1.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "options",
-                              "remote_ip", node2[0])
-        server2.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "options",
-                              "remote_ip", node1[0])
-
-        do_udp_tests(node1, node2, bandwidth, duration, ps)
-        do_udp_tests(node2, node1, bandwidth, duration, ps)
-        do_tcp_tests(node1, node2, duration)
-        do_tcp_tests(node2, node1, duration)
-
-    finally:
-        for server in servers_with_bridges:
-            server.del_bridge(DEFAULT_TEST_BRIDGE)
-
-
-
-def do_vlan_tests(node1, node2, bandwidth, duration, ps, tag):
-    """
-    Do VLAN tests between node1 and node2.
-    """
-    server1 = rpc_client(node1[0], node1[1])
-    server2 = rpc_client(node2[0], node2[1])
-
-    br_name1 = None
-    br_name2 = None
-
-    servers_with_test_ports = []
-
-    try:
-        interface_node1 = server1.get_interface(node1[0])
-        interface_node2 = server2.get_interface(node2[0])
-
-        if server1.is_ovs_bridge(interface_node1):
-            br_name1 = interface_node1
-        else:
-            br_name1 = DEFAULT_TEST_BRIDGE
-            server1.create_test_bridge(br_name1, interface_node1)
-
-        if server2.is_ovs_bridge(interface_node2):
-            br_name2 = interface_node2
-        else:
-            br_name2 = DEFAULT_TEST_BRIDGE
-            server2.create_test_bridge(br_name2, interface_node2)
-
-        server1.add_port_to_bridge(br_name1, DEFAULT_TEST_PORT)
-        servers_with_test_ports.append(server1)
-        server2.add_port_to_bridge(br_name2, DEFAULT_TEST_PORT)
-        servers_with_test_ports.append(server2)
-
-        server1.ovs_vsctl_set("Port", DEFAULT_TEST_PORT, "tag", None, tag)
-        server2.ovs_vsctl_set("Port", DEFAULT_TEST_PORT, "tag", None, tag)
-
-        server1.ovs_vsctl_set("Interface", DEFAULT_TEST_PORT, "type", None,
-                              "internal")
-        server2.ovs_vsctl_set("Interface", DEFAULT_TEST_PORT, "type", None,
-                              "internal")
-
-        server1.interface_assign_ip(DEFAULT_TEST_PORT, node1[2], None)
-        server2.interface_assign_ip(DEFAULT_TEST_PORT, node2[2], None)
-
-        server1.interface_up(DEFAULT_TEST_PORT)
-        server2.interface_up(DEFAULT_TEST_PORT)
-
-        do_udp_tests(node1, node2, bandwidth, duration, ps)
-        do_udp_tests(node2, node1, bandwidth, duration, ps)
-        do_tcp_tests(node1, node2, duration)
-        do_tcp_tests(node2, node1, duration)
-
-    finally:
-        for server in servers_with_test_ports:
-            server.del_port_from_bridge(DEFAULT_TEST_PORT)
-        if br_name1 == DEFAULT_TEST_BRIDGE:
-            server1.del_test_bridge(br_name1, interface_node1)
-        if br_name2 == DEFAULT_TEST_BRIDGE:
-            server2.del_test_bridge(br_name2, interface_node2)
-
-
-def do_direct_tests(node1, node2, bandwidth, duration, ps):
-    """
-    Do tests between outer IPs without involving Open vSwitch
-    """
-    n1 = (node1[0], node1[1], node1[0], node1[3])
-    n2 = (node2[0], node2[1], node2[0], node2[3])
-
-    do_udp_tests(n1, n2, bandwidth, duration, ps)
-    do_udp_tests(n2, n1, bandwidth, duration, ps)
-    do_tcp_tests(n1, n2, duration)
-    do_tcp_tests(n2, n1, duration)
-
-
 if __name__ == '__main__':
     local_server = None
     try:
@@ -360,10 +94,10 @@ if __name__ == '__main__':
             # ovs-test server by looking at the first OuterIP. if it is a
             # 127.0.0.1 then spawn local ovs-test server.
             if node1[0] == "127.0.0.1":
-                local_server = start_local_server(node1[1])
+                local_server = util.start_local_server(node1[1])
                 # We must determine the IP address that local ovs-test server
                 # will use:
-                me = rpc_client(node1[0], node1[1])
+                me = util.rpc_client(node1[0], node1[1])
                 my_ip = me.get_my_address_from(node2[0], node2[1])
                 node1 = (my_ip, node1[1], node1[2], node1[3])
 
@@ -372,7 +106,7 @@ if __name__ == '__main__':
 
             bandwidth = ovs_args.targetBandwidth
             interval = ovs_args.testInterval
-            ps = get_datagram_sizes(mtu_node1, mtu_node2)
+            ps = util.get_datagram_sizes(mtu_node1, mtu_node2)
 
             direct = ovs_args.direct
             vlan_tag = ovs_args.vlanTag
@@ -380,15 +114,17 @@ if __name__ == '__main__':
 
             if direct is not None:
                 print "Performing direct tests"
-                do_direct_tests(node2, node1, bandwidth, interval, ps)
+                tests.do_direct_tests(node2, node1, bandwidth, interval, ps)
 
             if vlan_tag is not None:
                 print "Performing VLAN tests"
-                do_vlan_tests(node2, node1, bandwidth, interval, ps, vlan_tag)
+                tests.do_vlan_tests(node2, node1, bandwidth, interval, ps,
+                                    vlan_tag)
 
             for tmode in tunnel_modes:
                 print "Performing", tmode, "tests"
-                do_l3_tests(node2, node1, bandwidth, interval, ps, tmode)
+                tests.do_l3_tests(node2, node1, bandwidth, interval, ps,
+                                  tmode)
 
     except KeyboardInterrupt:
         pass