blob: d6a42420191982dbdcf8121cda693146ba1e0d4b [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 = [
113 executor.submit(ssh.install_iperf_at_vms_and_get_mtu, vm_info)
114 for vm_info in vm_info]
115 mtus = [future.result() for future in futures]
Ievgeniia Zadorozhnac67b86b2023-02-02 18:09:12 +0300116 logger.info("MTU at networks: {}, {}".format(
117 os_resources['net1']['mtu'], os_resources['net2']['mtu']))
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200118 # Prepare the result table and run iperf3
Ievgeniia Zadorozhnac67b86b2023-02-02 18:09:12 +0300119 table_rows = [[
120 'Test Case', 'Host 1', 'Host 2', 'MTU at VMs', 'Result'
121 ]]
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200122 # Do iperf3 measurement #1
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300123 measurement1 = ("VM to VM in same project on same node via Private "
124 "IP, 1 thread; iperf3")
125 logger.info("Doing '{}' measurement...".format(measurement1))
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200126 result1 = transport1.exec_command(
127 'iperf3 -c {} -t {} | grep sender | tail -n 1'.format(
128 vm_info[1]['private_address'], iperf_time))
129 res1 = (b" ".join(result1.split()[-4:-2:])).decode('utf-8')
130 logger.info("Result #1 is {}".format(res1))
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300131 table_rows.append([measurement1,
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200132 "{}".format(pair[0]),
133 "{}".format(pair[0]),
Ievgeniia Zadorozhna0facf3c2022-06-16 16:19:09 +0300134 "{}, {}".format(mtus[0], mtus[1]),
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200135 "{}".format(res1)])
136
137 # Do iperf3 measurement #2
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300138 measurement2 = ("VM to VM in same project on different HW nodes via "
139 "Private IP, 1 thread; iperf3")
140 logger.info("Doing '{}' measurement...".format(measurement2))
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200141 result2 = transport1.exec_command(
142 'iperf3 -c {} -t {} | grep sender | tail -n 1'.format(
143 vm_info[2]['private_address'], iperf_time))
144 res2 = (b" ".join(result2.split()[-4:-2:])).decode('utf-8')
145 logger.info("Result #2 is {}".format(res2))
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300146 table_rows.append([measurement2,
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200147 "{}".format(pair[0]),
148 "{}".format(pair[1]),
Ievgeniia Zadorozhna0facf3c2022-06-16 16:19:09 +0300149 "{}, {}".format(mtus[0], mtus[2]),
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200150 "{}".format(res2)])
151
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300152 # Do iperf/iperf3 measurement #3
153 measurement3 = ("VM to VM in same project on different HW nodes via "
154 "Private IP, {} threads; {}"
155 "".format(threads, iperf_utility))
156 logger.info("Doing '{}' measurement...".format(measurement3))
Ievgeniia Zadorozhna90aa8022022-08-11 18:00:23 +0300157 if iperf_utility == "iperf3":
158 result3 = transport1.exec_command(
159 '{} -c {} -P {} -t {} | grep sender | tail -n 1'
160 ''.format(iperf_utility, vm_info[2]['private_address'],
161 threads, iperf_time))
162 res3 = (b" ".join(result3.split()[-4:-2:])).decode('utf-8')
163 else:
164 iperf_utility = "iperf"
165 result3 = transport1.exec_command(
Ievgeniia Zadorozhnac67b86b2023-02-02 18:09:12 +0300166 '{} -c {} -P {} -t {} | tail -n 1'.format(
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300167 iperf_utility, vm_info[2]['private_address'], threads,
168 iperf_time))
Ievgeniia Zadorozhna90aa8022022-08-11 18:00:23 +0300169 res3 = (b" ".join(result3.split()[-2::])).decode('utf-8')
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200170 logger.info("Result #3 is {}".format(res3))
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300171 table_rows.append([measurement3,
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200172 "{}".format(pair[0]),
173 "{}".format(pair[1]),
Ievgeniia Zadorozhna0facf3c2022-06-16 16:19:09 +0300174 "{}, {}".format(mtus[0], mtus[2]),
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200175 "{}".format(res3)])
176
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300177 # Do iperf3 measurement #4
178 measurement4 = ("VM to VM in same project via Floating IP and VMs "
179 "are on different nodes, 1 thread; iperf3")
180 logger.info("Doing '{}' measurement...".format(measurement4))
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200181 result4 = transport1.exec_command(
182 'iperf3 -c {} -t {} | grep sender | tail -n 1'.format(
183 vm_info[2]['fip'], iperf_time))
184 res4 = (b" ".join(result4.split()[-4:-2:])).decode('utf-8')
185 logger.info("Result #4 is {}".format(res4))
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300186 table_rows.append([measurement4,
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200187 "{}".format(pair[0]),
188 "{}".format(pair[1]),
Ievgeniia Zadorozhna0facf3c2022-06-16 16:19:09 +0300189 "{}, {}".format(mtus[0], mtus[2]),
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200190 "{}".format(res4)])
191
192 # Do iperf3 measurement #5
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300193 measurement5 = ("VM to VM in same project, different HW nodes and "
194 "each VM is connected to separate network which are "
195 "connected using Router via Private IP, 1 thread; "
196 "iperf3")
197 logger.info("Doing '{}' measurement...".format(measurement5))
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200198 result5 = transport1.exec_command(
199 'iperf3 -c {} -t {} | grep sender | tail -n 1'.format(
200 vm_info[3]['private_address'], iperf_time))
201 res5 = (b" ".join(result5.split()[-4:-2:])).decode('utf-8')
202 logger.info("Result #5 is {}".format(res5))
Ievgeniia Zadorozhnaf22827b2022-07-20 13:30:32 +0300203 table_rows.append([measurement5,
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200204 "{}".format(pair[0]),
205 "{}".format(pair[1]),
Ievgeniia Zadorozhna0facf3c2022-06-16 16:19:09 +0300206 "{}, {}".format(mtus[0], mtus[3]),
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200207 "{}".format(res5)])
208
209 logger.info("Drawing the table with iperf results...")
210 result_table.add_rows(table_rows)
Ievgeniia Zadorozhna97dfde42022-06-17 20:05:09 +0300211 sys.stdout.write('\n{}\n'.format(result_table.draw()))
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200212
Ievgeniia Zadorozhna9664b422023-03-28 21:09:46 +0300213 # Send the results to CSV file at reports/ directory
214 helpers.create_test_result_table_csv_file(
215 table_rows, request.node.name)
216
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200217 logger.info("Removing VMs and FIPs...")
218 for vm in vms:
219 openstack_clients.compute.servers.delete(vm)
Ievgeniia Zadorozhna97dfde42022-06-17 20:05:09 +0300220 logger.info("Removing FIPs...")
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200221 for fip in fips:
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +0300222 os_actions.delete_floating_ip(fip)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200223 except Exception as e:
Ievgeniia Zadorozhna97dfde42022-06-17 20:05:09 +0300224 sys.stdout.write("\n{}".format(e))
225 sys.stdout.write("\nSomething went wrong\n")
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200226 if 'vms' in locals():
227 logger.info("Removing VMs...")
228 for vm in vms:
229 openstack_clients.compute.servers.delete(vm)
230 if 'fips' in locals():
231 logger.info("Removing FIPs...")
232 for fip in fips:
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +0300233 os_actions.delete_floating_ip(fip)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200234 else:
Ievgeniia Zadorozhna97dfde42022-06-17 20:05:09 +0300235 sys.stdout.write("\nSkipping cleaning, VMs were not created")
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200236 pytest.fail("Something went wrong")