blob: ac6bbc004a90db16e6662fc51c4623b389a58b49 [file] [log] [blame]
Ievgeniia Zadorozhna96a715b2024-03-02 00:09:58 +01001from concurrent.futures import ThreadPoolExecutor
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +02002import logging
Ievgeniia Zadorozhna97dfde42022-06-17 20:05:09 +03003import sys
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +02004import time
5
6import pytest
7from texttable import Texttable
8
9import utils
Ievgeniia Zadorozhna9664b422023-03-28 21:09:46 +030010from utils import helpers
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020011from utils import os_client
12from utils import ssh
13
14
15logger = logging.getLogger(__name__)
16
17
Ievgeniia Zadorozhna9664b422023-03-28 21:09:46 +030018def test_vm2vm(openstack_clients, pair, os_resources, request, html_report):
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020019 """
20 Simplified Performance Tests VM to VM test in different topologies
21 1. Create 4 VMs admin project
22 2. Associate floating IPs to the VMs
23 3. Connect to each VM via SSH and install iperf3
24 4. Measure VM to VM on same node via Private IP, 1 thread
25 5. Measure VM to VM on different HW nodes via Private IP, 1 thread
Ievgeniia Zadorozhna5ed74e22022-07-26 16:56:23 +030026 6. Measure VM to VM on different HW nodes via Private IP, multiple threads
27 (10 by default)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020028 7. Measure VM to VM on different HW nodes via Floating IP, 1 thread
29 8. Measure VM to VM on different HW nodes, each VM is in separate network,
30 the networks are connected using Router via Private IP, 1 thread
31 9. Draw the table with all pairs and results
32 """
33 os_actions = os_client.OSCliActions(openstack_clients)
34 config = utils.get_configuration()
35 timeout = int(config.get('nova_timeout', 30))
36 iperf_time = int(config.get('iperf_time', 60))
37 private_key = os_resources['keypair'].private_key
38 ssh_timeout = int(config.get('ssh_timeout', 500))
Ievgeniia Zadorozhna5ed74e22022-07-26 16:56:23 +030039 threads = int(config.get('multiple_threads_number', 10))
Ievgeniia Zadorozhna90aa8022022-08-11 18:00:23 +030040 iperf_utility = config.get('multiple_threads_iperf_utility', 'iperf3')
Ievgeniia Zadorozhnac67b86b2023-02-02 18:09:12 +030041 custom_mtu = config.get('custom_mtu') or 'default'
Ievgeniia Zadorozhna90aa8022022-08-11 18:00:23 +030042 utils.check_iperf_utility(iperf_utility)
Ievgeniia Zadorozhna5ed74e22022-07-26 16:56:23 +030043 result_table = Texttable(max_width=120)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020044
45 try:
46 zone1 = [service.zone for service in
47 openstack_clients.compute.services.list() if
48 service.host == pair[0]]
49 zone2 = [service.zone for service in
50 openstack_clients.compute.services.list()
51 if service.host == pair[1]]
52
53 # create 4 VMs
54 logger.info("Creating 4 VMs...")
55 vm1 = os_actions.create_basic_server(
56 os_resources['image_id'], os_resources['flavor_id'],
57 os_resources['net1'], '{0}:{1}'.format(zone1[0], pair[0]),
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +030058 [os_resources['sec_group']['name']], os_resources['keypair'].name)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020059 logger.info("Created VM {}.".format(vm1.id))
60
61 vm2 = os_actions.create_basic_server(
62 os_resources['image_id'], os_resources['flavor_id'],
63 os_resources['net1'], '{0}:{1}'.format(zone1[0], pair[0]),
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +030064 [os_resources['sec_group']['name']], os_resources['keypair'].name)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020065 logger.info("Created VM {}.".format(vm2.id))
66
67 vm3 = os_actions.create_basic_server(
68 os_resources['image_id'], os_resources['flavor_id'],
69 os_resources['net1'], '{0}:{1}'.format(zone2[0], pair[1]),
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +030070 [os_resources['sec_group']['name']], os_resources['keypair'].name)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020071 logger.info("Created VM {}.".format(vm3.id))
72
73 vm4 = os_actions.create_basic_server(
74 os_resources['image_id'], os_resources['flavor_id'],
75 os_resources['net2'], '{0}:{1}'.format(zone2[0], pair[1]),
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +030076 [os_resources['sec_group']['name']], os_resources['keypair'].name)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020077 logger.info("Created VM {}.".format(vm4.id))
78
79 vm_info = []
80 vms = []
81 vms.extend([vm1, vm2, vm3, vm4])
82 fips = []
83 time.sleep(5)
84
85 # Associate FIPs and check VMs are Active
86 logger.info("Creating Floating IPs and associating them...")
Ievgeniia Zadorozhna96a715b2024-03-02 00:09:58 +010087 for i in range(len(vms)):
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +030088 fip = os_actions.create_floating_ip(os_resources['ext_net']['id'])
89 fips.append(fip['id'])
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020090 os_actions.check_vm_is_active(vms[i].id, timeout=timeout)
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +030091 vms[i].add_floating_ip(fip['floating_ip_address'])
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020092 private_address = vms[i].addresses[
93 list(vms[i].addresses.keys())[0]][0]['addr']
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +030094 vm_info.append({'vm': vms[i], 'fip': fip['floating_ip_address'],
Ievgeniia Zadorozhna96a715b2024-03-02 00:09:58 +010095 'private_address': private_address,
96 'private_key': private_key})
Ievgeniia Zadorozhnac67b86b2023-02-02 18:09:12 +030097 # Set custom MTU if required
98 if os_actions.is_cloud_tf() and (custom_mtu != "default"):
99 logger.info("Setting up custom MTU at network ports...")
100 for vm in vms:
101 os_actions.update_network_port_with_custom_mtu(vm.id,
102 custom_mtu)
103
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200104 # Check VMs are reachable and prepare iperf3
105 transport1 = ssh.SSHTransport(vm_info[0]['fip'], 'ubuntu',
106 password='dd', private_key=private_key)
Ievgeniia Zadorozhna96a715b2024-03-02 00:09:58 +0100107 logger.info("Checking VMs are reachable via SSH...")
108 for i in range(len(vms)):
109 transport1.check_vm_is_reachable_ssh(
110 floating_ip=vm_info[i]['fip'], timeout=ssh_timeout)
111 with ThreadPoolExecutor() as executor:
112 futures = [
Ievgeniia Zadorozhnaa8e8b572025-03-28 14:29:45 +0100113 executor.submit(ssh.install_iperf_at_vm, vm_info)
Ievgeniia Zadorozhna96a715b2024-03-02 00:09:58 +0100114 for vm_info in vm_info]
Ievgeniia Zadorozhnaa8e8b572025-03-28 14:29:45 +0100115 logger.info("Getting MTUs at VMs...")
116 mtus = []
117 for vm in vm_info:
118 mtus.append(ssh.get_mtu_at_vm(vm))
Ievgeniia Zadorozhnac67b86b2023-02-02 18:09:12 +0300119 logger.info("MTU at networks: {}, {}".format(
120 os_resources['net1']['mtu'], os_resources['net2']['mtu']))
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200121 # Prepare the result table and run iperf3
Ievgeniia Zadorozhnac67b86b2023-02-02 18:09:12 +0300122 table_rows = [[
123 'Test Case', 'Host 1', 'Host 2', 'MTU at VMs', 'Result'
124 ]]
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200125 # Do iperf3 measurement #1
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300126 measurement1 = ("VM to VM in same project on same node via Private "
127 "IP, 1 thread; iperf3")
128 logger.info("Doing '{}' measurement...".format(measurement1))
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200129 result1 = transport1.exec_command(
130 'iperf3 -c {} -t {} | grep sender | tail -n 1'.format(
131 vm_info[1]['private_address'], iperf_time))
132 res1 = (b" ".join(result1.split()[-4:-2:])).decode('utf-8')
133 logger.info("Result #1 is {}".format(res1))
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300134 table_rows.append([measurement1,
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200135 "{}".format(pair[0]),
136 "{}".format(pair[0]),
Ievgeniia Zadorozhna0facf3c2022-06-16 16:19:09 +0300137 "{}, {}".format(mtus[0], mtus[1]),
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200138 "{}".format(res1)])
139
140 # Do iperf3 measurement #2
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300141 measurement2 = ("VM to VM in same project on different HW nodes via "
142 "Private IP, 1 thread; iperf3")
143 logger.info("Doing '{}' measurement...".format(measurement2))
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200144 result2 = transport1.exec_command(
145 'iperf3 -c {} -t {} | grep sender | tail -n 1'.format(
146 vm_info[2]['private_address'], iperf_time))
147 res2 = (b" ".join(result2.split()[-4:-2:])).decode('utf-8')
148 logger.info("Result #2 is {}".format(res2))
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300149 table_rows.append([measurement2,
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200150 "{}".format(pair[0]),
151 "{}".format(pair[1]),
Ievgeniia Zadorozhna0facf3c2022-06-16 16:19:09 +0300152 "{}, {}".format(mtus[0], mtus[2]),
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200153 "{}".format(res2)])
154
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300155 # Do iperf/iperf3 measurement #3
156 measurement3 = ("VM to VM in same project on different HW nodes via "
157 "Private IP, {} threads; {}"
158 "".format(threads, iperf_utility))
159 logger.info("Doing '{}' measurement...".format(measurement3))
Ievgeniia Zadorozhna90aa8022022-08-11 18:00:23 +0300160 if iperf_utility == "iperf3":
161 result3 = transport1.exec_command(
162 '{} -c {} -P {} -t {} | grep sender | tail -n 1'
163 ''.format(iperf_utility, vm_info[2]['private_address'],
164 threads, iperf_time))
165 res3 = (b" ".join(result3.split()[-4:-2:])).decode('utf-8')
166 else:
167 iperf_utility = "iperf"
168 result3 = transport1.exec_command(
Ievgeniia Zadorozhnac67b86b2023-02-02 18:09:12 +0300169 '{} -c {} -P {} -t {} | tail -n 1'.format(
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300170 iperf_utility, vm_info[2]['private_address'], threads,
171 iperf_time))
Ievgeniia Zadorozhna90aa8022022-08-11 18:00:23 +0300172 res3 = (b" ".join(result3.split()[-2::])).decode('utf-8')
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200173 logger.info("Result #3 is {}".format(res3))
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300174 table_rows.append([measurement3,
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200175 "{}".format(pair[0]),
176 "{}".format(pair[1]),
Ievgeniia Zadorozhna0facf3c2022-06-16 16:19:09 +0300177 "{}, {}".format(mtus[0], mtus[2]),
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200178 "{}".format(res3)])
179
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300180 # Do iperf3 measurement #4
181 measurement4 = ("VM to VM in same project via Floating IP and VMs "
182 "are on different nodes, 1 thread; iperf3")
183 logger.info("Doing '{}' measurement...".format(measurement4))
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200184 result4 = transport1.exec_command(
185 'iperf3 -c {} -t {} | grep sender | tail -n 1'.format(
186 vm_info[2]['fip'], iperf_time))
187 res4 = (b" ".join(result4.split()[-4:-2:])).decode('utf-8')
188 logger.info("Result #4 is {}".format(res4))
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300189 table_rows.append([measurement4,
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200190 "{}".format(pair[0]),
191 "{}".format(pair[1]),
Ievgeniia Zadorozhna0facf3c2022-06-16 16:19:09 +0300192 "{}, {}".format(mtus[0], mtus[2]),
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200193 "{}".format(res4)])
194
195 # Do iperf3 measurement #5
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300196 measurement5 = ("VM to VM in same project, different HW nodes and "
197 "each VM is connected to separate network which are "
198 "connected using Router via Private IP, 1 thread; "
199 "iperf3")
200 logger.info("Doing '{}' measurement...".format(measurement5))
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200201 result5 = transport1.exec_command(
202 'iperf3 -c {} -t {} | grep sender | tail -n 1'.format(
203 vm_info[3]['private_address'], iperf_time))
204 res5 = (b" ".join(result5.split()[-4:-2:])).decode('utf-8')
205 logger.info("Result #5 is {}".format(res5))
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300206 table_rows.append([measurement5,
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200207 "{}".format(pair[0]),
208 "{}".format(pair[1]),
Ievgeniia Zadorozhna0facf3c2022-06-16 16:19:09 +0300209 "{}, {}".format(mtus[0], mtus[3]),
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200210 "{}".format(res5)])
211
212 logger.info("Drawing the table with iperf results...")
213 result_table.add_rows(table_rows)
Ievgeniia Zadorozhna97dfde42022-06-17 20:05:09 +0300214 sys.stdout.write('\n{}\n'.format(result_table.draw()))
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200215
Ievgeniia Zadorozhna9664b422023-03-28 21:09:46 +0300216 # Send the results to CSV file at reports/ directory
217 helpers.create_test_result_table_csv_file(
218 table_rows, request.node.name)
219
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200220 logger.info("Removing VMs and FIPs...")
221 for vm in vms:
222 openstack_clients.compute.servers.delete(vm)
Ievgeniia Zadorozhna97dfde42022-06-17 20:05:09 +0300223 logger.info("Removing FIPs...")
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200224 for fip in fips:
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +0300225 os_actions.delete_floating_ip(fip)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200226 except Exception as e:
Ievgeniia Zadorozhna97dfde42022-06-17 20:05:09 +0300227 sys.stdout.write("\n{}".format(e))
228 sys.stdout.write("\nSomething went wrong\n")
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200229 if 'vms' in locals():
230 logger.info("Removing VMs...")
231 for vm in vms:
232 openstack_clients.compute.servers.delete(vm)
233 if 'fips' in locals():
234 logger.info("Removing FIPs...")
235 for fip in fips:
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +0300236 os_actions.delete_floating_ip(fip)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200237 else:
Ievgeniia Zadorozhna97dfde42022-06-17 20:05:09 +0300238 sys.stdout.write("\nSkipping cleaning, VMs were not created")
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200239 pytest.fail("Something went wrong")