| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 1 | import logging | 
| Ievgeniia Zadorozhna | 97dfde4 | 2022-06-17 20:05:09 +0300 | [diff] [blame] | 2 | import sys | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 3 | import time | 
|  | 4 |  | 
|  | 5 | import pytest | 
|  | 6 | from texttable import Texttable | 
|  | 7 |  | 
|  | 8 | import utils | 
|  | 9 | from utils import os_client | 
|  | 10 | from utils import ssh | 
|  | 11 |  | 
|  | 12 |  | 
|  | 13 | logger = logging.getLogger(__name__) | 
|  | 14 |  | 
|  | 15 |  | 
|  | 16 | def test_vm2vm(openstack_clients, pair, os_resources, record_property): | 
|  | 17 | """ | 
|  | 18 | Simplified Performance Tests VM to VM test in different topologies | 
|  | 19 | 1. Create 4 VMs admin project | 
|  | 20 | 2. Associate floating IPs to the VMs | 
|  | 21 | 3. Connect to each VM via SSH and install iperf3 | 
|  | 22 | 4. Measure VM to VM on same node via Private IP, 1 thread | 
|  | 23 | 5. Measure VM to VM on different HW nodes via Private IP, 1 thread | 
| Ievgeniia Zadorozhna | 5ed74e2 | 2022-07-26 16:56:23 +0300 | [diff] [blame] | 24 | 6. Measure VM to VM on different HW nodes via Private IP, multiple threads | 
|  | 25 | (10 by default) | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 26 | 7. Measure VM to VM on different HW nodes via Floating IP, 1 thread | 
|  | 27 | 8. Measure VM to VM on different HW nodes, each VM is in separate network, | 
|  | 28 | the networks are connected using Router via Private IP, 1 thread | 
|  | 29 | 9. Draw the table with all pairs and results | 
|  | 30 | """ | 
|  | 31 | os_actions = os_client.OSCliActions(openstack_clients) | 
|  | 32 | config = utils.get_configuration() | 
|  | 33 | timeout = int(config.get('nova_timeout', 30)) | 
|  | 34 | iperf_time = int(config.get('iperf_time', 60)) | 
|  | 35 | private_key = os_resources['keypair'].private_key | 
|  | 36 | ssh_timeout = int(config.get('ssh_timeout', 500)) | 
| Ievgeniia Zadorozhna | 5ed74e2 | 2022-07-26 16:56:23 +0300 | [diff] [blame] | 37 | threads = int(config.get('multiple_threads_number', 10)) | 
| Ievgeniia Zadorozhna | 90aa802 | 2022-08-11 18:00:23 +0300 | [diff] [blame] | 38 | iperf_utility = config.get('multiple_threads_iperf_utility', 'iperf3') | 
|  | 39 | utils.check_iperf_utility(iperf_utility) | 
| Ievgeniia Zadorozhna | 5ed74e2 | 2022-07-26 16:56:23 +0300 | [diff] [blame] | 40 | result_table = Texttable(max_width=120) | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 41 |  | 
|  | 42 | try: | 
|  | 43 | zone1 = [service.zone for service in | 
|  | 44 | openstack_clients.compute.services.list() if | 
|  | 45 | service.host == pair[0]] | 
|  | 46 | zone2 = [service.zone for service in | 
|  | 47 | openstack_clients.compute.services.list() | 
|  | 48 | if service.host == pair[1]] | 
|  | 49 |  | 
|  | 50 | # create 4 VMs | 
|  | 51 | logger.info("Creating 4 VMs...") | 
|  | 52 | vm1 = os_actions.create_basic_server( | 
|  | 53 | os_resources['image_id'], os_resources['flavor_id'], | 
|  | 54 | os_resources['net1'], '{0}:{1}'.format(zone1[0], pair[0]), | 
| Ievgeniia Zadorozhna | 2c6469d | 2022-08-10 17:21:10 +0300 | [diff] [blame] | 55 | [os_resources['sec_group']['name']], os_resources['keypair'].name) | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 56 | logger.info("Created VM {}.".format(vm1.id)) | 
|  | 57 |  | 
|  | 58 | vm2 = os_actions.create_basic_server( | 
|  | 59 | os_resources['image_id'], os_resources['flavor_id'], | 
|  | 60 | os_resources['net1'], '{0}:{1}'.format(zone1[0], pair[0]), | 
| Ievgeniia Zadorozhna | 2c6469d | 2022-08-10 17:21:10 +0300 | [diff] [blame] | 61 | [os_resources['sec_group']['name']], os_resources['keypair'].name) | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 62 | logger.info("Created VM {}.".format(vm2.id)) | 
|  | 63 |  | 
|  | 64 | vm3 = os_actions.create_basic_server( | 
|  | 65 | os_resources['image_id'], os_resources['flavor_id'], | 
|  | 66 | os_resources['net1'], '{0}:{1}'.format(zone2[0], pair[1]), | 
| Ievgeniia Zadorozhna | 2c6469d | 2022-08-10 17:21:10 +0300 | [diff] [blame] | 67 | [os_resources['sec_group']['name']], os_resources['keypair'].name) | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 68 | logger.info("Created VM {}.".format(vm3.id)) | 
|  | 69 |  | 
|  | 70 | vm4 = os_actions.create_basic_server( | 
|  | 71 | os_resources['image_id'], os_resources['flavor_id'], | 
|  | 72 | os_resources['net2'], '{0}:{1}'.format(zone2[0], pair[1]), | 
| Ievgeniia Zadorozhna | 2c6469d | 2022-08-10 17:21:10 +0300 | [diff] [blame] | 73 | [os_resources['sec_group']['name']], os_resources['keypair'].name) | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 74 | logger.info("Created VM {}.".format(vm4.id)) | 
|  | 75 |  | 
|  | 76 | vm_info = [] | 
|  | 77 | vms = [] | 
|  | 78 | vms.extend([vm1, vm2, vm3, vm4]) | 
|  | 79 | fips = [] | 
|  | 80 | time.sleep(5) | 
|  | 81 |  | 
|  | 82 | # Associate FIPs and check VMs are Active | 
|  | 83 | logger.info("Creating Floating IPs and associating them...") | 
|  | 84 | for i in range(4): | 
| Ievgeniia Zadorozhna | 2c6469d | 2022-08-10 17:21:10 +0300 | [diff] [blame] | 85 | fip = os_actions.create_floating_ip(os_resources['ext_net']['id']) | 
|  | 86 | fips.append(fip['id']) | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 87 | os_actions.check_vm_is_active(vms[i].id, timeout=timeout) | 
| Ievgeniia Zadorozhna | 2c6469d | 2022-08-10 17:21:10 +0300 | [diff] [blame] | 88 | vms[i].add_floating_ip(fip['floating_ip_address']) | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 89 | private_address = vms[i].addresses[ | 
|  | 90 | list(vms[i].addresses.keys())[0]][0]['addr'] | 
| Ievgeniia Zadorozhna | 2c6469d | 2022-08-10 17:21:10 +0300 | [diff] [blame] | 91 | vm_info.append({'vm': vms[i], 'fip': fip['floating_ip_address'], | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 92 | 'private_address': private_address}) | 
|  | 93 | # Check VMs are reachable and prepare iperf3 | 
|  | 94 | transport1 = ssh.SSHTransport(vm_info[0]['fip'], 'ubuntu', | 
|  | 95 | password='dd', private_key=private_key) | 
| Ievgeniia Zadorozhna | 0facf3c | 2022-06-16 16:19:09 +0300 | [diff] [blame] | 96 | logger.info("Checking VMs are reachable via SSH, getting MTU...") | 
|  | 97 | mtus = [] | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 98 | for i in range(4): | 
|  | 99 | if transport1.check_vm_is_reachable_ssh( | 
|  | 100 | floating_ip=vm_info[i]['fip'], timeout=ssh_timeout): | 
|  | 101 | ssh.prepare_iperf(vm_info[i]['fip'], private_key=private_key) | 
| Ievgeniia Zadorozhna | 0facf3c | 2022-06-16 16:19:09 +0300 | [diff] [blame] | 102 | mtus.append(transport1.get_mtu_from_vm( | 
|  | 103 | vm_info[i]['fip'], private_key=private_key)) | 
|  | 104 | logger.info("MTU at networks: {}, {}".format(os_resources['net1']['mtu'], | 
|  | 105 | os_resources['net2']['mtu'])) | 
|  | 106 | logger.info("MTU at VMs: {}".format(", ".join(mtus))) | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 107 |  | 
|  | 108 | # Prepare the result table and run iperf3 | 
|  | 109 | table_rows = [] | 
| Ievgeniia Zadorozhna | 0facf3c | 2022-06-16 16:19:09 +0300 | [diff] [blame] | 110 | table_rows.append(['Test Case', 'Host 1', 'Host 2', | 
|  | 111 | 'MTU at VMs', 'Result']) | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 112 | # Do iperf3 measurement #1 | 
|  | 113 | logger.info("Doing 'VM to VM in same tenant on same node via Private " | 
|  | 114 | "IP, 1 thread' measurement...") | 
|  | 115 | result1 = transport1.exec_command( | 
|  | 116 | 'iperf3 -c {} -t {} | grep sender | tail -n 1'.format( | 
|  | 117 | vm_info[1]['private_address'], iperf_time)) | 
|  | 118 | res1 = (b" ".join(result1.split()[-4:-2:])).decode('utf-8') | 
|  | 119 | logger.info("Result #1 is {}".format(res1)) | 
|  | 120 | table_rows.append(['VM to VM in same tenant on same node via ' | 
| Ievgeniia Zadorozhna | 5ed74e2 | 2022-07-26 16:56:23 +0300 | [diff] [blame] | 121 | 'Private IP, 1 thread; iperf3', | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 122 | "{}".format(pair[0]), | 
|  | 123 | "{}".format(pair[0]), | 
| Ievgeniia Zadorozhna | 0facf3c | 2022-06-16 16:19:09 +0300 | [diff] [blame] | 124 | "{}, {}".format(mtus[0], mtus[1]), | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 125 | "{}".format(res1)]) | 
|  | 126 |  | 
|  | 127 | # Do iperf3 measurement #2 | 
|  | 128 | logger.info("Doing 'VM to VM in same tenant on different HW nodes " | 
|  | 129 | "via Private IP, 1 thread' measurement...") | 
|  | 130 | result2 = transport1.exec_command( | 
|  | 131 | 'iperf3 -c {} -t {} | grep sender | tail -n 1'.format( | 
|  | 132 | vm_info[2]['private_address'], iperf_time)) | 
|  | 133 | res2 = (b" ".join(result2.split()[-4:-2:])).decode('utf-8') | 
|  | 134 | logger.info("Result #2 is {}".format(res2)) | 
|  | 135 | table_rows.append(['VM to VM in same tenant on different HW nodes ' | 
| Ievgeniia Zadorozhna | 5ed74e2 | 2022-07-26 16:56:23 +0300 | [diff] [blame] | 136 | 'via Private IP, 1 thread; iperf3', | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 137 | "{}".format(pair[0]), | 
|  | 138 | "{}".format(pair[1]), | 
| Ievgeniia Zadorozhna | 0facf3c | 2022-06-16 16:19:09 +0300 | [diff] [blame] | 139 | "{}, {}".format(mtus[0], mtus[2]), | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 140 | "{}".format(res2)]) | 
|  | 141 |  | 
|  | 142 | # Do iperf3 measurement #3 | 
|  | 143 | logger.info("Doing 'VM to VM in same tenant on different HW nodes " | 
| Ievgeniia Zadorozhna | 5ed74e2 | 2022-07-26 16:56:23 +0300 | [diff] [blame] | 144 | "via Private IP, {} threads' measurement..." | 
|  | 145 | "".format(threads)) | 
| Ievgeniia Zadorozhna | 90aa802 | 2022-08-11 18:00:23 +0300 | [diff] [blame] | 146 | if iperf_utility == "iperf3": | 
|  | 147 | result3 = transport1.exec_command( | 
|  | 148 | '{} -c {} -P {} -t {} | grep sender | tail -n 1' | 
|  | 149 | ''.format(iperf_utility, vm_info[2]['private_address'], | 
|  | 150 | threads, iperf_time)) | 
|  | 151 | res3 = (b" ".join(result3.split()[-4:-2:])).decode('utf-8') | 
|  | 152 | else: | 
|  | 153 | iperf_utility = "iperf" | 
|  | 154 | result3 = transport1.exec_command( | 
|  | 155 | '{} -c {} -P {} -t {} | tail -n 1'.format(iperf_utility, | 
|  | 156 | vm_info[2]['private_address'], threads, iperf_time)) | 
|  | 157 | res3 = (b" ".join(result3.split()[-2::])).decode('utf-8') | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 158 | logger.info("Result #3 is {}".format(res3)) | 
|  | 159 | table_rows.append(['VM to VM in same tenant on different HW nodes ' | 
| Ievgeniia Zadorozhna | 90aa802 | 2022-08-11 18:00:23 +0300 | [diff] [blame] | 160 | 'via Private IP, {} threads; {}' | 
|  | 161 | ''.format(threads, iperf_utility), | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 162 | "{}".format(pair[0]), | 
|  | 163 | "{}".format(pair[1]), | 
| Ievgeniia Zadorozhna | 0facf3c | 2022-06-16 16:19:09 +0300 | [diff] [blame] | 164 | "{}, {}".format(mtus[0], mtus[2]), | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 165 | "{}".format(res3)]) | 
|  | 166 |  | 
| Ievgeniia Zadorozhna | 5ed74e2 | 2022-07-26 16:56:23 +0300 | [diff] [blame] | 167 | # Do iperf (v2) measurement #4 | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 168 | logger.info("Doing 'VM to VM in same tenant via Floating IP and VMs " | 
|  | 169 | "are on different nodes, 1 thread' measurement...") | 
|  | 170 | result4 = transport1.exec_command( | 
|  | 171 | 'iperf3 -c {} -t {} | grep sender | tail -n 1'.format( | 
|  | 172 | vm_info[2]['fip'], iperf_time)) | 
|  | 173 | res4 = (b" ".join(result4.split()[-4:-2:])).decode('utf-8') | 
|  | 174 | logger.info("Result #4 is {}".format(res4)) | 
|  | 175 | table_rows.append(['VM to VM in same tenant via Floating IP and VMs ' | 
| Ievgeniia Zadorozhna | 5ed74e2 | 2022-07-26 16:56:23 +0300 | [diff] [blame] | 176 | 'are on different nodes, 1 thread; iperf3', | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 177 | "{}".format(pair[0]), | 
|  | 178 | "{}".format(pair[1]), | 
| Ievgeniia Zadorozhna | 0facf3c | 2022-06-16 16:19:09 +0300 | [diff] [blame] | 179 | "{}, {}".format(mtus[0], mtus[2]), | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 180 | "{}".format(res4)]) | 
|  | 181 |  | 
|  | 182 | # Do iperf3 measurement #5 | 
|  | 183 | logger.info("Doing 'VM to VM in same tenant, different HW nodes and " | 
|  | 184 | "each VM is connected to separate network which are " | 
|  | 185 | " connected using Router via Private IP, 1 thread' " | 
|  | 186 | "measurement...") | 
|  | 187 | result5 = transport1.exec_command( | 
|  | 188 | 'iperf3 -c {} -t {} | grep sender | tail -n 1'.format( | 
|  | 189 | vm_info[3]['private_address'], iperf_time)) | 
|  | 190 | res5 = (b" ".join(result5.split()[-4:-2:])).decode('utf-8') | 
|  | 191 | logger.info("Result #5 is {}".format(res5)) | 
|  | 192 | table_rows.append(['VM to VM in same tenant, different HW nodes and ' | 
|  | 193 | 'each VM is connected to separate network which are' | 
| Ievgeniia Zadorozhna | 5ed74e2 | 2022-07-26 16:56:23 +0300 | [diff] [blame] | 194 | ' connected using Router via Private IP, 1 thread; ' | 
|  | 195 | 'iperf3', | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 196 | "{}".format(pair[0]), | 
|  | 197 | "{}".format(pair[1]), | 
| Ievgeniia Zadorozhna | 0facf3c | 2022-06-16 16:19:09 +0300 | [diff] [blame] | 198 | "{}, {}".format(mtus[0], mtus[3]), | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 199 | "{}".format(res5)]) | 
|  | 200 |  | 
|  | 201 | logger.info("Drawing the table with iperf results...") | 
|  | 202 | result_table.add_rows(table_rows) | 
| Ievgeniia Zadorozhna | 97dfde4 | 2022-06-17 20:05:09 +0300 | [diff] [blame] | 203 | sys.stdout.write('\n{}\n'.format(result_table.draw())) | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 204 |  | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 205 | logger.info("Removing VMs and FIPs...") | 
|  | 206 | for vm in vms: | 
|  | 207 | openstack_clients.compute.servers.delete(vm) | 
| Ievgeniia Zadorozhna | 97dfde4 | 2022-06-17 20:05:09 +0300 | [diff] [blame] | 208 | logger.info("Removing FIPs...") | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 209 | for fip in fips: | 
| Ievgeniia Zadorozhna | 2c6469d | 2022-08-10 17:21:10 +0300 | [diff] [blame] | 210 | os_actions.delete_floating_ip(fip) | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 211 | except Exception as e: | 
| Ievgeniia Zadorozhna | 97dfde4 | 2022-06-17 20:05:09 +0300 | [diff] [blame] | 212 | sys.stdout.write("\n{}".format(e)) | 
|  | 213 | sys.stdout.write("\nSomething went wrong\n") | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 214 | if 'vms' in locals(): | 
|  | 215 | logger.info("Removing VMs...") | 
|  | 216 | for vm in vms: | 
|  | 217 | openstack_clients.compute.servers.delete(vm) | 
|  | 218 | if 'fips' in locals(): | 
|  | 219 | logger.info("Removing FIPs...") | 
|  | 220 | for fip in fips: | 
| Ievgeniia Zadorozhna | 2c6469d | 2022-08-10 17:21:10 +0300 | [diff] [blame] | 221 | os_actions.delete_floating_ip(fip) | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 222 | else: | 
| Ievgeniia Zadorozhna | 97dfde4 | 2022-06-17 20:05:09 +0300 | [diff] [blame] | 223 | sys.stdout.write("\nSkipping cleaning, VMs were not created") | 
| Ievgeniia Zadorozhna | 8402302 | 2021-12-30 13:00:41 +0200 | [diff] [blame] | 224 | pytest.fail("Something went wrong") |