def test_network_connectivity_to_v_m_during_live_migration(self): """This test checks network connectivity to VM during Live Migration Steps: 1. Create a floating ip 2. Create an instance from an image with 'm1.micro' flavor 3. Add the floating ip to the instance 4. Ping the instance by the floating ip 5. Execute live migration 6. Check current hypervisor and status of instance 7. Check that packets loss was minimal """ net = self.get_admin_int_net_id() image_id = [image.id for image in self.nova.images.list() if image.name == 'TestVM'][0] flavor = [flavor for flavor in self.nova.flavors.list() if flavor.name == 'm1.micro'][0] floating_ip = self.nova.floating_ips.create() self.floating_ips.append(floating_ip) self.assertIn(floating_ip.ip, [fip_info.ip for fip_info in self.nova.floating_ips.list()]) inst = common_functions.create_instance(self.nova, "inst_2238776_{}" .format(flavor.name), flavor.id, net, [self.sec_group.id], image_id=image_id, inst_list=self.instances) self.instances.append(inst.id) inst.add_floating_ip(floating_ip.ip) ping = common_functions.ping_command(floating_ip.ip) self.assertTrue(ping, "Instance is not reachable") self.live_migration(inst, floating_ip.ip)
def test_resize_down_an_instance_booted_from_volume(self): """This test checks that nova allows resize down an instance booted from volume Steps: 1. Create bootable volume 2. Boot instance from newly created volume 3. Resize instance from m1.small to m1.tiny """ # 1. Create bootable volume image_id = [image.id for image in self.nova.images.list() if image.name == 'TestVM'][0] volume = common_functions.create_volume(self.cinder, image_id, timeout=60) self.volumes.append(volume) # 2. Create instance from newly created volume, associate floating_ip name = 'TestVM_543355_instance_to_resize' networks = self.neutron.list_networks()['networks'] net = [net['id'] for net in networks if not net['router:external']][0] flavor_list = {f.name: f.id for f in self.nova.flavors.list()} initial_flavor = flavor_list['m1.small'] resize_flavor = flavor_list['m1.tiny'] bdm = {'vda': volume.id} instance = common_functions.create_instance(self.nova, name, initial_flavor, net, [self.sec_group.name], block_device_mapping=bdm, inst_list=self.instances) self.instances.append(instance.id) # Assert for attached volumes attached_volumes = self.nova.servers.get(instance).to_dict()[ 'os-extended-volumes:volumes_attached'] self.assertIn({'id': volume.id}, attached_volumes) # Assert to flavor size self.assertEqual(self.nova.servers.get(instance).flavor['id'], initial_flavor, "Unexpected instance flavor before resize") floating_ip = self.nova.floating_ips.create() self.floating_ips.append(floating_ip.ip) instance.add_floating_ip(floating_ip.ip) # 3. Resize from m1.small to m1.tiny self.nova.servers.resize(instance, resize_flavor) common_functions.check_inst_status(self.nova, instance.id, 'VERIFY_RESIZE', 60) self.nova.servers.confirm_resize(instance) common_functions.check_inst_status(self.nova, instance.id, 'ACTIVE', 60) self.assertEqual(self.nova.servers.get(instance).flavor['id'], resize_flavor, "Unexpected instance flavor after resize") # Check that instance is reachable ping = common_functions.ping_command(floating_ip.ip) self.assertTrue(ping, "Instance after resize is not reachable")
def test_network_connectivity_to_v_m_during_live_migration(self): """This test checks network connectivity to VM during Live Migration Steps: 1. Create a floating ip 2. Create an instance from an image with 'm1.micro' flavor 3. Add the floating ip to the instance 4. Ping the instance by the floating ip 5. Execute live migration 6. Check current hypervisor and status of instance 7. Check that packets loss was minimal """ networks = self.neutron.list_networks()['networks'] net = [net['id'] for net in networks if not net['router:external']][0] image_id = [image.id for image in self.nova.images.list() if image.name == 'TestVM'][0] flavor = [flavor for flavor in self.nova.flavors.list() if flavor.name == 'm1.micro'][0] floating_ip = self.nova.floating_ips.create() self.floating_ips.append(floating_ip) self.assertIn(floating_ip.ip, [fip_info.ip for fip_info in self.nova.floating_ips.list()]) inst = common_functions.create_instance(self.nova, "inst_2238776_{}" .format(flavor.name), flavor.id, net, [self.sec_group.name], image_id=image_id, inst_list=self.instances) self.instances.append(inst.id) inst.add_floating_ip(floating_ip.ip) ping = common_functions.ping_command(floating_ip.ip) self.assertTrue(ping, "Instance is not reachable") hypervisors = {h.hypervisor_hostname: h for h in self.nova.hypervisors.list()} old_hyper = getattr(inst, "OS-EXT-SRV-ATTR:hypervisor_hostname") new_hyper = [h for h in hypervisors.keys() if h != old_hyper][0] ping = subprocess.Popen(["/bin/ping", "-c100", "-i1", floating_ip.ip], stdout=subprocess.PIPE) self.nova.servers.live_migrate(inst, new_hyper, block_migration=False, disk_over_commit=False) inst = self.nova.servers.get(inst.id) timeout = 5 end_time = time() + 60 * timeout while getattr(inst, "OS-EXT-SRV-ATTR:hypervisor_hostname") != \ new_hyper: if time() > end_time: msg = "Hypervisor is not changed after live migration" raise AssertionError(msg) sleep(1) inst = self.nova.servers.get(inst.id) self.assertEqual(inst.status, 'ACTIVE') ping.wait() output = ping.stdout.read().split('\n')[-3].split() packets = {'transmitted': int(output[0]), 'received': int(output[3])} loss = packets['transmitted'] - packets['received'] if loss > 5: msg = "Packets loss exceeds the limit, {} packets were lost" raise AssertionError(msg.format(loss))
def test_boot_instance_from_volume_bigger_than_flavor_size(self): """This test checks that nova allows creation instance from volume with size bigger than flavor size Steps: 1. Create volume with size 2Gb. 2. Boot instance with flavor size 'tiny' from newly created volume 3. Check that instance created with correct values """ # 1. Create volume image_id = [image.id for image in self.nova.images.list() if image.name == 'TestVM'][0] volume = common_functions.create_volume(self.cinder, image_id, size=2, timeout=60) self.volumes.append(volume) # 2. Create router, network, subnet, connect them to external network exist_networks = self.os_conn.list_networks()['networks'] ext_network = [x for x in exist_networks if x.get('router:external')][0] self.router = self.os_conn.create_router(name="router01")['router'] self.os_conn.router_gateway_add(router_id=self.router['id'], network_id=ext_network['id']) net_id = self.os_conn.add_net(self.router['id']) # 3. Create instance from newly created volume, associate floating_ip name = 'TestVM_1517671_instance' flavor_list = {f.name: f.id for f in self.nova.flavors.list()} initial_flavor_id = flavor_list['m1.tiny'] bdm = {'vda': volume.id} instance = common_functions.create_instance(self.nova, name, initial_flavor_id, net_id, [self.sec_group.id], block_device_mapping=bdm, inst_list=self.instances) self.instances.append(instance.id) # Assert for attached volumes attached_volumes = self.nova.servers.get(instance).to_dict()[ 'os-extended-volumes:volumes_attached'] self.assertIn({'id': volume.id}, attached_volumes) # Assert to flavor size self.assertEqual(self.nova.servers.get(instance).flavor['id'], initial_flavor_id, "Unexpected instance flavor after creation") floating_ip = self.nova.floating_ips.create() self.floating_ips.append(floating_ip) instance.add_floating_ip(floating_ip.ip) # Check that instance is reachable ping = common_functions.ping_command(floating_ip.ip) self.assertTrue(ping, "Instance after creation is not reachable")
def test_nova_launch_v_m_from_volume_with_all_flavours(self): """This test case checks creation of instance from volume with all types of flavor. For this test we need node with compute role: 8 VCPUs, 16+GB RAM and 160+GB disk for any compute Steps: 1. Create bootable volume 1. Create a floating ip 2. Create an instance from an image with some flavor 3. Add the floating ip to the instance 4. Ping the instance by the floating ip 5. Delete the floating ip 6. delete the instance 7. Repeat all steps for all types of flavor """ image_id = [ image.id for image in self.nova.images.list() if image.name == 'TestVM' ][0] networks = self.neutron.list_networks()['networks'] net = [net['id'] for net in networks if not net['router:external']][0] flavor_list = self.nova.flavors.list() volume = common_functions.create_volume(self.cinder, image_id) self.volumes.append(volume) bdm = {'vda': volume.id} for flavor in flavor_list: floating_ip = self.nova.floating_ips.create() self.floating_ips.append(floating_ip) self.assertIn( floating_ip.ip, [fip_info.ip for fip_info in self.nova.floating_ips.list()]) inst = common_functions.create_instance(self.nova, "inst_543360_{}".format( flavor.name), flavor.id, net, [self.sec_group.name], block_device_mapping=bdm, inst_list=self.instances) inst.add_floating_ip(floating_ip.ip) self.assertTrue( common_functions.check_ip(self.nova, inst.id, floating_ip.ip)) ping = common_functions.ping_command(floating_ip.ip) common_functions.delete_instance(self.nova, inst.id) self.assertTrue(ping, "Instance is not reachable")
def test_nova_launch_v_m_from_volume_with_all_flavours(self): """This test case checks creation of instance from volume with all types of flavor. For this test needs 2 nodes with compute role: 20Gb RAM and 150GB disk for each Steps: 1. Create bootable volume 1. Create a floating ip 2. Create an instance from an image with some flavor 3. Add the floating ip to the instance 4. Ping the instance by the floating ip 5. Delete the floating ip 6. delete the instance 7. Repeat all steps for all types of flavor """ image_id = [image.id for image in self.nova.images.list() if image.name == 'TestVM'][0] networks = self.neutron.list_networks()['networks'] net = [net['id'] for net in networks if not net['router:external']][0] flavor_list = self.nova.flavors.list() for flavor in flavor_list: floating_ip = self.nova.floating_ips.create() self.floating_ips.append(floating_ip) self.assertIn(floating_ip.ip, [fip_info.ip for fip_info in self.nova.floating_ips.list()]) volume = common_functions.create_volume(self.cinder, image_id) self.volumes.append(volume) bdm = {'vda': volume.id} inst = common_functions.create_instance(self.nova, "inst_543360_{}" .format(flavor.name), flavor.id, net, [self.sec_group.name], block_device_mapping=bdm, inst_list=self.instances) inst_id = inst.id self.instances.append(inst_id) inst.add_floating_ip(floating_ip.ip) self.assertTrue(common_functions.check_ip(self.nova, inst_id, floating_ip.ip)) ping = common_functions.ping_command(floating_ip.ip) self.assertTrue(ping, "Instance is not reachable")
def test_network_connectivity_to_v_m_during_live_migration(self): """This test checks network connectivity to VM during Live Migration Steps: 1. Create a floating ip 2. Create an instance from an image with 'm1.micro' flavor 3. Add the floating ip to the instance 4. Ping the instance by the floating ip 5. Execute live migration 6. Check current hypervisor and status of instance 7. Check that packets loss was minimal """ networks = self.neutron.list_networks()['networks'] net = [net['id'] for net in networks if not net['router:external']][0] image_id = [ image.id for image in self.nova.images.list() if image.name == 'TestVM' ][0] flavor = [ flavor for flavor in self.nova.flavors.list() if flavor.name == 'm1.micro' ][0] floating_ip = self.nova.floating_ips.create() self.floating_ips.append(floating_ip) self.assertIn( floating_ip.ip, [fip_info.ip for fip_info in self.nova.floating_ips.list()]) inst = common_functions.create_instance(self.nova, "inst_2238776_{}".format( flavor.name), flavor.id, net, [self.sec_group.name], image_id=image_id, inst_list=self.instances) self.instances.append(inst.id) inst.add_floating_ip(floating_ip.ip) ping = common_functions.ping_command(floating_ip.ip) self.assertTrue(ping, "Instance is not reachable") self.live_migration(inst, floating_ip.ip)
def test_nova_launch_v_m_from_volume_with_all_flavours(self): """This test case checks creation of instance from volume with all types of flavor. For this test we need node with compute role: 8 VCPUs, 16+GB RAM and 160+GB disk for any compute Steps: 1. Create bootable volume 1. Create a floating ip 2. Create an instance from an image with some flavor 3. Add the floating ip to the instance 4. Ping the instance by the floating ip 5. Delete the floating ip 6. delete the instance 7. Repeat all steps for all types of flavor """ image_id = [image.id for image in self.nova.images.list() if image.name == 'TestVM'][0] net = self.get_admin_int_net_id() flavor_list = self.nova.flavors.list() volume = common_functions.create_volume(self.cinder, image_id) self.volumes.append(volume) bdm = {'vda': volume.id} for flavor in flavor_list: floating_ip = self.nova.floating_ips.create() self.floating_ips.append(floating_ip) self.assertIn(floating_ip.ip, [fip_info.ip for fip_info in self.nova.floating_ips.list()]) inst = common_functions.create_instance(self.nova, "inst_543360_{}" .format(flavor.name), flavor.id, net, [self.sec_group.id], block_device_mapping=bdm, inst_list=self.instances) inst.add_floating_ip(floating_ip.ip) self.assertTrue(common_functions.check_ip(self.nova, inst.id, floating_ip.ip)) ping = common_functions.ping_command(floating_ip.ip) common_functions.delete_instance(self.nova, inst.id) self.assertTrue(ping, "Instance is not reachable")
def test_delete_instance_in_resize_state(self): """Delete an instance while it is in resize state Steps: 1. Create a new instance 2. Resize instance from m1.small to m1.tiny 3. Delete the instance immediately after vm_state is 'RESIZE' 4. Check that the instance was successfully deleted 5. Repeat steps 1-4 some times """ name = 'TestVM_857431_instance_to_resize' admin_net = self.get_admin_int_net_id() initial_flavor = self.nova.flavors.find(name='m1.small') resize_flavor = self.nova.flavors.find(name='m1.tiny') image_id = self.nova.images.find(name='TestVM') for _ in range(10): instance = common_functions.create_instance( self.nova, name, initial_flavor, admin_net, [self.sec_group.id], image_id=image_id, inst_list=self.instances) # resize instance instance.resize(resize_flavor) common_functions.wait( lambda: (self.os_conn.server_status_is(instance, 'RESIZE') or self.os_conn.server_status_is(instance, 'VERIFY_RESIZE')), timeout_seconds=2 * 60, waiting_for='instance state is RESIZE or VERIFY_RESIZE') # check that instance can be deleted common_functions.delete_instance(self.nova, instance.id) assert instance not in self.nova.servers.list()
def test_nova_launch_v_m_from_image_with_all_flavours(self): """This test case checks creation of instance from image with all types of flavor. For this test we need node with compute role: 8 VCPUs, 16+GB RAM and 160+GB disk for any compute Steps: 1. Create a floating ip 2. Create an instance from an image with some flavor 3. Add the floating ip to the instance 4. Ping the instance by the floating ip 5. Delete the floating ip 6. delete the instance 7. Repeat all steps for all types of flavor """ networks = self.neutron.list_networks()['networks'] net = [net['id'] for net in networks if not net['router:external']][0] image_id = [image.id for image in self.nova.images.list() if image.name == 'TestVM'][0] flavor_list = self.nova.flavors.list() for flavor in flavor_list: floating_ip = self.nova.floating_ips.create() self.floating_ips.append(floating_ip) self.assertIn(floating_ip.ip, [fip_info.ip for fip_info in self.nova.floating_ips.list()]) inst = common_functions.create_instance(self.nova, "inst_543358_{}" .format(flavor.name), flavor.id, net, [self.sec_group.name], image_id=image_id, inst_list=self.instances) inst.add_floating_ip(floating_ip.ip) self.assertTrue(common_functions.check_ip(self.nova, inst.id, floating_ip.ip)) ping = common_functions.ping_command(floating_ip.ip) common_functions.delete_instance(self.nova, inst.id) self.assertTrue(ping, "Instance is not reachable")
def test_live_migration_of_v_ms_with_data_on_root_and_ephemeral_disk(self): """This test checks Live Migration of VMs with data on root and ephemeral disk Steps: 1. Create flavor with ephemeral disk 2. Create a floating ip 3. Create an instance from an image with 'm1.ephemeral' flavor 4. Add the floating ip to the instance 5. Ssh to instance and create timestamp on root and ephemeral disks 6. Ping the instance by the floating ip 7. Execute live migration 8. Check current hypervisor and status of instance 9. Check that packets loss was minimal 10. Ssh to instance and check timestamp on root and ephemeral disks """ net = self.get_admin_int_net_id() image_id = [image.id for image in self.nova.images.list() if image.name == 'TestVM'][0] flavor = self.nova.flavors.create("m1.ephemeral", 64, 1, 1, ephemeral=1, is_public=True) self.flavors.append(flavor) floating_ip = self.nova.floating_ips.create() self.floating_ips.append(floating_ip) self.assertIn(floating_ip.ip, [fip_info.ip for fip_info in self.nova.floating_ips.list()]) keys = self.nova.keypairs.create('key_2238776') self.keys.append(keys) private_key = paramiko.RSAKey.from_private_key(six.StringIO(str( keys.private_key))) inst = common_functions.create_instance(self.nova, "inst_2238776_{}" .format(flavor.name), flavor.id, net, [self.sec_group.id], image_id=image_id, key_name='key_2238776', inst_list=self.instances) self.instances.append(inst.id) inst.add_floating_ip(floating_ip.ip) ping = common_functions.ping_command(floating_ip.ip, i=10) self.assertTrue(ping, "Instance is not reachable") out = [] with SSHClient(host=floating_ip.ip, username="******", password=None, private_keys=[private_key]) as vm_r: out.append(vm_r.execute("sudo sh -c 'date > /timestamp.txt'")) out.append(vm_r.execute("sudo sh -c 'date > /mnt/timestamp.txt'")) out.append(vm_r.execute("sudo -i cat /timestamp.txt")) out.append(vm_r.execute("sudo -i cat /mnt/timestamp.txt")) for i in out: if i.get('stderr'): raise Exception("ssh commands were executed with errors") root_data = out[-2]['stdout'][0] ephem_data = out[-1]['stdout'][0] self.live_migration(inst, floating_ip.ip) out = [] with SSHClient(host=floating_ip.ip, username="******", password=None, private_keys=[private_key]) as vm_r: out.append(vm_r.execute("sudo -i cat /timestamp.txt")) out.append(vm_r.execute("sudo -i cat /mnt/timestamp.txt")) for i in out: if i.get('stderr'): raise Exception("ssh commands were executed with errors") r_data = out[0]['stdout'][0] ep_data = out[1]['stdout'][0] self.assertEqual(root_data, r_data, "Data on root disk is changed") self.assertEqual(ephem_data, ep_data, "Data on ephemeral disk is " "changed")
def test_live_migration_of_v_ms_with_data_on_root_and_ephemeral_disk(self): """This test checks Live Migration of VMs with data on root and ephemeral disk Steps: 1. Create flavor with ephemeral disk 2. Create a floating ip 3. Create an instance from an image with 'm1.ephemeral' flavor 4. Add the floating ip to the instance 5. Ssh to instance and create timestamp on root and ephemeral disks 6. Ping the instance by the floating ip 7. Execute live migration 8. Check current hypervisor and status of instance 9. Check that packets loss was minimal 10. Ssh to instance and check timestamp on root and ephemeral disks """ networks = self.neutron.list_networks()['networks'] net = [net['id'] for net in networks if not net['router:external']][0] image_id = [ image.id for image in self.nova.images.list() if image.name == 'TestVM' ][0] flavor = self.nova.flavors.create("m1.ephemeral", 64, 1, 1, ephemeral=1, is_public=True) self.flavors.append(flavor) floating_ip = self.nova.floating_ips.create() self.floating_ips.append(floating_ip) self.assertIn( floating_ip.ip, [fip_info.ip for fip_info in self.nova.floating_ips.list()]) keys = self.nova.keypairs.create('key_2238776') self.keys.append(keys) private_key = paramiko.RSAKey.from_private_key( six.StringIO(str(keys.private_key))) inst = common_functions.create_instance(self.nova, "inst_2238776_{}".format( flavor.name), flavor.id, net, [self.sec_group.name], image_id=image_id, key_name='key_2238776', inst_list=self.instances) self.instances.append(inst.id) inst.add_floating_ip(floating_ip.ip) ping = common_functions.ping_command(floating_ip.ip, i=10) self.assertTrue(ping, "Instance is not reachable") out = [] with SSHClient(host=floating_ip.ip, username="******", password=None, private_keys=[private_key]) as vm_r: out.append(vm_r.execute("sudo sh -c 'date > /timestamp.txt'")) out.append(vm_r.execute("sudo sh -c 'date > /mnt/timestamp.txt'")) out.append(vm_r.execute("sudo -i cat /timestamp.txt")) out.append(vm_r.execute("sudo -i cat /mnt/timestamp.txt")) for i in out: if i.get('stderr'): raise Exception("ssh commands were executed with errors") root_data = out[-2]['stdout'][0] ephem_data = out[-1]['stdout'][0] self.live_migration(inst, floating_ip.ip) out = [] with SSHClient(host=floating_ip.ip, username="******", password=None, private_keys=[private_key]) as vm_r: out.append(vm_r.execute("sudo -i cat /timestamp.txt")) out.append(vm_r.execute("sudo -i cat /mnt/timestamp.txt")) for i in out: if i.get('stderr'): raise Exception("ssh commands were executed with errors") r_data = out[0]['stdout'][0] ep_data = out[1]['stdout'][0] self.assertEqual(root_data, r_data, "Data on root disk is changed") self.assertEqual(ephem_data, ep_data, "Data on ephemeral disk is " "changed")
def setUp(self): super(self.__class__, self).setUp() # Get path on node to 'images' dir self.image_name = os.path.join(settings.TEST_IMAGE_PATH, settings.WIN_SERVER_QCOW2) self.uid_list = [] # timeouts (in minutes) self.ping_timeout = 3 self.hypervisor_timeout = 10 self.amount_of_images_before = len(list(self.glance.images.list())) self.image = None self.our_own_flavor_was_created = False self.expected_flavor_id = 3 self.instance = None self.security_group_name = "ms_compatibility" # protect for multiple definition of the same group for sg in self.nova.security_groups.list(): if sg.name == self.security_group_name: self.nova.security_groups.delete(sg) # adding required security group self.the_security_group = self.nova.security_groups.create( name=self.security_group_name, description="Windows Compatibility" ) # Add rules for ICMP, TCP/22 self.icmp_rule = self.nova.security_group_rules.create( self.the_security_group.id, ip_protocol="icmp", from_port=-1, to_port=-1, cidr="0.0.0.0/0" ) self.tcp_rule = self.nova.security_group_rules.create( self.the_security_group.id, ip_protocol="tcp", from_port=22, to_port=22, cidr="0.0.0.0/0" ) # Add both rules to default group self.default_security_group_id = 0 for sg in self.nova.security_groups.list(): if sg.name == "default": self.default_security_group_id = sg.id break self.icmp_rule_default = self.nova.security_group_rules.create( self.default_security_group_id, ip_protocol="icmp", from_port=-1, to_port=-1, cidr="0.0.0.0/0" ) self.tcp_rule_default = self.nova.security_group_rules.create( self.default_security_group_id, ip_protocol="tcp", from_port=22, to_port=22, cidr="0.0.0.0/0" ) # adding floating ip self.floating_ip = self.nova.floating_ips.create(self.nova.floating_ip_pools.list()[0].name) # creating of the image self.image = self.glance.images.create(name="MyTestSystem", disk_format="qcow2", container_format="bare") with open(self.image_name, "rb") as win_image_file: self.glance.images.upload(self.image.id, win_image_file) # check that required image in active state is_activated = False while not is_activated: for image_object in self.glance.images.list(): if image_object.id == self.image.id: self.image = image_object logger.info("Image in the {} state".format(self.image.status)) if self.image.status == "active": is_activated = True break time.sleep(1) # Default - the first network_id = self.nova.networks.list()[0].id # More detailed check of network list for network in self.nova.networks.list(): if "internal" in network.label: network_id = network.id logger.info("Starting with network interface id {}".format(network_id)) # TODO(mlaptev) add check flavor parameters vs. vm parameters # Collect information about the medium flavor and create a copy of it for flavor in self.nova.flavors.list(): # TODO(rpromyshlennikov): change flavor to medium if we will have # memory issues on windows and CI will be ready for it if "small" in flavor.name and "copy.of." not in flavor.name: new_flavor_name = "copy.of." + flavor.name new_flavor_id = common_functions.get_flavor_id_by_name(self.nova, new_flavor_name) # delete the flavor if it already exists if new_flavor_id is not None: common_functions.delete_flavor(self.nova, new_flavor_id) # create the flavor for our needs expected_flavor = self.nova.flavors.create( name=new_flavor_name, ram=flavor.ram, vcpus=1, disk=flavor.disk # Only one VCPU ) self.expected_flavor_id = expected_flavor.id self.our_own_flavor_was_created = True break logger.info("Starting with flavor {}".format(self.nova.flavors.get(self.expected_flavor_id))) # nova boot self.instance = common_functions.create_instance( nova_client=self.nova, inst_name="MyTestSystemWithNova", flavor_id=self.expected_flavor_id, net_id=network_id, security_groups=[self.the_security_group.name, "default"], image_id=self.image.id, ) logger.info("Using following floating ip {}".format(self.floating_ip.ip)) self.instance.add_floating_ip(self.floating_ip) self.assertTrue(common_functions.check_ip(self.nova, self.instance.id, self.floating_ip.ip)) self.wait_instance_to_boot()
def setUp(self): super(self.__class__, self).setUp() # Get path on node to 'images' dir self.image_name = os.path.join(settings.TEST_IMAGE_PATH, settings.WIN_SERVER_QCOW2) self.uid_list = [] # timeouts (in minutes) self.ping_timeout = 3 self.hypervisor_timeout = 10 self.amount_of_images_before = len(list(self.glance.images.list())) self.image = None self.our_own_flavor_was_created = False self.expected_flavor_id = 3 self.instance = None self.security_group_name = "ms_compatibility" # protect for multiple definition of the same group for sg in self.nova.security_groups.list(): if sg.name == self.security_group_name: self.nova.security_groups.delete(sg) # adding required security group self.the_security_group = self.nova.security_groups.create( name=self.security_group_name, description="Windows Compatibility") # Add rules for ICMP, TCP/22 self.icmp_rule = self.nova.security_group_rules.create( self.the_security_group.id, ip_protocol="icmp", from_port=-1, to_port=-1, cidr="0.0.0.0/0") self.tcp_rule = self.nova.security_group_rules.create( self.the_security_group.id, ip_protocol="tcp", from_port=22, to_port=22, cidr="0.0.0.0/0") # Add both rules to default group self.default_security_group_id = 0 for sg in self.nova.security_groups.list(): if sg.name == 'default': self.default_security_group_id = sg.id break self.icmp_rule_default = self.nova.security_group_rules.create( self.default_security_group_id, ip_protocol="icmp", from_port=-1, to_port=-1, cidr="0.0.0.0/0") self.tcp_rule_default = self.nova.security_group_rules.create( self.default_security_group_id, ip_protocol="tcp", from_port=22, to_port=22, cidr="0.0.0.0/0") # adding floating ip self.floating_ip = self.nova.floating_ips.create( self.nova.floating_ip_pools.list()[0].name) # creating of the image self.image = self.glance.images.create( name='MyTestSystem', disk_format='qcow2', container_format='bare') with open(self.image_name, 'rb') as win_image_file: self.glance.images.upload( self.image.id, win_image_file) # check that required image in active state is_activated = False while not is_activated: for image_object in self.glance.images.list(): if image_object.id == self.image.id: self.image = image_object logger.info( "Image in the {} state".format(self.image.status)) if self.image.status == 'active': is_activated = True break time.sleep(1) # Default - the first network_id = self.nova.networks.list()[0].id # More detailed check of network list for network in self.nova.networks.list(): if 'internal' in network.label: network_id = network.id logger.info("Starting with network interface id {}".format(network_id)) # TODO(mlaptev) add check flavor parameters vs. vm parameters # Collect information about the medium flavor and create a copy of it for flavor in self.nova.flavors.list(): # TODO(rpromyshlennikov): change flavor to medium if we will have # memory issues on windows and CI will be ready for it if 'small' in flavor.name and 'copy.of.' not in flavor.name: new_flavor_name = "copy.of." + flavor.name new_flavor_id = common_functions.get_flavor_id_by_name( self.nova, new_flavor_name) # delete the flavor if it already exists if new_flavor_id is not None: common_functions.delete_flavor(self.nova, new_flavor_id) # create the flavor for our needs expected_flavor = self.nova.flavors.create( name=new_flavor_name, ram=flavor.ram, vcpus=1, # Only one VCPU disk=flavor.disk) self.expected_flavor_id = expected_flavor.id self.our_own_flavor_was_created = True break logger.info("Starting with flavor {}".format( self.nova.flavors.get(self.expected_flavor_id))) # nova boot self.instance = common_functions.create_instance( nova_client=self.nova, inst_name="MyTestSystemWithNova", flavor_id=self.expected_flavor_id, net_id=network_id, security_groups=[self.the_security_group.name, 'default'], image_id=self.image.id) logger.info("Using following floating ip {}".format( self.floating_ip.ip)) self.instance.add_floating_ip(self.floating_ip) self.assertTrue(common_functions.check_ip(self.nova, self.instance.id, self.floating_ip.ip)) self.wait_instance_to_boot()
def test_live_migration_of_v_ms_with_data_on_root_and_ephemeral_disk(self): """This test checks Live Migration of VMs with data on root and ephemeral disk Steps: 1. Create flavor with ephemeral disk 2. Create a floating ip 3. Create an instance from an image with 'm1.ephemeral' flavor 4. Add the floating ip to the instance 5. Ssh to instance and create timestamp on root and ephemeral disks 6. Ping the instance by the floating ip 7. Execute live migration 8. Check current hypervisor and status of instance 9. Check that packets loss was minimal 10. Ssh to instance and check timestamp on root and ephemeral disks """ networks = self.neutron.list_networks()['networks'] net = [net['id'] for net in networks if not net['router:external']][0] image_id = [image.id for image in self.nova.images.list() if image.name == 'TestVM'][0] flavor = self.nova.flavors.create("m1.ephemeral", 64, 1, 1, ephemeral=1, is_public=True) self.flavors.append(flavor) floating_ip = self.nova.floating_ips.create() self.floating_ips.append(floating_ip) self.assertIn(floating_ip.ip, [fip_info.ip for fip_info in self.nova.floating_ips.list()]) keys = self.nova.keypairs.create('key_2238776') self.keys.append(keys) private_key = paramiko.RSAKey.from_private_key(six.StringIO(str( keys.private_key))) inst = common_functions.create_instance(self.nova, "inst_2238776_{}" .format(flavor.name), flavor.id, net, [self.sec_group.name], image_id=image_id, key_name='key_2238776', inst_list=self.instances) inst.add_floating_ip(floating_ip.ip) ping = common_functions.ping_command(floating_ip.ip, i=10) self.assertTrue(ping, "Instance is not reachable") out = [] with SSHClient(host=floating_ip.ip, username="******", password=None, private_keys=[private_key]) as vm_r: out.append(vm_r.execute("sudo sh -c 'date > /timestamp.txt'")) out.append(vm_r.execute("sudo sh -c 'date > /mnt/timestamp.txt'")) out.append(vm_r.execute("sudo -i cat /timestamp.txt")) out.append(vm_r.execute("sudo -i cat /mnt/timestamp.txt")) for i in out: if i.get('stderr'): raise Exception("ssh commands were executed with errors") root_data = out[-2]['stdout'][0] ephem_data = out[-1]['stdout'][0] # live migration hypervisors = {h.hypervisor_hostname: h for h in self.nova.hypervisors.list()} old_hyper = getattr(inst, "OS-EXT-SRV-ATTR:hypervisor_hostname") new_hyper = [h for h in hypervisors.keys() if h != old_hyper][0] ping = subprocess.Popen(["/bin/ping", "-c100", "-i1", floating_ip.ip], stdout=subprocess.PIPE) self.nova.servers.live_migrate(inst, new_hyper, block_migration=False, disk_over_commit=False) inst = self.nova.servers.get(inst.id) timeout = 10 end_time = time() + 60 * timeout while getattr(inst, "OS-EXT-SRV-ATTR:hypervisor_hostname") != \ new_hyper: if time() > end_time: msg = "Hypervisor is not changed after live migration" raise AssertionError(msg) sleep(1) inst = self.nova.servers.get(inst.id) self.assertEqual(inst.status, 'ACTIVE') ping.wait() output = ping.stdout.read().split('\n')[-3].split() packets = {'transmitted': int(output[0]), 'received': int(output[3])} loss = packets['transmitted'] - packets['received'] if loss > 5: msg = "Packets loss exceeds the limit, {} packets were lost" raise AssertionError(msg.format(loss)) out = [] with SSHClient(host=floating_ip.ip, username="******", password=None, private_keys=[private_key]) as vm_r: out.append(vm_r.execute("sudo -i cat /timestamp.txt")) out.append(vm_r.execute("sudo -i cat /mnt/timestamp.txt")) for i in out: if i.get('stderr'): raise Exception("ssh commands were executed with errors") r_data = out[0]['stdout'][0] ep_data = out[1]['stdout'][0] self.assertEqual(root_data, r_data, "Data on root disk is changed") self.assertEqual(ephem_data, ep_data, "Data on ephemeral disk is " "changed")
def test_resize_down_an_instance_booted_from_volume(self): """This test checks that nova allows resize down an instance booted from volume Steps: 1. Create bootable volume 2. Boot instance from newly created volume 3. Resize instance from m1.small to m1.tiny """ # 1. Create bootable volume image_id = [ image.id for image in self.nova.images.list() if image.name == 'TestVM' ][0] volume = common_functions.create_volume(self.cinder, image_id, timeout=60) self.volumes.append(volume) # 2. Create instance from newly created volume, associate floating_ip name = 'TestVM_543355_instance_to_resize' networks = self.neutron.list_networks()['networks'] net = [net['id'] for net in networks if not net['router:external']][0] flavor_list = {f.name: f.id for f in self.nova.flavors.list()} initial_flavor = flavor_list['m1.small'] resize_flavor = flavor_list['m1.tiny'] bdm = {'vda': volume.id} instance = common_functions.create_instance(self.nova, name, initial_flavor, net, [self.sec_group.name], block_device_mapping=bdm, inst_list=self.instances) self.instances.append(instance.id) # Assert for attached volumes attached_volumes = self.nova.servers.get( instance).to_dict()['os-extended-volumes:volumes_attached'] self.assertIn({'id': volume.id}, attached_volumes) # Assert to flavor size self.assertEqual( self.nova.servers.get(instance).flavor['id'], initial_flavor, "Unexpected instance flavor before resize") floating_ip = self.nova.floating_ips.create() self.floating_ips.append(floating_ip.ip) instance.add_floating_ip(floating_ip.ip) # 3. Resize from m1.small to m1.tiny self.nova.servers.resize(instance, resize_flavor) common_functions.check_inst_status(self.nova, instance.id, 'VERIFY_RESIZE', 60) self.nova.servers.confirm_resize(instance) common_functions.check_inst_status(self.nova, instance.id, 'ACTIVE', 60) self.assertEqual( self.nova.servers.get(instance).flavor['id'], resize_flavor, "Unexpected instance flavor after resize") # Check that instance is reachable ping = common_functions.ping_command(floating_ip.ip) self.assertTrue(ping, "Instance after resize is not reachable")
def setUp(self): """ :return: Nothing """ self.amount_of_images_before = len(list(self.glance.images.list())) self.image = None self.our_own_flavor_was_created = False self.expected_flavor_id = 3 self.node_to_boot = None self.security_group_name = "ms_compatibility" # protect for multiple definition of the same group for sg in self.nova.security_groups.list(): if sg.name == self.security_group_name: self.nova.security_groups.delete(sg) # adding required security group self.the_security_group = self.nova.security_groups.create( name=self.security_group_name, description="Windows Compatibility") # Add rules for ICMP, TCP/22 self.icmp_rule = self.nova.security_group_rules.create( self.the_security_group.id, ip_protocol="icmp", from_port=-1, to_port=-1, cidr="0.0.0.0/0") self.tcp_rule = self.nova.security_group_rules.create( self.the_security_group.id, ip_protocol="tcp", from_port=22, to_port=22, cidr="0.0.0.0/0") # Add both rules to default group self.default_security_group_id = 0 for sg in self.nova.security_groups.list(): if sg.name == 'default': self.default_security_group_id = sg.id break self.icmp_rule_default = self.nova.security_group_rules.create( self.default_security_group_id, ip_protocol="icmp", from_port=-1, to_port=-1, cidr="0.0.0.0/0") self.tcp_rule_default = self.nova.security_group_rules.create( self.default_security_group_id, ip_protocol="tcp", from_port=22, to_port=22, cidr="0.0.0.0/0") # adding floating ip self.floating_ip = self.nova.floating_ips.create( self.nova.floating_ip_pools.list()[0].name) # creating of the image self.image = self.glance.images.create( name='MyTestSystem', disk_format='qcow2', container_format='bare') self.glance.images.upload( self.image.id, open('/tmp/trusty-server-cloudimg-amd64-disk1.img', 'rb')) # check that required image in active state is_activated = False while not is_activated: for image_object in self.glance.images.list(): if image_object.id == self.image.id: self.image = image_object logger.info("Image in the {} state". format(self.image.status)) if self.image.status == 'active': is_activated = True break time.sleep(1) # Default - the first network_id = self.nova.networks.list()[0].id # More detailed check of network list for network in self.nova.networks.list(): if 'internal' in network.label: network_id = network.id logger.info("Starting with network interface id {}". format(network_id)) # TODO: add check flavor parameters vs. vm parameters # Collect information about the medium flavor and create a copy of it for flavor in self.nova.flavors.list(): if 'medium' in flavor.name and 'copy.of.' not in flavor.name: new_flavor_name = "copy.of." + flavor.name new_flavor_id = common_functions.get_flavor_id_by_name( self.nova, new_flavor_name) # delete the flavor if it already exists if new_flavor_id is not None: common_functions.delete_flavor( self.nova, new_flavor_id) # create the flavor for our needs expected_flavor = self.nova.flavors.create( name=new_flavor_name, ram=flavor.ram, vcpus=1, # Only one VCPU disk=flavor.disk ) self.expected_flavor_id = expected_flavor.id self.our_own_flavor_was_created = True break logger.info("Starting with flavor {}".format( self.nova.flavors.get(self.expected_flavor_id))) # nova boot self.node_to_boot = common_functions.create_instance( nova_client=self.nova, inst_name="MyTestSystemWithNova", flavor_id=self.expected_flavor_id, net_id=network_id, security_groups=[self.the_security_group.name, 'default'], image_id=self.image.id) # check that boot returns expected results self.assertEqual(self.node_to_boot.status, 'ACTIVE', "The node not in active state!") logger.info("Using following floating ip {}".format( self.floating_ip.ip)) self.node_to_boot.add_floating_ip(self.floating_ip) self.assertTrue(common_functions.check_ip( self.nova, self.node_to_boot.id, self.floating_ip.ip))
def test_boot_instance_from_volume_bigger_than_flavor_size(self): """This test checks that nova allows creation instance from volume with size bigger than flavor size Steps: 1. Create volume with size 2Gb. 2. Boot instance with flavor size 'tiny' from newly created volume 3. Check that instance created with correct values """ # 1. Create volume image_id = [ image.id for image in self.nova.images.list() if image.name == 'TestVM' ][0] volume = common_functions.create_volume(self.cinder, image_id, size=2, timeout=60) self.volumes.append(volume) # 2. Create router, network, subnet, connect them to external network exist_networks = self.os_conn.list_networks()['networks'] ext_network = [x for x in exist_networks if x.get('router:external')][0] self.router = self.os_conn.create_router(name="router01")['router'] self.os_conn.router_gateway_add(router_id=self.router['id'], network_id=ext_network['id']) net_id = self.os_conn.add_net(self.router['id']) # 3. Create instance from newly created volume, associate floating_ip name = 'TestVM_1517671_instance' flavor_list = {f.name: f.id for f in self.nova.flavors.list()} initial_flavor = flavor_list['m1.tiny'] bdm = {'vda': volume.id} instance = common_functions.create_instance(self.nova, name, initial_flavor, net_id, [self.sec_group.name], block_device_mapping=bdm, inst_list=self.instances) self.instances.append(instance.id) # Assert for attached volumes attached_volumes = self.nova.servers.get( instance).to_dict()['os-extended-volumes:volumes_attached'] self.assertIn({'id': volume.id}, attached_volumes) # Assert to flavor size self.assertEqual( self.nova.servers.get(instance).flavor['id'], initial_flavor, "Unexpected instance flavor after creation") floating_ip = self.nova.floating_ips.create() self.floating_ips.append(floating_ip.ip) instance.add_floating_ip(floating_ip.ip) # Check that instance is reachable ping = common_functions.ping_command(self.floating_ip.ip) self.assertTrue(ping, "Instance after creation is not reachable")