VPP install and verify in __init__.robot
[csit.git] / resources / tools / virl / bin / start-testcase
index 0d9c49e..ce47378 100755 (executable)
 
 __author__ = 'ckoester@cisco.com'
 
-import sys
-import re
-import os
 import argparse
-import tempfile
+import netifaces
+import os
+import paramiko
+import random
+import re
 import shutil
+import sys
+import tempfile
 import time
-import paramiko
-import netifaces
 
 import requests
 
+IPS_PER_SIMULATION = 5
+
+
 def indent(lines, amount, fillchar=' '):
     """Indent the string by amount of fill chars.
 
@@ -44,6 +48,7 @@ def indent(lines, amount, fillchar=' '):
     padding = amount * fillchar
     return padding + ('\n'+padding).join(lines.split('\n'))
 
+
 def print_to_stderr(msg, end='\n'):
     """Writes any text to stderr.
 
@@ -57,11 +62,77 @@ def print_to_stderr(msg, end='\n'):
     except ValueError:
         pass
 
+
+def get_assigned_interfaces(args, network="flat"):
+    """Retrieve assigned interfaces in openstack network.
+
+    :param args: Command line params.
+    :param network: Openstack network.
+    :type args: ArgumentParser
+    :type network: str
+    :returns: Assigned interfaces.
+    :rtype: list
+    :raises RuntimeError: If response is not 200.
+    """
+    req = requests.get('http://{}/openstack/rest/ports/{}'
+                       .format(args.virl_ip, network),
+                       auth=(args.username, args.password))
+    if req.status_code == 200:
+        return req.json()
+    else:
+        raise RuntimeError("ERROR: Retrieving ports in use - "
+                           "Status other than 200 HTTP OK:\n{}"
+                           .format(req.content))
+
+
+def get_assigned_interfaces_count(args, network="flat"):
+    """Count assigned interfaces in openstack network.
+
+    :param args: Command line params.
+    :param network: Openstack network.
+    :type args: ArgumentParser
+    :type network: str
+    :returns: Assigned interfaces count.
+    :rtype: int
+    """
+    return len(get_assigned_interfaces(args, network=network))
+
+
+def check_ip_addresses(args):
+    """Check IP address availability.
+
+    :param args: Command line params.
+    :type args: ArgumentParser
+    :raises RuntimeError: If not enough free addresses available.
+    """
+    for i in range(args.wait_count):
+        if (args.quota -
+                get_assigned_interfaces_count(args) >= IPS_PER_SIMULATION):
+            break
+        if args.verbosity >= 2:
+            print_to_stderr("DEBUG: - Attempt {} out of {}, waiting for free "
+                            "IP addresses".format(i, args.wait_count))
+        # Wait random amount of time within range 1-3 minutes
+        time.sleep(random.randint(60,180))
+    else:
+        raise RuntimeError("ERROR: Not enough IP addresses to run simulation")
+
+
+def check_virl_resources(args):
+    """Check virl resources availability.
+
+    :param args: Command line params.
+    :type args: ArgumentParser
+    """
+    check_ip_addresses(args)
+
 #
 # FIXME: Right now, this is really coded like a shell script, as one big
 # function executed in sequence. This should be broken down into multiple
 # functions.
 #
+
+
 def main():
     """ Main function."""
     #
@@ -123,6 +194,11 @@ def main():
                         default="csit-ubuntu-16.04.1_2016-12-19_1.6")
     parser.add_argument("--topology-directory", help="Topology directory",
                         default="/home/jenkins-in/testcase-infra/topologies")
+    parser.add_argument("-q", "--quota",
+                        help="VIRL quota for max number of allowed IPs",
+                        type=int, default=74)
+    parser.add_argument("-si", "--skip-install", help="Skip VPP installation",
+                        action='store_true')
 
     args = parser.parse_args()
 
@@ -150,14 +226,15 @@ def main():
     #
     # Check if VPP package exists
     #
-    for package in args.packages:
-        if args.verbosity >= 2:
-            print_to_stderr("DEBUG: Checking if file {} exists"
-                            .format(package))
-        if not os.path.isfile(package):
-            print_to_stderr("ERROR: Debian package {} does not exist"
-                            .format(package))
-            sys.exit(1)
+    if not args.skip_install:
+        for package in args.packages:
+            if args.verbosity >= 2:
+                print_to_stderr("DEBUG: Checking if file {} exists"
+                                .format(package))
+            if not os.path.isfile(package):
+                print_to_stderr("ERROR: Required package {} does not exist"
+                                .format(package))
+                sys.exit(1)
 
     #
     # Start VIRL topology
@@ -181,6 +258,7 @@ def main():
 
     try:
         data = open(temp_topology, 'rb')
+        check_virl_resources(args)
         req = requests.post('http://' + args.virl_ip + '/simengine/rest/launch',
                             auth=(args.username, args.password),
                             data=data)
