Implemented HW2HW network performance testing
Implemented HW2HW network performance test:
- Added K8S client manager and API methods
- Added method for collecting HW compute nodes
- Improved and extended global config
- Extended requirements.txt, pinned some modules
- Extended and improved SSH methods
Added some small improvements:
- extended .gitignore
- Added some custom exceptions instead of basic ones
- Renamed some classes
- Set iperf v2 to be default for multi-threads tests
- Updated README file
Related-PROD: PROD-36943
Change-Id: I265058967ccc01d96bf3bca532a8a0ae2a26f1f2
diff --git a/utils/ssh.py b/utils/ssh.py
index e9e5f3a..caca30e 100644
--- a/utils/ssh.py
+++ b/utils/ssh.py
@@ -6,6 +6,8 @@
import time
import os
+from netaddr import IPNetwork, IPAddress
+
logger = logging.getLogger(__name__)
# Suppress paramiko logging
@@ -20,6 +22,10 @@
self.username = username
self.password = password
if private_key is not None:
+ if os.path.isfile(private_key):
+ with open(private_key, 'r') as key_file:
+ private_key_content = key_file.read()
+ private_key = private_key_content
self.private_key = paramiko.RSAKey.from_private_key(
StringIO(private_key))
else:
@@ -131,7 +137,7 @@
any(req in pack for req in required_packages) if
pack.endswith('.deb')]
if not iperf_deb_files:
- raise BaseException(
+ raise utils.exceptions.NoPackageInstalled(
"iperf3 or iperf *.deb packages are not found locally at path"
" {}. Please recheck 'iperf_deb_package_dir_path' variable in "
"global_config.yaml and check *.deb packages are manually "
@@ -178,7 +184,8 @@
"seconds.".format(floating_ip, attempts, bsleep))
time.sleep(bsleep)
- def get_mtu_from_vm(self, floating_ip, user='ubuntu', password='password',
+ @staticmethod
+ def get_mtu_from_vm(floating_ip, user='ubuntu', password='password',
private_key=None):
transport = SSHTransport(floating_ip, user, password, private_key)
iface = (transport.exec_command(
@@ -186,8 +193,29 @@
mtu = transport.exec_command('cat /sys/class/net/{}/mtu'.format(iface))
return mtu.decode("utf-8")
+ @staticmethod
+ def get_node_ip_addresses_from_cidr(ip, cidr, user='mcc-user',
+ private_key=None):
+ transport = SSHTransport(
+ ip, username=user, private_key=private_key)
+ command = "ip -4 addr show scope global"
+ output = transport.exec_command(command)
+ try:
+ all_ip_addresses = [line.split()[1] for line in
+ output.decode().splitlines()
+ if "/" in line.split()[1]]
+ for address in all_ip_addresses:
+ ip_addr = address.split('/')[0]
+ if IPAddress(ip_addr) in IPNetwork(cidr):
+ return ip_addr
+ except Exception as e:
+ raise utils.exceptions.InvalidConfigException(
+ f"Could not find the IP at the interface {cidr} at the node "
+ f"with K8S Private IP {ip}. Please check the configuration. "
+ f"\nException: {e}")
-class prepare_iperf(object):
+
+class IperfAtVM(object):
def __init__(self, fip, user='ubuntu', password='password',
private_key=None):
@@ -218,13 +246,49 @@
logger.info(check.decode('utf-8'))
if not check:
if internet_at_vms.lower() == 'true':
- info = "Please check the Internet access at VM."
+ info = "Please check the Internet access at VM"
else:
info = "Could not put offline iperf packages from {} to the " \
- "VM.".format(path_to_iperf_deb)
- raise BaseException("iperf3 is not installed at VM with FIP {}. "
- "{}.\nStdout, stderr at VM:\n{}\n{}"
- "".format(fip, info, stdout, stderr))
+ "VM".format(path_to_iperf_deb)
+ raise utils.exceptions.NoPackageInstalled(
+ "iperf3 is not installed at VM with FIP {}. {}.\nStdout, "
+ "stderr at VM:\n{}\n{}".format(fip, info, stdout, stderr))
# Staring iperf server
transport.exec_command('nohup iperf3 -s > file 2>&1 &')
transport.exec_command('nohup iperf -s > file 2>&1 &')
+
+
+class IperfAtNode(object):
+
+ def __init__(self, ip, iperf_test_ip, user='mcc-user', private_key=None):
+ transport = SSHTransport(ip, user, private_key=private_key)
+ # TODO: to avoid looping, both packages can be installed by one
+ # 'install -y iperf iperf3' command. 'which' command can also be
+ # executed for multiple packages at once.
+ packages = ["iperf", "iperf3"]
+ for p in packages:
+ check_path = transport.exec_command(f'which {p}')
+ if not check_path:
+ self.install_iperf = True
+ # Install iperf/iperf3 at MOSK nodes
+ logger.info(f"Installing {p} at MOSK nodes...")
+ _, stdout, stderr = transport.exec_sync(
+ f"sudo apt update && sudo apt install -y {p}")
+ else:
+ self.install_iperf = False
+ check_path = transport.exec_command(f'which {p}')
+ # Log whether iperf is installed
+ logger.info(f"{p} package path: {check_path.decode('utf-8')}")
+ if not check_path:
+ raise utils.exceptions.NoPackageInstalled(
+ f"{p} is not installed at the MOSK node with IP {ip}.\n"
+ f"Stdout, stderr at VM:\n{stdout}\n{stderr}")
+ # Staring iperf/iperf3 server
+ transport.exec_command(
+ f"nohup {p} -s -B {iperf_test_ip} > file 2>&1 &")
+
+ @staticmethod
+ def remove_iperf_packages(ip, user='mcc-user', private_key=None):
+ transport = SSHTransport(ip, user, private_key=private_key)
+ logger.info(f"Removing iperf,iperf3 packages from the node {ip}...")
+ transport.exec_command("sudo apt remove iperf iperf3 -y")