From d4757d239155cbd21ce45b656469c10d67cdf569 Mon Sep 17 00:00:00 2001 From: Manuel Buil Date: Tue, 12 Dec 2017 12:15:00 +0100 Subject: Clean up our utils.py Utils.py was getting messy. This patch divides it into three different files: * test_utils.py * odl_utils.py * openstack_utils.py The tacker library is integrated into openstack_utils.py Change-Id: I310949d1cee49b6aa1c9b3396bf6d6ca458cbaac Signed-off-by: Manuel Buil --- sfc/lib/test_utils.py | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 sfc/lib/test_utils.py (limited to 'sfc/lib/test_utils.py') diff --git a/sfc/lib/test_utils.py b/sfc/lib/test_utils.py new file mode 100644 index 00000000..9cdc02b2 --- /dev/null +++ b/sfc/lib/test_utils.py @@ -0,0 +1,222 @@ +#!/usr/bin/python +# +# Copyright (c) 2016 All rights reserved +# This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +import os +import subprocess +import time + +import logging +import functest.utils.functest_utils as ft_utils + + +logger = logging.getLogger(__name__) +SSH_OPTIONS = '-q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' +FUNCTEST_RESULTS_DIR = os.path.join("home", "opnfv", + "functest", "results", "odl-sfc") + + +def run_cmd(cmd): + """ + Run given command locally + Return a tuple with the return code, stdout, and stderr of the command + """ + pipe = subprocess.Popen(cmd, + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + + stdout, stderr = [stream.strip() for stream in pipe.communicate()] + output = ' - STDOUT: "%s"' % stdout if len(stdout) > 0 else '' + error = ' - STDERR: "%s"' % stdout if len(stderr) > 0 else '' + logger.debug("Running [{command}] returns: [{rc}]{output}{error}".format( + command=cmd, + rc=pipe.returncode, + output=output, + error=error)) + + return pipe.returncode, stdout, stderr + + +def run_cmd_remote(ip, cmd, username="root", passwd="opnfv"): + """run given command on Remote Machine, Can be VM""" + ssh_opt_append = "%s -o ConnectTimeout=50 " % SSH_OPTIONS + ssh_cmd = "sshpass -p %s ssh %s %s@%s %s" % ( + passwd, ssh_opt_append, username, ip, cmd) + return run_cmd(ssh_cmd) + + +def download_image(url, image_path): + image_filename = os.path.basename(image_path) + image_url = "%s/%s" % (url, image_filename) + image_dir = os.path.dirname(image_path) + if not os.path.isfile(image_path): + logger.info("Downloading image") + ft_utils.download_url(image_url, image_dir) + else: + logger.info("Using old image") + + +def ping(remote, retries=100, retry_timeout=1): + cmd = 'ping -c1 -w{timeout} {remote}'.format( + timeout=retry_timeout, + remote=remote) + + while retries > 0: + rc, _, _ = run_cmd(cmd) + if rc == 0: + return True + + retries -= 1 + + return False + + +def start_http_server(ip, iterations_check=10): + """ + Start http server on a given machine. Wait until the process exists + and until the port is up + """ + cmd = "\'python -m SimpleHTTPServer 80" + cmd = cmd + " > /dev/null 2>&1 &\'" + run_cmd_remote(ip, cmd) + + # Wait for the process to start before checking + time.sleep(3) + _, output, _ = run_cmd_remote(ip, "ps aux | grep SimpleHTTPServer") + if not output: + logger.error("Failed to start http server") + return False + logger.info(output) + + while iterations_check > 0: + _, output, _ = run_cmd_remote(ip, "ss -na | grep *:80") + if output: + return True + else: + logger.debug("Port 80 is not up yet") + iterations_check -= 1 + time.sleep(5) + + logger.error("Failed to start http server") + return False + + +def start_vxlan_tool(remote_ip, interface="eth0", block=None): + """ + Starts vxlan_tool on a remote host. + vxlan_tool.py converts a regular Service Function into a NSH-aware SF + when the "--do forward" option is used, it decrements the NSI appropiately. + 'block' parameters allows to specify a port where packets will be dropped. + """ + command = "nohup python /root/vxlan_tool.py" + options = "{do} {interface} {block_option}".format( + do="--do forward", + interface="--interface {}".format(interface), + block_option="--block {}".format(block) if block is not None else "") + output_redirection = "> /dev/null 2>&1" + + full_command = "{command} {options} {output_redirection} &".format( + command=command, + options=options, + output_redirection=output_redirection) + + output_execution = run_cmd_remote(remote_ip, full_command) + + # Wait for the process to start before checking + time.sleep(3) + _, output, _ = run_cmd_remote(remote_ip, "ps aux | grep vxlan_tool") + if not output: + logger.error("Failed to start the vxlan tool") + return False + + return output_execution + + +def stop_vxlan_tool(remote_ip): + """ Stops vxlan_tool on a remote host""" + command = "pkill -f vxlan_tool.py" + return run_cmd_remote(remote_ip, command) + + +def netcat(source_ip, destination_ip, destination_port, source_port=None, + timeout=5): + """ + SSH into source_ip, and check the connectivity from there to destination_ip + on the specified port, using the netcat command. + Returns 0 on successful execution, != 0 on failure + """ + source_port_option = '' if source_port is None else '-p %s' % source_port + cmd = "nc -z {option} -w {timeout} {ip} {port}".format( + option=source_port_option, + timeout=timeout, + ip=destination_ip, + port=destination_port) + rc, _, _ = run_cmd_remote(source_ip, cmd) + logger.info("Running [%s] from [%s] returns [%s]" % (cmd, source_ip, rc)) + return rc + + +def is_ssh_blocked(source_ip, destination_ip, source_port=None): + rc = netcat( + source_ip, + destination_ip, + destination_port="22", + source_port=source_port) + return rc != 0 + + +def is_http_blocked(source_ip, destination_ip, source_port=None): + rc = netcat( + source_ip, + destination_ip, + destination_port="80", + source_port=source_port) + return rc != 0 + + +def capture_ovs_logs(ovs_logger, controller_clients, compute_clients, error): + timestamp = time.strftime("%Y%m%d-%H%M%S") + ovs_logger.dump_ovs_logs(controller_clients, + compute_clients, + related_error=error, + timestamp=timestamp) + + +def get_ssh_clients(nodes): + return [n.ssh_client for n in nodes] + + +def check_ssh(ips, retries=100): + """Check SSH connectivity to VNFs""" + check = [False for ip in ips] + logger.info("Checking SSH connectivity to the SFs with ips %s" % str(ips)) + while retries and not all(check): + for index, ip in enumerate(ips): + rc, _, _ = run_cmd_remote(ip, "exit") + check[index] = True if rc == 0 else False + + if all(check): + logger.info("SSH connectivity to the SFs established") + return True + + time.sleep(3) + retries -= 1 + + return False + + +def fill_installer_dict(installer_type): + default_string = "defaults.installer.{}.".format(installer_type) + installer_yaml_fields = { + "user": default_string+"user", + "password": default_string+"password", + "cluster": default_string+"cluster", + "pkey_file": default_string+"pkey_file" + } + return installer_yaml_fields -- cgit 1.2.3-korg