ovs-test: A new tool that allows to diagnose connectivity and performance issues
[openvswitch] / python / ovstest / args.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 ovsargs provide argument parsing for ovs-test utility
17 """
18
19 import argparse
20 import socket
21 import re
22
23
24 def ip(string):
25     """Verifies if string is a valid IP address"""
26     try:
27         socket.inet_aton(string)
28     except socket.error:
29         raise argparse.ArgumentTypeError("Not a valid IPv4 address")
30     return string
31
32
33 def port(string):
34     """Convert a string into a Port (integer)"""
35     try:
36         port_number = int(string)
37         if port_number < 1 or port_number > 65535:
38             raise argparse.ArgumentTypeError("Port is out of range")
39     except ValueError:
40         raise argparse.ArgumentTypeError("Port is not an integer")
41     return port_number
42
43
44 def ip_optional_port(string, default_port):
45     """Convert a string into IP and Port pair. If port was absent then use
46     default_port as the port"""
47     value = string.split(':')
48     if len(value) == 1:
49         return (ip(value[0]), default_port)
50     elif len(value) == 2:
51         return (ip(value[0]), port(value[1]))
52     else:
53         raise argparse.ArgumentTypeError("IP address from the optional Port "
54                                          "must be colon-separated")
55
56
57
58 def server_endpoint(string):
59     """Converts a string in ControlIP[:ControlPort][,TestIP[:TestPort]] format
60     into a 4-tuple, where:
61     1. First element is ControlIP
62     2. Second element is ControlPort (if omitted will use default value 15531)
63     3  Third element is TestIP (if omitted will be the same as ControlIP)
64     4. Fourth element is TestPort (if omitted will use default value 15532)"""
65     value = string.split(',')
66     if len(value) == 1: #  TestIP and TestPort are not present
67         ret = ip_optional_port(value[0], 15531)
68         return (ret[0], ret[1], ret[0], 15532)
69     elif len(value) == 2:
70         ret1 = ip_optional_port(value[0], 15531)
71         ret2 = ip_optional_port(value[1], 15532)
72         return (ret1[0], ret1[1], ret2[0], ret2[1])
73     else:
74         raise argparse.ArgumentTypeError("ControlIP:ControlPort and TestIP:"
75                                          "TestPort must be comma "
76                                          "separated")
77
78
79 def bandwidth(string):
80     """Convert a string (given in bits/second with optional magnitude for
81     units) into a long (bytes/second)"""
82     if re.match("^[1-9][0-9]*[MK]?$", string) == None:
83         raise argparse.ArgumentTypeError("Not a valid target bandwidth")
84     bwidth = string.replace("M", "000000")
85     bwidth = bwidth.replace("K", "000")
86     return long(bwidth) / 8 #  Convert from bits to bytes
87
88
89 def ovs_initialize_args():
90     """Initialize args for ovstest utility"""
91     parser = argparse.ArgumentParser(description = 'Test ovs connectivity')
92     parser.add_argument('-v', '--version', action = 'version',
93                 version = 'ovs-test (Open vSwitch) @VERSION@')
94     parser.add_argument("-b", "--bandwidth", action = 'store',
95                 dest = "targetBandwidth", default = "1M", type = bandwidth,
96                 help = 'target bandwidth for UDP tests in bits/second. Use '
97                 'postfix M or K to alter unit magnitude.')
98     group = parser.add_mutually_exclusive_group(required = True)
99     group.add_argument("-s", "--server", action = "store", dest = "port",
100                 type = port,
101                 help = 'run in server mode and wait client to connect to this '
102                 'port')
103     group.add_argument('-c', "--client", action = "store", nargs = 2,
104                 dest = "servers", type = server_endpoint,
105                 metavar = ("SERVER1", "SERVER2"),
106                 help = 'run in client mode and do tests between these '
107                 'two servers. Each server must be specified in following '
108                 'format - ControlIP[:ControlPort][,TestIP[:TestPort]]. If '
109                 'TestIP is omitted then ovs-test server will also use the '
110                 'ControlIP for testing purposes. ControlPort is TCP port '
111                 'where server will listen for incoming XML/RPC control '
112                 'connections to schedule tests (by default 15531). TestPort '
113                 'is port which will be used by server to send test traffic '
114                 '(by default 15532)')
115     return parser.parse_args()