blob: 51dccdd787527fb5665a805e82a0026c5845cd41 [file] [log] [blame]
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +02001import logging
Ievgeniia Zadorozhna97dfde42022-06-17 20:05:09 +03002import sys
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +02003import time
4
5import pytest
6from texttable import Texttable
7
8import utils
Ievgeniia Zadorozhna9664b422023-03-28 21:09:46 +03009from utils import helpers
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020010from utils import os_client
11from utils import ssh
12
13
14logger = logging.getLogger(__name__)
15
16
Ievgeniia Zadorozhna9664b422023-03-28 21:09:46 +030017def test_vm2vm(openstack_clients, pair, os_resources, request, html_report):
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020018 """
19 Simplified Performance Tests VM to VM test in different topologies
20 1. Create 4 VMs admin project
21 2. Associate floating IPs to the VMs
22 3. Connect to each VM via SSH and install iperf3
23 4. Measure VM to VM on same node via Private IP, 1 thread
24 5. Measure VM to VM on different HW nodes via Private IP, 1 thread
Ievgeniia Zadorozhna5ed74e22022-07-26 16:56:23 +030025 6. Measure VM to VM on different HW nodes via Private IP, multiple threads
26 (10 by default)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020027 7. Measure VM to VM on different HW nodes via Floating IP, 1 thread
28 8. Measure VM to VM on different HW nodes, each VM is in separate network,
29 the networks are connected using Router via Private IP, 1 thread
30 9. Draw the table with all pairs and results
31 """
32 os_actions = os_client.OSCliActions(openstack_clients)
33 config = utils.get_configuration()
34 timeout = int(config.get('nova_timeout', 30))
35 iperf_time = int(config.get('iperf_time', 60))
36 private_key = os_resources['keypair'].private_key
37 ssh_timeout = int(config.get('ssh_timeout', 500))
Ievgeniia Zadorozhna5ed74e22022-07-26 16:56:23 +030038 threads = int(config.get('multiple_threads_number', 10))
Ievgeniia Zadorozhna90aa8022022-08-11 18:00:23 +030039 iperf_utility = config.get('multiple_threads_iperf_utility', 'iperf3')
Ievgeniia Zadorozhnac67b86b2023-02-02 18:09:12 +030040 custom_mtu = config.get('custom_mtu') or 'default'
Ievgeniia Zadorozhna90aa8022022-08-11 18:00:23 +030041 utils.check_iperf_utility(iperf_utility)
Ievgeniia Zadorozhna5ed74e22022-07-26 16:56:23 +030042 result_table = Texttable(max_width=120)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020043
44 try:
45 zone1 = [service.zone for service in
46 openstack_clients.compute.services.list() if
47 service.host == pair[0]]
48 zone2 = [service.zone for service in
49 openstack_clients.compute.services.list()
50 if service.host == pair[1]]
51
52 # create 4 VMs
53 logger.info("Creating 4 VMs...")
54 vm1 = os_actions.create_basic_server(
55 os_resources['image_id'], os_resources['flavor_id'],
56 os_resources['net1'], '{0}:{1}'.format(zone1[0], pair[0]),
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +030057 [os_resources['sec_group']['name']], os_resources['keypair'].name)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020058 logger.info("Created VM {}.".format(vm1.id))
59
60 vm2 = os_actions.create_basic_server(
61 os_resources['image_id'], os_resources['flavor_id'],
62 os_resources['net1'], '{0}:{1}'.format(zone1[0], pair[0]),
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +030063 [os_resources['sec_group']['name']], os_resources['keypair'].name)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020064 logger.info("Created VM {}.".format(vm2.id))
65
66 vm3 = os_actions.create_basic_server(
67 os_resources['image_id'], os_resources['flavor_id'],
68 os_resources['net1'], '{0}:{1}'.format(zone2[0], pair[1]),
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +030069 [os_resources['sec_group']['name']], os_resources['keypair'].name)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020070 logger.info("Created VM {}.".format(vm3.id))
71
72 vm4 = os_actions.create_basic_server(
73 os_resources['image_id'], os_resources['flavor_id'],
74 os_resources['net2'], '{0}:{1}'.format(zone2[0], pair[1]),
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +030075 [os_resources['sec_group']['name']], os_resources['keypair'].name)
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020076 logger.info("Created VM {}.".format(vm4.id))
77
78 vm_info = []
79 vms = []
80 vms.extend([vm1, vm2, vm3, vm4])
81 fips = []
82 time.sleep(5)
83
84 # Associate FIPs and check VMs are Active
85 logger.info("Creating Floating IPs and associating them...")
86 for i in range(4):
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +030087 fip = os_actions.create_floating_ip(os_resources['ext_net']['id'])
88 fips.append(fip['id'])
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020089 os_actions.check_vm_is_active(vms[i].id, timeout=timeout)
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +030090 vms[i].add_floating_ip(fip['floating_ip_address'])
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020091 private_address = vms[i].addresses[
92 list(vms[i].addresses.keys())[0]][0]['addr']
Ievgeniia Zadorozhna2c6469d2022-08-10 17:21:10 +030093 vm_info.append({'vm': vms[i], 'fip': fip['floating_ip_address'],
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +020094 'private_address': private_address})
Ievgeniia Zadorozhnac67b86b2023-02-02 18:09:12 +030095 # Set custom MTU if required
96 if os_actions.is_cloud_tf() and (custom_mtu != "default"):
97 logger.info("Setting up custom MTU at network ports...")
98 for vm in vms:
99 os_actions.update_network_port_with_custom_mtu(vm.id,
100 custom_mtu)
101
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200102 # Check VMs are reachable and prepare iperf3
103 transport1 = ssh.SSHTransport(vm_info[0]['fip'], 'ubuntu',
104 password='dd', private_key=private_key)
Ievgeniia Zadorozhna0facf3c2022-06-16 16:19:09 +0300105 logger.info("Checking VMs are reachable via SSH, getting MTU...")
106 mtus = []
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200107 for i in range(4):
108 if transport1.check_vm_is_reachable_ssh(
109 floating_ip=vm_info[i]['fip'], timeout=ssh_timeout):
Ievgeniia Zadorozhnaa080ec02023-12-05 02:08:52 +0100110 ssh.IperfAtVM(
111 vm_info[i]['fip'], private_key=private_key)
Ievgeniia Zadorozhna0facf3c2022-06-16 16:19:09 +0300112 mtus.append(transport1.get_mtu_from_vm(
113 vm_info[i]['fip'], private_key=private_key))
Ievgeniia Zadorozhnac67b86b2023-02-02 18:09:12 +0300114 logger.info("MTU at networks: {}, {}".format(
115 os_resources['net1']['mtu'], os_resources['net2']['mtu']))
Ievgeniia Zadorozhna0facf3c2022-06-16 16:19:09 +0300116 logger.info("MTU at VMs: {}".format(", ".join(mtus)))
Ievgeniia Zadorozhna84023022021-12-30 13:00:41 +0200117
118 # 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")