@@ -310,7 +388,7 @@ def main():
                 shutil.rmtree(scratch_directory)
             except shutil.Error:
                 print_to_stderr("ERROR: Removing scratch directory")
-        print "{}".format(session_id)
+            print "{}".format(session_id)
         sys.exit(1)
 
     if args.verbosity >= 2:
@@ -348,7 +426,7 @@ def main():
                 shutil.rmtree(scratch_directory)
             except shutil.Error:
                 print_to_stderr("ERROR: Removing scratch directory")
-        print "{}".format(session_id)
+            print "{}".format(session_id)
         sys.exit(1)
     data = req.json()
 
@@ -423,52 +501,53 @@ def main():
                 shutil.rmtree(scratch_directory)
             except shutil.Error:
                 print_to_stderr("ERROR: Removing scratch directory")
-        print "{}".format(session_id)
+            print "{}".format(session_id)
         sys.exit(1)
 
     #
     # Upgrade VPP
     #
-    if args.verbosity >= 1:
-        print_to_stderr("DEBUG: Uprading VPP")
-
-    for key1 in nodeaddrs:
-        if not key1 == 'tg':
-            for key2 in nodeaddrs[key1]:
-                ipaddr = nodeaddrs[key1][key2]
-                if args.verbosity >= 2:
-                    print_to_stderr("DEBUG: Upgrading VPP on node {}"
-                                    .format(ipaddr))
-                paramiko.util.log_to_file(os.path.join(scratch_directory,
-                                                       "ssh.log"))
-                client = paramiko.SSHClient()
-                client.load_system_host_keys()
-                client.load_host_keys("/dev/null")
-                client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
-                client.connect(ipaddr, username=args.ssh_user,
-                               key_filename=args.ssh_privkey)
-                if 'centos' in args.topology:
-                    if args.verbosity >= 1:
-                        print_to_stderr("DEBUG: Installing RPM packages")
-                    vpp_install_command = 'sudo rpm -ivh /scratch/vpp/*.rpm'
-                elif 'trusty' in args.topology or 'xenial' in args.topology:
-                    if args.verbosity >= 1:
-                        print_to_stderr("DEBUG: Installing DEB packages")
-                    vpp_install_command = 'sudo dpkg -i --force-all ' \
-                                          '/scratch/vpp/*.deb'
-                else:
-                    print_to_stderr("ERROR: Unsupported OS requested: {}"
-                                    .format(args.topology))
-                    vpp_install_command = ''
-                _, stdout, stderr = \
-                    client.exec_command(vpp_install_command)
-                c_stdout = stdout.read()
-                c_stderr = stderr.read()
-                if args.verbosity >= 2:
-                    print_to_stderr("DEBUG: Command output was:")
-                    print_to_stderr(c_stdout)
-                    print_to_stderr("DEBUG: Command stderr was:")
-                    print_to_stderr(c_stderr)
+    if not args.skip_install:
+        if args.verbosity >= 1:
+            print_to_stderr("DEBUG: Uprading VPP")
+
+        for key1 in nodeaddrs:
+            if not key1 == 'tg':
+                for key2 in nodeaddrs[key1]:
+                    ipaddr = nodeaddrs[key1][key2]
+                    if args.verbosity >= 2:
+                        print_to_stderr("DEBUG: Upgrading VPP on node {}"
+                                        .format(ipaddr))
+                    paramiko.util.log_to_file(os.path.join(scratch_directory,
+                                                           "ssh.log"))
+                    client = paramiko.SSHClient()
+                    client.load_system_host_keys()
+                    client.load_host_keys("/dev/null")
+                    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+                    client.connect(ipaddr, username=args.ssh_user,
+                                   key_filename=args.ssh_privkey)
+                    if 'centos' in args.topology:
+                        if args.verbosity >= 1:
+                            print_to_stderr("DEBUG: Installing RPM packages")
+                        vpp_install_command = 'sudo rpm -ivh /scratch/vpp/*.rpm'
+                    elif 'trusty' in args.topology or 'xenial' in args.topology:
+                        if args.verbosity >= 1:
+                            print_to_stderr("DEBUG: Installing DEB packages")
+                        vpp_install_command = 'sudo dpkg -i --force-all ' \
+                                              '/scratch/vpp/*.deb'
+                    else:
+                        print_to_stderr("ERROR: Unsupported OS requested: {}"
+                                         .format(args.topology))
+                        vpp_install_command = ''
+                    _, stdout, stderr = \
+                        client.exec_command(vpp_install_command)
+                    c_stdout = stdout.read()
+                    c_stderr = stderr.read()
+                    if args.verbosity >= 2:
+                        print_to_stderr("DEBUG: Command output was:")
+                        print_to_stderr(c_stdout)
+                        print_to_stderr("DEBUG: Command stderr was:")
+                        print_to_stderr(c_stderr)
 
     #
     # Write a file with timestamp to scratch directory. We can use this to track