class ResizeServerDownConfirmTests(object): compute_config = ComputeConfig() hypervisor = compute_config.hypervisor.lower() @tags(type='positive', net='no') def test_verify_confirm_resize_response(self): pass @tags(type='positive', net='no') def test_server_properties_after_resize(self): self.assertEqual(self.server.flavor.id, self.resized_flavor.id) @tags(type='positive', net='yes') def test_resized_server_vcpus(self): """Verify the number of vCPUs matches the value of the new flavor""" remote_client = self.server_behaviors.get_remote_instance_client( self.server, config=self.servers_config, key=self.key.private_key) server_actual_vcpus = remote_client.get_number_of_cpus() self.assertEqual( server_actual_vcpus, self.resized_flavor.vcpus, msg="Expected number of vcpus to be {0}, was {1}.".format( self.resized_flavor.vcpus, server_actual_vcpus)) @tags(type='positive', net='yes') @unittest.skipIf(hypervisor == ComputeHypervisors.KVM, 'Disks do resize down for KVM.') def test_created_server_disk_size(self): """Verify the size of the virtual disk matches that of the flavor""" remote_client = self.server_behaviors.get_remote_instance_client( self.server, config=self.servers_config, key=self.key.private_key) disk_size = remote_client.get_disk_size( self.servers_config.instance_disk_path) self.assertEqual(disk_size, self.resized_flavor.disk, msg="Expected disk to be {0} GB, was {1} GB".format( self.resized_flavor.disk, disk_size)) @tags(type='positive', net='yes') def test_can_log_into_resized_server(self): """Tests that we can log into the server after resizing""" remote_client = self.server_behaviors.get_remote_instance_client( self.server, config=self.servers_config, key=self.key.private_key) self.assertTrue(remote_client.can_authenticate(), msg="Cannot connect to server using public ip") @tags(type='positive', net='yes') def test_server_ram_after_resize(self): """The server's RAM and should be modified to that of the new flavor""" remote_instance = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) margin = (int(self.resized_flavor.ram) * .1) lower_limit = int(self.resized_flavor.ram) - margin server_ram_size = int(remote_instance.get_allocated_ram()) self.assertTrue((int(self.resized_flavor.ram) == server_ram_size or lower_limit <= server_ram_size), msg='Ram size after confirm-resize did not match.' 'Expected ram size : %s, Actual ram size : %s' % (self.resized_flavor.ram, server_ram_size)) @tags(type='positive', net='no') def test_resized_server_instance_actions(self): """Verify the correct actions are logged during a confirmed resize.""" actions = self.servers_client.get_instance_actions( self.server.id).entity # Verify the resize action is listed self.assertTrue(any(a.action == 'resize' for a in actions)) filtered_actions = [a for a in actions if a.action == 'resize'] self.assertEquals(len(filtered_actions), 1) resize_action = filtered_actions[0] self.validate_instance_action( resize_action, self.server.id, self.user_config.user_id, self.user_config.project_id, self.resize_resp.headers['x-compute-request-id']) # Verify the confirm resize action is listed self.assertTrue(any(a.action == 'confirmResize' for a in actions)) filtered_actions = [a for a in actions if a.action == 'confirmResize'] self.assertEquals(len(filtered_actions), 1) resize_action = filtered_actions[0] self.validate_instance_action( resize_action, self.server.id, self.user_config.user_id, self.user_config.project_id, self.confirm_resize_resp.headers['x-compute-request-id'])
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ import unittest from cafe.drivers.unittest.decorators import tags from cloudcafe.common.tools.datagen import rand_name from cloudcafe.compute.common.types import ComputeHypervisors, \ NovaServerStatusTypes from cloudcafe.compute.config import ComputeConfig from cloudcafe.compute.flavors_api.config import FlavorsConfig from cloudroast.compute.fixtures import ServerFromImageFixture compute_config = ComputeConfig() hypervisor = compute_config.hypervisor.lower() flavors_config = FlavorsConfig() resize_enabled = flavors_config.resize_enabled can_resize = (resize_enabled and hypervisor not in [ ComputeHypervisors.IRONIC, ComputeHypervisors.LXC_LIBVIRT ]) class ResizeServerUpConfirmTests(object): @tags(type='smoke', net='no') def test_verify_confirm_resize_response(self): """ This test will pass
class ResizeServerDownConfirmTests(object): compute_config = ComputeConfig() hypervisor = compute_config.hypervisor.lower() @tags(type='positive', net='no') def test_verify_confirm_resize_response(self): """ This test will pass """ pass @tags(type='positive', net='no') def test_server_properties_after_resize(self): """ The flavor id of the resized server should be equal to the resize flavor The following assertions occur: - The flavor id from test configuration is equal to the flavor id of the resized server """ self.assertEqual(self.server.flavor.id, self.resized_flavor.id) @tags(type='positive', net='yes') def test_resized_server_vcpus(self): """ vCPUs of resized server should be equal to the server's flavor's vCPUs Get a remote client for the server resized during test set up. Use the remote client to get the number of CPUs for the server. Validate that this value is equal to the vCPUs of the flavor from test configuration. The following validations occur: - The vCPUs value of the flavor from test configuration is equal to the number of CPUs on the server resized during test set up """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, config=self.servers_config, key=self.key.private_key) server_actual_vcpus = remote_client.get_number_of_cpus() self.assertEqual( server_actual_vcpus, self.resized_flavor.vcpus, msg="Expected number of vcpus to be {0}, was {1}.".format( self.resized_flavor.vcpus, server_actual_vcpus)) @tags(type='positive', net='yes') @unittest.skipIf(hypervisor == ComputeHypervisors.KVM, 'Disks do resize down for KVM.') def test_created_server_disk_size(self): """ Disk size of resized server should be match the flavor's disk size The virtual disk size of a resized server should be equal to the disk size of the flavor used to resize the server. Get a remote client for the server resized during test setup. Use the remote client to get the disk size of the server. Validate that the disk size of the server is equal to the disk size of the flavor from test configuration. The following assertions occur: - The disk size of the server created during test set up is equal to the disk size of the flavor from test configuration. """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, config=self.servers_config, key=self.key.private_key) disk_size = remote_client.get_disk_size( self.servers_config.instance_disk_path) self.assertEqual(disk_size, self.resized_flavor.disk, msg="Expected disk to be {0} GB, was {1} GB".format( self.resized_flavor.disk, disk_size)) @tags(type='positive', net='yes') def test_can_log_into_resized_server(self): """ Resized server should be accessible using a remote instance client Get a remote instance client for the server resized during test set up. Validate that the remote instance client can authenticate to the server. The following assertions occur: - The remote client for the server resized during test set up can authenticate to the server """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, config=self.servers_config, key=self.key.private_key) self.assertTrue(remote_client.can_authenticate(), msg="Cannot connect to server using public ip") @tags(type='positive', net='yes') def test_server_ram_after_resize(self): """ RAM of a resized server should be equal to the server's flavor's RAM Get a remote instance client for the instance resized during test set up. Calculate the minimum acceptable RAM value, this is 90% of the RAM value of the flavor from test configuration. Validate that the RAM of the server is equal to the RAM value of the flavor from the test configuration or greater than/equal to the minimum RAM value previously calculated. The following assertions occur: - The RAM value of the server resized during test set up is equal to the RAM value of the flavor from test configuration or greater than/equal to a value that is 90% of the RAM value of the flavor from test configuration """ remote_instance = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) margin = (int(self.resized_flavor.ram) * .1) lower_limit = int(self.resized_flavor.ram) - margin server_ram_size = int(remote_instance.get_allocated_ram()) self.assertTrue((int(self.resized_flavor.ram) == server_ram_size or lower_limit <= server_ram_size), msg='Ram size after confirm-resize did not match.' 'Expected ram size : %s, Actual ram size : %s' % (self.resized_flavor.ram, server_ram_size)) @tags(type='positive', net='no') def test_resized_server_instance_actions(self): """ Verify the correct actions are logged during a server resize. Get the list of all actions that the server has taken from the Nova API. Filter the list so that only the actions 'resize' remain. Validate that the list of filtered actions has a length of 1 (that only 1 resize action has been performed.) Validate that the values of the identified create action match the values returned in the create server response received during test setup. Filter the list so that only the actions 'confirmResize' remain. Validate that the list of filtered actions has a length of 1 (that only 1 confirmResize action has been performed.) Validate that the values of the identified create action match the values returned in the create server response received during test setup. The following assertions occur: - The list of actions that match 'resize' has only one item - The values for the resize action match the values received in response to the create request - The list of actions that match 'confirmResize' has only one item - The values for the confirmResize action match the values received in response to the resize request """ actions = self.servers_client.get_instance_actions( self.server.id).entity # Verify the resize action is listed self.assertTrue(any(a.action == 'resize' for a in actions)) filtered_actions = [a for a in actions if a.action == 'resize'] self.assertEquals(len(filtered_actions), 1) resize_action = filtered_actions[0] self.validate_instance_action( resize_action, self.server.id, self.compute.user.user_id, self.compute.user.project_id, self.resize_resp.headers['x-compute-request-id']) # Verify the confirm resize action is listed self.assertTrue(any(a.action == 'confirmResize' for a in actions)) filtered_actions = [a for a in actions if a.action == 'confirmResize'] self.assertEquals(len(filtered_actions), 1) resize_action = filtered_actions[0] self.validate_instance_action( resize_action, self.server.id, self.compute.user.user_id, self.compute.user.project_id, self.confirm_resize_resp.headers['x-compute-request-id'])
class ServersTest(ComputeFixture): compute_config = ComputeConfig() hypervisor = compute_config.hypervisor.lower() DEFAULT_PSWD_LENGTH = 24 @unittest.skipIf( hypervisor in [ComputeHypervisors.KVM, ComputeHypervisors.QEMU], 'Password authentication disabled.') @tags(type='positive', net='yes') def test_create_server_with_admin_password(self): """ Creates a server with an admin password to be used as root's password. This will set the server that is created with the root password of oldslice129690TuG72Bgj2. Calls cloudcafe's server behaviors get remote instance client with the password to validate that it can authenticate wth password. The following assertions occur: - Defined password is the same as the admin password. - get_remote_instance_client has a true value for can_authenticate """ admin_password = '******' response = self.server_behaviors.create_active_server( admin_pass=admin_password) server = response.entity self.resources.add(server.id, self.servers_client.delete_server) self.assertEqual(admin_password, server.admin_pass) remote_client = self.server_behaviors.get_remote_instance_client( server, self.servers_config, password=admin_password, auth_strategy=InstanceAuthStrategies.PASSWORD) self.assertTrue(remote_client.can_authenticate(), msg="Cannot authenticate to the server.") @tags(type='positive', net='yes') def test_create_server_with_default_password(self): """ Creates a server with a default password set by the provisioning algorithm. This will set the server that is created with a default password with a length of 24 characters. Calls cloudcafe's server behaviors get remote instance client with the password to validate that it can authenticate wth password. The following assertions occur: - Default password is the correct length. - get_remote_instance_client has a true value for can_authenticate Design Change: https://jira.rax.io/browse/VIRT-3004 """ border = '*' * 65 self.fixture_log.info("\n\n{BORDER}\nCreate a server with a default " "password\n{BORDER}\n\n".format(BORDER=border)) response = self.server_behaviors.create_active_server() server = response.entity self.resources.add(server.id, self.servers_client.delete_server) # Record expectations and results self.fixture_log.info( "\n\n{BORDER}\n" "Validate Password Length:\n" "\tEXPECTED PSWD LENGTH: {EXP}\n" "\tACTUAL PSWD LENGTH: {ACT}\n" "{BORDER}\n\n".format( EXP=self.DEFAULT_PSWD_LENGTH, ACT=len(server.admin_pass), BORDER=border)) self.assertEqual( len(server.admin_pass), self.DEFAULT_PSWD_LENGTH, "Actual length ({ACTUAL}) does not match the expected length " "({EXPECTED})".format( EXPECTED=self.DEFAULT_PSWD_LENGTH, ACTUAL=len(server.admin_pass))) self.fixture_log.info( "\n\n{BORDER}\nVerify admin password can be used to log " "in.\n{BORDER}\n\n".format(BORDER=border)) remote_client = self.server_behaviors.get_remote_instance_client( server, self.servers_config, password=server.admin_pass, auth_strategy=InstanceAuthStrategies.PASSWORD) self.assertTrue(remote_client.can_authenticate(), msg="Cannot authenticate to the server.") self.fixture_log.info( "\n\n{BORDER}\nPassword accepted. Test PASSES.\n{BORDER}" "\n\n".format(BORDER=border)) @tags(type='positive', net='no') def test_update_server(self): """ Creates a server and then updates the name, ipv4 and ipv6 values. Will call the create_active_server from server behaviors, then call update_server from cloudcafe's server_client passing in the newly created server's id, new random name, ipv4 address 192.168.32.16 and ipv6 address 3ffe:1900:4545:3:200:f8ff:fe21:67cf and then waiting for the server to make it to active status. Calling get_server to validate the updates occurred correctly The following assertions occur: - Server name was updated with new random name. - Server's IPV4 address is 192.168.32.16. - Server's IPV6 address is 3ffe:1900:4545:3:200:f8ff:fe21:67cf. - Server's creation date is still the same as the original. - Server's updated date is not the same as the original. """ response = self.server_behaviors.create_active_server() original_server = response.entity self.resources.add( original_server.id, self.servers_client.delete_server) # Use server bookmark's link to update the server new_name = rand_name("testserver") accessIPv4 = '192.168.32.16' accessIPv6 = '3ffe:1900:4545:3:200:f8ff:fe21:67cf' updated_server_response = self.servers_client.update_server( original_server.id, new_name, accessIPv4=accessIPv4, accessIPv6=accessIPv6) updated_server = updated_server_response.entity self.server_behaviors.wait_for_server_status( updated_server.id, NovaServerStatusTypes.ACTIVE) # Verify the name and access ips of the server have changed server = self.servers_client.get_server(updated_server.id).entity self.assertEqual(new_name, server.name, msg="The server name was not updated") self.assertEqual(accessIPv4, server.accessIPv4, msg="AccessIPv4 address was not updated") self.assertEqual(accessIPv6, server.accessIPv6, msg="AccessIPv6 address was not updated") self.assertEqual(server.created, updated_server.created, msg="The server creation date was updated") self.assertNotEqual( server.updated, original_server.updated, msg="Updated time for server {server_id} " "did not change after a modification to the server.".format( server_id=server.id))
class CreateServerTest(object): compute_config = ComputeConfig() hypervisor = compute_config.hypervisor.lower() servers_config = ServersConfig() file_injection_enabled = servers_config.personality_file_injection_enabled @tags(type='smoke', net='no') def test_create_server_response(self): """Verify the parameters are correct in the initial response""" self.assertTrue(self.server.id is not None, msg="Server id was not set in the response") self.assertTrue(self.server.admin_pass is not None, msg="Admin password was not set in the response") self.assertTrue(self.server.links is not None, msg="Server links were not set in the response") @tags(type='smoke', net='no') def test_created_server_fields(self): """Verify that a created server has all expected fields""" message = "Expected {0} to be {1}, was {2}." self.assertEqual(self.server.name, self.name, msg=message.format('server name', self.server.name, self.name)) self.assertEqual(self.server.flavor.id, self.flavor_ref, msg=message.format('flavor id', self.flavor_ref, self.server.flavor.id)) self.assertTrue(self.server.created is not None, msg="Expected server created date to be set") self.assertTrue(self.server.updated is not None, msg="Expected server updated date to be set.") self.assertGreaterEqual(self.server.updated, self.server.created, msg='Expected server updated date to be' 'after the created date.') @tags(type='smoke', net='no') def test_server_addresses(self): """ The server should have the expected network configuration. """ addresses = self.server.addresses for name, ip_addresses in self.expected_networks.iteritems(): network = addresses.get_by_name(name) if ip_addresses.get('v4'): self.assertIsNotNone( network.ipv4, msg='Expected {name} network to have an IPv4 address.') else: self.assertIsNone( network.ipv4, msg='Expected {name} network to not have an IPv4 address.') if ip_addresses.get('v6'): self.assertIsNotNone( network.ipv6, msg='Expected {name} network to have an IPv6 address.') else: self.assertIsNone( network.ipv6, msg='Expected {name} network to not have an IPv6 address.') @tags(type='smoke', net='yes') def test_created_server_vcpus(self): """ Verify the number of vCPUs reported matches the amount set by the flavor """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) server_actual_vcpus = remote_client.get_number_of_cpus() self.assertEqual( server_actual_vcpus, self.flavor.vcpus, msg="Expected number of vcpus to be {0}, was {1}.".format( self.flavor.vcpus, server_actual_vcpus)) @tags(type='smoke', net='yes') def test_created_server_primary_disk(self): """ Verify the size of the virtual disk matches the size set by the flavor """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) disk_size = remote_client.get_disk_size( self.servers_config.instance_disk_path) self.assertEqual(disk_size, self.flavor.disk, msg="Expected disk to be {0} GB, was {1} GB".format( self.flavor.disk, disk_size)) @tags(type='smoke', net='yes') def test_created_server_ephemeral_disk(self): """ Verify the size of the ephemeral disk matches the size set by the flavor """ if self.flavor.ephemeral_disk == 0: # No ephemeral disk, no further validation necessary return remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) # Get all disks and remove the primary disk from the list disks = remote_client.get_all_disks() disks.pop(self.servers_config.instance_disk_path, None) # Verify the ephemeral disks have the correct size self._verify_ephemeral_disk_size( disks=disks, flavor=self.flavor, split_ephemeral_disk_enabled=self.split_ephemeral_disk_enabled, ephemeral_disk_max_size=self.ephemeral_disk_max_size) # Partition and format the disks for disk in disks: self._format_disk(remote_client=remote_client, disk=disk, disk_format=self.disk_format_type) mount_point = '/mnt/{name}'.format(name=rand_name('disk')) self._mount_disk(remote_client=remote_client, disk=disk, mount_point=mount_point) @tags(type='smoke', net='yes') def test_created_server_ram(self): """ The server's RAM and should be set to the amount specified in the flavor """ remote_instance = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) lower_limit = int(self.flavor.ram) - (int(self.flavor.ram) * .1) server_ram_size = int(remote_instance.get_allocated_ram()) self.assertTrue((int(self.flavor.ram) == server_ram_size or lower_limit <= server_ram_size), msg='Unexpected ram size.' 'Expected ram size : %s, Actual ram size : %s'.format( self.flavor.ram, server_ram_size)) @tags(type='smoke', net='yes') def test_created_server_hostname(self): """ Verify that the hostname of the server is the same as the server name """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) hostname = remote_client.get_hostname() self.assertEqual(hostname, self.name, msg="Expected hostname to be {0}, was {1}".format( self.name, hostname)) @tags(type='smoke', net='yes') def test_can_log_into_created_server(self): """Validate that the server instance can be accessed""" remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) self.assertTrue(remote_client.can_authenticate(), msg="Cannot connect to server using public ip") @tags(type='smoke', net='yes') @unittest.skipUnless(file_injection_enabled, "File injection disabled.") def test_personality_file_created(self): """ Validate the injected file was created on the server with the correct contents """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) self.assertTrue(remote_client.is_file_present('/test.txt')) self.assertEqual( remote_client.get_file_details('/test.txt').content, self.file_contents) @tags(type='smoke', net='no') def test_created_server_metadata(self): """Verify the provided metadata was set for the server""" # Verify the metadata items were added to the server self.assertIn('meta_key_1', self.server.metadata) self.assertIn('meta_key_2', self.server.metadata) # Verify the values of the metadata items are correct self.assertEqual(self.server.metadata.get('meta_key_1'), 'meta_value_1') self.assertEqual(self.server.metadata.get('meta_key_2'), 'meta_value_2') @tags(type='smoke', net='no') def test_created_server_instance_actions(self): """Verify the correct actions are logged while creating a server.""" actions = self.servers_client.get_instance_actions( self.server.id).entity # Verify the create action is listed self.assertTrue(any(a.action == 'create' for a in actions)) filtered_actions = [a for a in actions if a.action == 'create'] self.assertEquals(len(filtered_actions), 1) create_action = filtered_actions[0] self.validate_instance_action( create_action, self.server.id, self.user_config.user_id, self.user_config.project_id, self.create_resp.headers['x-compute-request-id']) @tags(type='smoke', net='yes') @unittest.skipUnless(hypervisor == ComputeHypervisors.XEN_SERVER, 'Requires Xen Server.') def test_created_server_xenstore_metadata(self): """Verify the provided metadata was set for the server""" remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) xen_meta = remote_client.get_xen_user_metadata() for key, value in self.metadata.iteritems(): self.assertEqual(xen_meta[key], value) @tags(type='smoke', net='yes') @unittest.skipUnless(hypervisor == ComputeHypervisors.XEN_SERVER, 'Requires Xen Server.') def test_xenstore_disk_config(self): """Verify the disk config of the server is propagated to the XenStore metadata.""" remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) auto_config_enabled = remote_client.get_xenstore_disk_config_value() actual_disk_config = self.server.disk_config self.assertEqual(auto_config_enabled, actual_disk_config.lower() == 'auto')
class RebuildServerTests(object): compute_config = ComputeConfig() hypervisor = compute_config.hypervisor.lower() servers_config = ServersConfig() file_injection_enabled = servers_config.personality_file_injection_enabled @tags(type='smoke', net='no') def test_verify_rebuild_server_response(self): """Verify the properties in the initial response are correct""" rebuilt_server = self.rebuilt_server_response.entity self.assertEqual(rebuilt_server.name, self.name, msg="Server name did not match") self.assertEqual(rebuilt_server.image.id, self.image_ref_alt, msg="Image id did not match") self.assertEqual(rebuilt_server.flavor.id, self.flavor_ref, msg="Flavor id did not match") self.assertEqual(rebuilt_server.id, self.server.id, msg="Server id did not match") self.assertEqual(rebuilt_server.links.bookmark, self.server.links.bookmark, msg="Bookmark links do not match") self.assertEqual(rebuilt_server.metadata.get('key'), 'value') self.assertEqual(rebuilt_server.created, self.server.created, msg="Server Created date changed after rebuild") self.assertTrue(rebuilt_server.updated != self.server.updated, msg="Server Updated date not changed after rebuild") self.assertEquals(rebuilt_server.addresses, self.server.addresses, msg="Server IP addresses changed after rebuild") @tags(type='smoke', net='no') def test_rebuilt_server_addresses(self): """ The server should have the expected network configuration after being rebuilt. """ rebuilt_server = self.rebuilt_server_response.entity addresses = rebuilt_server.addresses for name, ip_addresses in self.expected_networks.iteritems(): network = addresses.get_by_name(name) if ip_addresses.get('v4'): self.assertIsNotNone( network.ipv4, msg='Expected {name} network to have an IPv4 address.'. format(name=name)) else: self.assertIsNone( network.ipv4, msg='Expected {name} network to not have an IPv4 address.'. format(name=name)) if ip_addresses.get('v6'): self.assertIsNotNone( network.ipv6, msg='Expected {name} network to have an IPv6 address.'. format(name=name)) else: self.assertIsNone( network.ipv6, msg='Expected {name} network to not have an IPv6 address.'. format(name=name)) @tags(type='smoke', net='no') def test_address_not_changed_on_rebuild(self): rebuilt_server = self.rebuilt_server_response.entity addresses = rebuilt_server.addresses self.assertEqual(addresses, self.server.addresses) @tags(type='smoke', net='yes') def test_can_log_into_server_after_rebuild(self): remote_instance = self.server_behaviors.get_remote_instance_client( self.server, config=self.servers_config, password=self.password, key=self.key.private_key) self.assertTrue(remote_instance.can_authenticate()) @tags(type='smoke', net='yes') def test_rebuilt_server_vcpus(self): """Verify the number of vCPUs reported is the correct after rebuild""" remote_client = self.server_behaviors.get_remote_instance_client( self.server, config=self.servers_config, password=self.password, key=self.key.private_key) server_actual_vcpus = remote_client.get_number_of_cpus() self.assertEqual( server_actual_vcpus, self.flavor.vcpus, msg="Expected number of vcpus to be {0}, was {1}.".format( self.flavor.vcpus, server_actual_vcpus)) @tags(type='smoke', net='yes') def test_rebuilt_server_ephemeral_disk(self): """ Verify the size of the virtual disk matches the size set by the flavor """ if self.flavor.ephemeral_disk == 0: # No ephemeral disk, no further validation necessary return remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, password=self.password, key=self.key.private_key) # Get all disks and remove the primary disk from the list disks = remote_client.get_all_disks() disks.pop(self.servers_config.instance_disk_path, None) # Verify the ephemeral disks have the correct size self._verify_ephemeral_disk_size( disks=disks, flavor=self.flavor, split_ephemeral_disk_enabled=self.split_ephemeral_disk_enabled, ephemeral_disk_max_size=self.ephemeral_disk_max_size) # Partition and format the disks for disk in disks: self._format_disk(remote_client=remote_client, disk=disk, disk_format=self.disk_format_type) mount_point = remote_client.generate_mountpoint() self._mount_disk(remote_client=remote_client, disk=disk, mount_point=mount_point) @tags(type='smoke', net='yes') def test_server_ram_after_rebuild(self): remote_instance = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, password=self.password, key=self.key.private_key) lower_limit = int(self.flavor.ram) - (int(self.flavor.ram) * .1) server_ram_size = int(remote_instance.get_allocated_ram()) self.assertTrue((int(self.flavor.ram) == server_ram_size or lower_limit <= server_ram_size), msg='Ram size after confirm-resize did not match.' 'Expected ram size : %s, Actual ram size : %s.' % (self.flavor.ram, server_ram_size)) @tags(type='smoke', net='yes') @unittest.skipUnless(file_injection_enabled, "File injection disabled.") def test_personality_file_created_on_rebuild(self): """ Validate the injected file was created on the rebuilt server with the correct contents """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, password=self.password, key=self.key.private_key) self.assertTrue(remote_client.is_file_present(self.rebuilt_file_path)) self.assertEqual( remote_client.get_file_details(self.rebuilt_file_path).content, self.rebuilt_file_contents) @tags(type='smoke', net='no') def test_server_metadata_set_on_rebuild(self): """Verify the provided metadata was set for the rebuilt server""" rebuilt_server = self.rebuilt_server_response.entity # Verify the metadata items were added to the server self.assertIn('key', rebuilt_server.metadata) # Verify the values of the metadata items are correct self.assertEqual(rebuilt_server.metadata.get('key'), 'value') @tags(type='smoke', net='no') def test_rebuilt_server_instance_actions(self): """Verify the correct actions are logged during a rebuild.""" actions = self.servers_client.get_instance_actions( self.server.id).entity # Verify the rebuild action is listed self.assertTrue(any(a.action == 'rebuild' for a in actions)) filtered_actions = [a for a in actions if a.action == 'rebuild'] self.assertEquals(len(filtered_actions), 1) rebuild_action = filtered_actions[0] self.validate_instance_action( rebuild_action, self.server.id, self.compute.user.user_id, self.compute.user.project_id, self.rebuilt_server_response.headers['x-compute-request-id']) @tags(type='smoke', net='yes') @unittest.skipUnless(hypervisor == ComputeHypervisors.XEN_SERVER, 'Requires Xen Server.') def test_rebuilt_server_xenstore_metadata(self): """Verify the provided metadata was set for the server""" remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, password=self.password, key=self.key.private_key) xen_meta = remote_client.get_xen_user_metadata() for key, value in self.metadata.iteritems(): self.assertIn(key, xen_meta) self.assertEqual(xen_meta[key], value) @tags(type='smoke', net='yes') @unittest.skipUnless(hypervisor == ComputeHypervisors.XEN_SERVER, 'Requires Xen Server.') def test_xenstore_disk_config_on_rebuild(self): """Verify the disk config of the server is propagated to the XenStore metadata on server rebuild.""" rebuilt_server = self.rebuilt_server_response.entity remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key, password=self.password) auto_config_enabled = remote_client.get_xenstore_disk_config_value() actual_disk_config = rebuilt_server.disk_config self.assertEqual(auto_config_enabled, actual_disk_config.lower() == 'auto') @tags(type='smoke', net='yes') @unittest.skipUnless(file_injection_enabled, "File injection disabled.") def test_file_system_cleared_on_rebuild(self): """ Verify that after a rebuild any files on the file system that are not explicitly injected into the rebuild are no longer on the file system. """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, password=self.password, key=self.key.private_key) self.assertFalse(remote_client.is_file_present(self.file_path)) @unittest.skip("Skipping until refactor of 'get_distribution_and_version'") @tags(type='smoke', net='yes') def test_distro_after_rebuild(self): """ Verify the distro is changed if using rebuild with different image """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, password=self.password, key=self.key.private_key) distro_after_rebuild = remote_client.get_distribution_and_version() if (self.distro_before_rebuild and distro_after_rebuild and self.image_ref != self.image_ref_alt): self.assertNotEqual(self.distro_before_rebuild, distro_after_rebuild) else: self.assertEqual(self.distro_before_rebuild, distro_after_rebuild)
class RebuildServerTests(ComputeFixture): compute_config = ComputeConfig() hypervisor = compute_config.hypervisor.lower() @classmethod def setUpClass(cls): super(RebuildServerTests, cls).setUpClass() cls.key = cls.keypairs_client.create_keypair(rand_name("key")).entity cls.resources.add(cls.key.name, cls.keypairs_client.delete_keypair) response = cls.server_behaviors.create_active_server( key_name=cls.key.name) cls.server = response.entity response = cls.flavors_client.get_flavor_details(cls.flavor_ref) cls.flavor = response.entity cls.resources.add(cls.server.id, cls.servers_client.delete_server) cls.metadata = {'key': 'value'} cls.name = rand_name('testserver') cls.file_contents = 'Test server rebuild.' personality = [{'path': '/rebuild.txt', 'contents': base64.b64encode(cls.file_contents)}] cls.password = '******' cls.rebuilt_server_response = cls.servers_client.rebuild( cls.server.id, cls.image_ref_alt, name=cls.name, metadata=cls.metadata, personality=personality, admin_pass=cls.password, key_name=cls.key.name) cls.server_behaviors.wait_for_server_status( cls.server.id, NovaServerStatusTypes.ACTIVE) @tags(type='smoke', net='no') def test_verify_rebuild_server_response(self): # Verify the properties in the initial response are correct rebuilt_server = self.rebuilt_server_response.entity if rebuilt_server.addresses.public is not None: v4_address = rebuilt_server.addresses.public.ipv4 v6_address = rebuilt_server.addresses.public.ipv6 self.assertEqual(v4_address, self.server.accessIPv4, msg="AccessIPv4 did not match") self.assertEqual(v6_address, self.server.accessIPv6, msg="AccessIPv6 did not match") self.assertEqual(rebuilt_server.name, self.name, msg="Server name did not match") self.assertEqual(rebuilt_server.image.id, self.image_ref_alt, msg="Image id did not match") self.assertEqual(rebuilt_server.flavor.id, self.flavor_ref, msg="Flavor id did not match") self.assertEqual(rebuilt_server.id, self.server.id, msg="Server id did not match") self.assertEqual(rebuilt_server.links.bookmark, self.server.links.bookmark, msg="Bookmark links do not match") self.assertEqual(rebuilt_server.metadata.get('key'), 'value') self.assertEqual(rebuilt_server.created, self.server.created, msg="Server Created date changed after rebuild") self.assertTrue(rebuilt_server.updated != self.server.updated, msg="Server Updated date not changed after rebuild") self.assertEquals(rebuilt_server.addresses, self.server.addresses, msg="Server IP addresses changed after rebuild") @tags(type='smoke', net='yes') def test_can_log_into_server_after_rebuild(self): server = self.rebuilt_server_response.entity rebuilt_server = self.rebuilt_server_response.entity public_address = self.server_behaviors.get_public_ip_address( rebuilt_server) remote_instance = self.server_behaviors.get_remote_instance_client( server, config=self.servers_config, password=self.password, key=self.key.private_key) self.assertTrue( remote_instance.can_connect_to_public_ip(), msg="Could not connect to server (%s) using new admin password %s" % (public_address, server.admin_pass)) @tags(type='smoke', net='yes') def test_rebuilt_server_vcpus(self): """Verify the number of vCPUs reported is the correct after rebuild""" remote_client = self.server_behaviors.get_remote_instance_client( self.server, config=self.servers_config, password=self.password, key=self.key.private_key) server_actual_vcpus = remote_client.get_number_of_vcpus() self.assertEqual( server_actual_vcpus, self.flavor.vcpus, msg="Expected number of vcpus to be {0}, was {1}.".format( self.flavor.vcpus, server_actual_vcpus)) @tags(type='smoke', net='yes') def test_rebuilt_server_disk_size(self): """Verify the size of the virtual disk after the server rebuild""" remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, password=self.password, key=self.key.private_key) disk_size = remote_client.get_disk_size_in_gb( self.servers_config.instance_disk_path) self.assertEqual(disk_size, self.flavor.disk, msg="Expected disk to be {0} GB, was {1} GB".format( self.flavor.disk, disk_size)) @tags(type='smoke', net='yes') def test_server_ram_after_rebuild(self): remote_instance = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, password=self.password, key=self.key.private_key) lower_limit = int(self.flavor.ram) - (int(self.flavor.ram) * .1) server_ram_size = int(remote_instance.get_ram_size_in_mb()) self.assertTrue((int(self.flavor.ram) == server_ram_size or lower_limit <= server_ram_size), msg='Ram size after confirm-resize did not match.' 'Expected ram size : %s, Actual ram size : %s.' % (self.flavor.ram, server_ram_size)) @tags(type='smoke', net='yes') @unittest.skip("Known issue") def test_personality_file_created_on_rebuild(self): """ Validate the injected file was created on the rebuilt server with the correct contents """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, password=self.password, key=self.key.private_key) self.assertTrue(remote_client.is_file_present('/rebuild.txt')) self.assertEqual( remote_client.get_file_details('/rebuild.txt').content, self.file_contents) @tags(type='smoke', net='no') def test_server_metadata_set_on_rebuild(self): """Verify the provided metadata was set for the rebuilt server""" rebuilt_server = self.rebuilt_server_response.entity # Verify the metadata items were added to the server self.assertIn('key', rebuilt_server.metadata) # Verify the values of the metadata items are correct self.assertEqual(rebuilt_server.metadata.get('key'), 'value') @tags(type='smoke', net='no') def test_rebuilt_server_instance_actions(self): """Verify the correct actions are logged during a rebuild.""" actions = self.servers_client.get_instance_actions( self.server.id).entity # Verify the rebuild action is listed self.assertTrue(any(a.action == 'rebuild' for a in actions)) filtered_actions = [a for a in actions if a.action == 'rebuild'] self.assertEquals(len(filtered_actions), 1) rebuild_action = filtered_actions[0] self.validate_instance_action( rebuild_action, self.server.id, self.user_config.user_id, self.user_config.project_id, self.rebuilt_server_response.headers['x-compute-request-id']) @tags(type='smoke', net='yes') @unittest.skipUnless( hypervisor == ComputeHypervisors.XEN_SERVER, 'Requires Xen Server.') def test_rebuilt_server_xenstore_metadata(self): """Verify the provided metadata was set for the server""" remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, password=self.password, key=self.key.private_key) xen_meta = remote_client.get_xen_user_metadata() for key, value in self.metadata.iteritems(): self.assertEqual(xen_meta[key], value)
class ServersTest(ComputeFixture): compute_config = ComputeConfig() hypervisor = compute_config.hypervisor.lower() @unittest.skipIf(hypervisor in [ComputeHypervisors.KVM, ComputeHypervisors.QEMU], 'Password authentication disabled.') @tags(type='positive', net='yes') def test_create_server_with_admin_password(self): """ Creates a server with an admin password to be used as root's password. This will set the server that is created with the root password of oldslice129690TuG72Bgj2. Calls cloudcafe's server behaviors get remote instance client with the password to validate that it can authenticate wth password. The following assertions occur: - Defined password is the same as the admin password. - get_remote_instance_client has a true value for can_authenticate """ admin_password = '******' response = self.server_behaviors.create_active_server( admin_pass=admin_password) server = response.entity self.resources.add(server.id, self.servers_client.delete_server) self.assertEqual(admin_password, server.admin_pass) remote_client = self.server_behaviors.get_remote_instance_client( server, self.servers_config, password=admin_password, auth_strategy=InstanceAuthStrategies.PASSWORD) self.assertTrue(remote_client.can_authenticate(), msg="Cannot authenticate to the server.") @tags(type='positive', net='no') def test_update_server(self): """ Creates a server and then updates the name, ipv4 and ipv6 values. Will call the create_active_server from server behaviors, then call update_server from cloudcafe's server_client passing in the newly created server's id, new random name, ipv4 address 192.168.32.16 and ipv6 address 3ffe:1900:4545:3:200:f8ff:fe21:67cf and then waiting for the server to make it to active status. Calling get_server to validate the updates occurred correctly The following assertions occur: - Server name was updated with new random name. - Server's IPV4 address is 192.168.32.16. - Server's IPV6 address is 3ffe:1900:4545:3:200:f8ff:fe21:67cf. - Server's creation date is still the same as the original. - Server's updated date is not the same as the original. """ response = self.server_behaviors.create_active_server() original_server = response.entity self.resources.add(original_server.id, self.servers_client.delete_server) # Use server bookmark's link to update the server new_name = rand_name("testserver") accessIPv4 = '192.168.32.16' accessIPv6 = '3ffe:1900:4545:3:200:f8ff:fe21:67cf' updated_server_response = self.servers_client.update_server( original_server.id, new_name, accessIPv4=accessIPv4, accessIPv6=accessIPv6) updated_server = updated_server_response.entity self.server_behaviors.wait_for_server_status( updated_server.id, NovaServerStatusTypes.ACTIVE) # Verify the name and access ips of the server have changed server = self.servers_client.get_server(updated_server.id).entity self.assertEqual(new_name, server.name, msg="The server name was not updated") self.assertEqual(accessIPv4, server.accessIPv4, msg="AccessIPv4 address was not updated") self.assertEqual(accessIPv6, server.accessIPv6, msg="AccessIPv6 address was not updated") self.assertEqual(server.created, updated_server.created, msg="The server creation date was updated") self.assertNotEqual( server.updated, original_server.updated, msg="Updated time for server {server_id} " "did not change after a modification to the server.".format( server_id=server.id))
class CreateServerTest(object): compute_config = ComputeConfig() hypervisor = compute_config.hypervisor.lower() servers_config = ServersConfig() file_injection_enabled = servers_config.personality_file_injection_enabled @tags(type='smoke', net='no') def test_create_server_response(self): """ A create server request should return a server id and server links value Validate that the server created during test set up has a Server id value. Validate that the server created during test set up has a value for server links. The following assertions occur: - The id of the server created during test set up is not None - The server links value of the server created during test set up is not None """ self.assertTrue(self.server.id is not None, msg="Server id was not set in the response") self.assertTrue(self.server.links is not None, msg="Server links were not set in the response") @unittest.skipIf(hypervisor in [ComputeHypervisors.ON_METAL], 'Admin Password not supported in current configuration.') @tags(type='smoke', net='no') def test_create_server_admin_password(self): """ A create server request should return an admin password Validate that the server created during test set up has an admin password value. The following validations occur: - The admin password of the server created during test set up is not None """ self.assertTrue(self.server.admin_pass is not None, msg="Admin password was not set in the response") @tags(type='smoke', net='no') def test_created_server_fields(self): """ Verify that a created server has all expected fields The name and flavor id of the server created during test set up should match the values set during test set up and configuration. The 'updated' value of the server should be greater than the 'created' value. The following assertions occur: - The name of the server created during test set up is equal to the server name value generated during test set up - The flavor id of the server created during test set up is equal to the flavor id used in test configuration - The server 'created' value of the server created during test set up is not None - The server 'updated' value of the server created during test set up is not None - The server 'updated' value of the server created during test set up is greater than the 'created' value of the server created during test set up """ message = "Expected {0} to be {1}, was {2}." self.assertEqual(self.server.name, self.name, msg=message.format('server name', self.server.name, self.name)) self.assertEqual(self.server.flavor.id, self.flavor_ref, msg=message.format('flavor id', self.flavor_ref, self.server.flavor.id)) self.assertTrue(self.server.created is not None, msg="Expected server created date to be set") self.assertTrue(self.server.updated is not None, msg="Expected server updated date to be set.") self.assertGreaterEqual(self.server.updated, self.server.created, msg='Expected server updated date to be' 'after the created date.') @tags(type='smoke', net='no') def test_server_addresses(self): """ A server should have the expected network configuration. Get the addresses of the server created during test set up. Get a dictionary of expected networks from test configuration. For each network in the expected networks dictionary check to see if the test was configured to expect an IPv4 address for that network, if yes validate that there is a network of the same name with an IPv4 address. If that network is expected to not have an IPv4 addressm validate that there is a a network with that name that does not have an IPv4 address. For each network in the expected networks dictionary check to see if the test was configured to expect an IPv6 address for that network, if yes validate that there is a network of the same name with an IPv6 address. If that network is expected to not have an IPv6 addressm validate that there is a a network with that name that does not have an IPv6 address. The following assertions occur: - Each network in the expected networks dictionary from test configuration is found in the networks of the server created during test set up - If the network is expected to have an IPv4 address validate that the IPv4 address for the network of the same name from the server created during set up is not None - If the network is expected to not have an IPv4 address validate that the IPv4 address for the network of the same name from the server created during set up is None - If the network is expected to have an IPv6 address validate that the IPv6 address for the network of the same name from the server created during set up is not None - If the network is expected to not have an IPv6 address validate that the IPv6 address for the network of the same name from the server created during set up is None """ addresses = self.server.addresses for name, ip_addresses in self.expected_networks.iteritems(): network = addresses.get_by_name(name) if ip_addresses.get('v4'): self.assertIsNotNone( network.ipv4, msg='Expected {name} network to have an IPv4 address.'. format(name=name)) else: self.assertIsNone( network.ipv4, msg='Expected {name} network to not have an IPv4 address.'. format(name=name)) if ip_addresses.get('v6'): self.assertIsNotNone( network.ipv6, msg='Expected {name} network to have an IPv6 address.'. format(name=name)) else: self.assertIsNone( network.ipv6, msg='Expected {name} network to not have an IPv6 address.'. format(name=name)) @tags(type='smoke', net='yes') def test_created_server_vcpus(self): """ vCPUs of a server should be equal to the server's flavor's vCPU value Get a remote client for the server created during test set up. Use the remote client to get the number of CPUs for the server. Validate that this value is equal to the vCPUs of the flavor from test configuration. The following validations occur: - The vCPUs value of the flavor from test configuration is equal to the number of CPUs on the server created during test set up """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) server_actual_vcpus = remote_client.get_number_of_cpus() self.assertEqual( server_actual_vcpus, self.flavor.vcpus, msg="Expected number of vcpus to be {0}, was {1}.".format( self.flavor.vcpus, server_actual_vcpus)) @tags(type='smoke', net='yes') def test_created_server_ephemeral_disk(self): """ Server's ephemeral disk(s) size should equal the flavor's disk(s) size The size of the ephemeral disk(s) of the server created during test set up should be equal to the size of the ephemeral disk(s) of the flavor from test configuration, If the flavors ephemeral disk(s) size is 0, the test will return and end. If the flavor's ephemeral disk(s) size is not 0, get a remote client for the server created during test set up. Use the remote client to get a list of all disks on the server. Remove the primary disk from the list of disks. Verify that the remaining disks in the disk list are equal in size to the ephemeral disk size of the flavor from test configuration. Format each disk in the list of disks and mount them to the server. """ if self.flavor.ephemeral_disk == 0: # No ephemeral disk, no further validation necessary return remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) # Get all disks and remove the primary disk from the list disks = remote_client.get_all_disks() disks.pop(self.servers_config.instance_disk_path, None) # Verify the ephemeral disks have the correct size self._verify_ephemeral_disk_size( disks=disks, flavor=self.flavor, split_ephemeral_disk_enabled=self.split_ephemeral_disk_enabled, ephemeral_disk_max_size=self.ephemeral_disk_max_size) # Partition and format the disks for disk in disks: self._format_disk(remote_client=remote_client, disk=disk, disk_format=self.disk_format_type) mount_point = remote_client.generate_mountpoint() self._mount_disk(remote_client=remote_client, disk=disk, mount_point=mount_point) @tags(type='smoke', net='yes') def test_created_server_ram(self): """ RAM of a server should be equal to the server's flavor's RAM value Get a remote instance client for the instance created during test set up. Calculate the minimum acceptable RAM value, this is 90% of the RAM value of the flavor from test configuration. Validate that the RAM of the server is equal to the RAM value of the flavor from the test configuration or greater than/equal to the minimum RAM value previously calculated. The following assertions occur: - The RAM value of the server created during test set up is equal to the RAM value of the flavor from test configuration or greater than/equal to a value that is 90% of the RAM value of the flavor from test configuration """ remote_instance = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) lower_limit = int(self.flavor.ram) - (int(self.flavor.ram) * .1) server_ram_size = int(remote_instance.get_allocated_ram()) self.assertTrue((int(self.flavor.ram) == server_ram_size or lower_limit <= server_ram_size), msg='Unexpected ram size.' 'Expected ram size : %s, Actual ram size : %s'.format( self.flavor.ram, server_ram_size)) @tags(type='smoke', net='yes') def test_created_server_hostname(self): """ The hostname of the server is the same as the server name Get a remote instance client for the server created during test set up. Use the remote client to get the host name of the server. Validate that the host name is equal to the name value set during test set up. The following assertions occur: - The host name of the server created during test set up is equal to the name value generated during test set up """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) hostname = remote_client.get_hostname() self.assertEqual(hostname, self.name, msg="Expected hostname to be {0}, was {1}".format( self.name, hostname)) @tags(type='smoke', net='yes') def test_can_log_into_created_server(self): """ A server should be able to be accessed using a remote instance client Get a remote instance client for the server created during test set up. Validate that the remote instance client can authenticate to the server. The following assertions occur: - The remote client for the server created during test set up can authenticate to the server """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) self.assertTrue(remote_client.can_authenticate(), msg="Cannot connect to server using public ip") @tags(type='smoke', net='yes') @unittest.skipUnless(file_injection_enabled, "File injection disabled.") def test_personality_file_created(self): """ A file injected during test set up should have the expected contents Get a remote instance client for the server created during test set up. Use the remote instance client to validate that a file exists at the location set by the file path value set during test set up. Use the remote client to validate that the contents of the file on the server are equal to the file contents set during test set up. The following assertions occur: - A file should be found on the server created during test set up at the location of the file path value created during test set. created during test set up - The file contents created during test set up should be equal to the contents of the file on the server created during test set up found at the file path created during test set up """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) self.assertTrue(remote_client.is_file_present(self.file_path)) self.assertEqual( remote_client.get_file_details(self.file_path).content, self.file_contents) @tags(type='smoke', net='no') def test_created_server_metadata(self): """ Verify the provided metadata was set for the server Validate that the key 'meta_key_1' and the key 'meta_key_2' are in the metadata for the server created during test set up. Validate that the value for the key 'meta_key_1' is equal to 'meta_value_1'. Validate that the value for the key 'meta_key_2' is equal to 'meta_value_2'. The following assertions occur: - The key 'meta_key_1' is in the metadata on the server created during test set up - The key 'meta_key_2' is in the metadata on the server created during test set up - The value of the 'meta_key_1' key in the metadata on the server created during test set up is equal to 'meta_value_1' - The value of the 'meta_key_1' key in the metadata on the server created during test set up is equal to 'meta_value_1' """ # Verify the metadata items were added to the server self.assertIn('meta_key_1', self.server.metadata) self.assertIn('meta_key_2', self.server.metadata) # Verify the values of the metadata items are correct self.assertEqual(self.server.metadata.get('meta_key_1'), 'meta_value_1') self.assertEqual(self.server.metadata.get('meta_key_2'), 'meta_value_2') @tags(type='smoke', net='no') def test_created_server_instance_actions(self): """ Verify the correct actions are logged during a server creation. Get the list of all actions that the server has taken from the Nova API. Filter the list so that only the actions 'create' remain. Validate that the list of filtered actions has a length of 1 (that only 1 create action has been performed.) Validate that the values of the identified create action match the values returned in the create server response received during test setup. The following assertions occur: - The list of actions that match 'create' has only one item - The values for the create action match the values received in response to the create request """ actions = self.servers_client.get_instance_actions( self.server.id).entity # Verify the create action is listed self.assertTrue(any(a.action == 'create' for a in actions)) filtered_actions = [a for a in actions if a.action == 'create'] self.assertEquals(len(filtered_actions), 1) create_action = filtered_actions[0] self.validate_instance_action( create_action, self.server.id, self.user_config.user_id, self.user_config.project_id, self.create_resp.headers['x-compute-request-id']) @tags(type='smoke', net='yes') @unittest.skipUnless(hypervisor == ComputeHypervisors.XEN_SERVER, 'Requires Xen Server.') def test_created_server_xenstore_metadata(self): """ Verify the provided metadata was set in the server's Xenstore metadata Get a remote instance client for the server created during test set up. Use the remote instance client to get the Xen client metadata from the server. Validate that each key value pair of the metadata dictionary generated during test set up is found in the Xen client metadata. The following assertions occur: - For each metadata key in the metadata dictionary generated during test set up, the key should be found in the Xen metadata of the server created during test set up - For each metadata key value value pair in the metadata dictionary generated during test set up, the value should be equal to the value of the key in the Xen metadata of the server created during test set up """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) xen_meta = remote_client.get_xen_user_metadata() for key, value in self.metadata.iteritems(): self.assertIn(key, xen_meta) self.assertEqual(xen_meta[key], value) @tags(type='smoke', net='yes') @unittest.skipUnless(hypervisor == ComputeHypervisors.XEN_SERVER, 'Requires Xen Server.') def test_xenstore_disk_config(self): """ The disk config of a server should be accurate on the XenStore metadata Get a remote instance client for the server created during test set up. Use the remote instance client to get a boolean value representing whether the auto_config_enabled value in the XenStore on the server created during setup. Validate that if the disk_config value of the server created during test set up is 'auto' the auto_config_enabled value in the XenStore is True. Or if the disk_config value of the server created during test set up is not 'auto' the auto_config_enabled value in the XenStore is False. The following assertions occur: - The auto_config_enable value in the XenStore on the server created during test configuration is equal to True is the server's disk config is equal to 'auto'. Or the auto_config_enable value is false if the server's disk config is not equal to 'auto' """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) auto_config_enabled = remote_client.get_xenstore_disk_config_value() actual_disk_config = self.server.disk_config self.assertEqual(auto_config_enabled, actual_disk_config.lower() == 'auto')
class CreateServerTest(ComputeFixture): compute_config = ComputeConfig() hypervisor = compute_config.hypervisor.lower() @classmethod def setUpClass(cls): super(CreateServerTest, cls).setUpClass() cls.name = rand_name("server") cls.metadata = {'meta_key_1': 'meta_value_1', 'meta_key_2': 'meta_value_2'} cls.file_contents = 'This is a test file.' files = [{'path': '/test.txt', 'contents': base64.b64encode( cls.file_contents)}] cls.key = cls.keypairs_client.create_keypair(rand_name("key")).entity cls.resources.add(cls.key.name, cls.keypairs_client.delete_keypair) cls.create_resp = cls.servers_client.create_server( cls.name, cls.image_ref, cls.flavor_ref, metadata=cls.metadata, personality=files, key_name=cls.key.name) created_server = cls.create_resp.entity cls.resources.add(created_server.id, cls.servers_client.delete_server) wait_response = cls.server_behaviors.wait_for_server_status( created_server.id, NovaServerStatusTypes.ACTIVE) wait_response.entity.admin_pass = created_server.admin_pass cls.image = cls.images_client.get_image(cls.image_ref).entity cls.flavor = cls.flavors_client.get_flavor_details( cls.flavor_ref).entity cls.server = wait_response.entity @tags(type='smoke', net='no') def test_create_server_response(self): """Verify the parameters are correct in the initial response""" self.assertTrue(self.server.id is not None, msg="Server id was not set in the response") self.assertTrue(self.server.admin_pass is not None, msg="Admin password was not set in the response") self.assertTrue(self.server.links is not None, msg="Server links were not set in the response") @tags(type='smoke', net='no') def test_created_server_fields(self): """Verify that a created server has all expected fields""" message = "Expected {0} to be {1}, was {2}." self.assertEqual(self.server.name, self.name, msg=message.format('server name', self.server.name, self.name)) self.assertEqual(self.image_ref, self.server.image.id, msg=message.format('image id', self.image_ref, self.server.image.id)) self.assertEqual(self.server.flavor.id, self.flavor_ref, msg=message.format('flavor id', self.flavor_ref, self.server.flavor.id)) self.assertTrue(self.server.created is not None, msg="Expected server created date to be set") self.assertTrue(self.server.updated is not None, msg="Expected server updated date to be set.") self.assertGreaterEqual(self.server.updated, self.server.created, msg='Expected server updated date to be' 'after the created date.') @tags(type='smoke', net='no') def test_server_access_addresses(self): """ If the server has public addresses, the access IP addresses should be same as the public addresses """ addresses = self.server.addresses if addresses.public is not None: self.assertTrue( addresses.public.ipv4 is not None, msg="Expected server to have a public IPv4 address set.") self.assertTrue( addresses.public.ipv6 is not None, msg="Expected server to have a public IPv6 address set.") self.assertTrue( addresses.private.ipv4 is not None, msg="Expected server to have a private IPv4 address set.") self.assertEqual( addresses.public.ipv4, self.server.accessIPv4, msg="Expected access IPv4 address to be {0}, was {1}.".format( addresses.public.ipv4, self.server.accessIPv4)) self.assertEqual( addresses.public.ipv6, self.server.accessIPv6, msg="Expected access IPv6 address to be {0}, was {1}.".format( addresses.public.ipv6, self.server.accessIPv6)) @tags(type='smoke', net='yes') def test_created_server_vcpus(self): """ Verify the number of vCPUs reported matches the amount set by the flavor """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) server_actual_vcpus = remote_client.get_number_of_vcpus() self.assertEqual( server_actual_vcpus, self.flavor.vcpus, msg="Expected number of vcpus to be {0}, was {1}.".format( self.flavor.vcpus, server_actual_vcpus)) @tags(type='smoke', net='yes') def test_created_server_disk_size(self): """ Verify the size of the virtual disk matches the size set by the flavor """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) disk_size = remote_client.get_disk_size_in_gb( self.servers_config.instance_disk_path) self.assertEqual(disk_size, self.flavor.disk, msg="Expected disk to be {0} GB, was {1} GB".format( self.flavor.disk, disk_size)) @tags(type='smoke', net='yes') def test_created_server_ram(self): """ The server's RAM and should be set to the amount specified in the flavor """ remote_instance = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) lower_limit = int(self.flavor.ram) - (int(self.flavor.ram) * .1) server_ram_size = int(remote_instance.get_ram_size_in_mb()) self.assertTrue( (int(self.flavor.ram) == server_ram_size or lower_limit <= server_ram_size), msg='Unexpected ram size.' 'Expected ram size : %s, Actual ram size : %s'.format( self.flavor.ram, server_ram_size)) @tags(type='smoke', net='yes') def test_created_server_hostname(self): """ Verify that the hostname of the server is the same as the server name """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) hostname = remote_client.get_hostname() self.assertEqual(hostname, self.name, msg="Expected hostname to be {0}, was {1}".format( self.name, hostname)) @tags(type='smoke', net='yes') def test_can_log_into_created_server(self): """Validate that the server instance can be accessed""" remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) self.assertTrue(remote_client.can_connect_to_public_ip(), msg="Cannot connect to server using public ip") @tags(type='smoke', net='yes') def test_personality_file_created(self): """ Validate the injected file was created on the server with the correct contents """ remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) self.assertTrue(remote_client.is_file_present('/test.txt')) self.assertEqual( remote_client.get_file_details('/test.txt').content, self.file_contents) @tags(type='smoke', net='no') def test_created_server_metadata(self): """Verify the provided metadata was set for the server""" # Verify the metadata items were added to the server self.assertTrue(hasattr(self.server.metadata, 'meta_key_1')) self.assertTrue(hasattr(self.server.metadata, 'meta_key_2')) # Verify the values of the metadata items are correct self.assertEqual(self.server.metadata.meta_key_1, 'meta_value_1') self.assertEqual(self.server.metadata.meta_key_2, 'meta_value_2') @tags(type='smoke', net='no') def test_created_server_instance_actions(self): """Verify the correct actions are logged while creating a server.""" actions = self.servers_client.get_instance_actions( self.server.id).entity # Verify the create action is listed self.assertTrue(any(a.action == 'create' for a in actions)) filtered_actions = [a for a in actions if a.action == 'create'] self.assertEquals(len(filtered_actions), 1) create_action = filtered_actions[0] self.validate_instance_action( create_action, self.server.id, self.user_config.user_id, self.user_config.project_id, self.create_resp.headers['x-compute-request-id']) @tags(type='smoke', net='yes') @unittest.skipUnless( hypervisor == ComputeHypervisors.XEN_SERVER, 'Requires Xen Server.') def test_created_server_xenstore_metadata(self): """Verify the provided metadata was set for the server""" remote_client = self.server_behaviors.get_remote_instance_client( self.server, self.servers_config, key=self.key.private_key) xen_meta = remote_client.get_xen_user_metadata() for key, value in self.metadata.iteritems(): self.assertEqual(xen_meta[key], value)
class ServersTest(ComputeFixture): compute_config = ComputeConfig() hypervisor = compute_config.hypervisor.lower() @unittest.skipIf(hypervisor in [ComputeHypervisors.KVM, ComputeHypervisors.QEMU], 'Password authentication disabled.') @tags(type='positive', net='yes') def test_create_server_with_admin_password(self): """ If an admin password is provided on server creation, the server's root password should be set to that password. """ admin_password = '******' response = self.server_behaviors.create_active_server( admin_pass=admin_password) server = response.entity self.resources.add(server.id, self.servers_client.delete_server) self.assertEqual(admin_password, server.admin_pass) remote_client = self.server_behaviors.get_remote_instance_client( server, self.servers_config, password=admin_password, auth_strategy=InstanceAuthStrategies.PASSWORD) self.assertTrue(remote_client.can_authenticate(), msg="Cannot authenticate to the server.") @tags(type='positive', net='no') def test_update_server(self): """Update the name and access addresses of a server.""" response = self.server_behaviors.create_active_server() original_server = response.entity self.resources.add(original_server.id, self.servers_client.delete_server) # Use server bookmark's link to update the server new_name = rand_name("testserver") accessIPv4 = '192.168.32.16' accessIPv6 = '3ffe:1900:4545:3:200:f8ff:fe21:67cf' updated_server_response = self.servers_client.update_server( original_server.id, new_name, accessIPv4=accessIPv4, accessIPv6=accessIPv6) updated_server = updated_server_response.entity self.server_behaviors.wait_for_server_status( updated_server.id, NovaServerStatusTypes.ACTIVE) # Verify the name and access ips of the server have changed server = self.servers_client.get_server(updated_server.id).entity self.assertEqual(new_name, server.name, msg="The server name was not updated") self.assertEqual(accessIPv4, server.accessIPv4, msg="AccessIPv4 address was not updated") self.assertEqual(accessIPv6, server.accessIPv6, msg="AccessIPv6 address was not updated") self.assertEqual(server.created, updated_server.created, msg="The server creation date was updated") self.assertNotEqual( server.updated, original_server.updated, msg="Updated time for server {server_id} " "did not change after a modification to the server.".format( server_id=server.id))