def test_upload_download_bucket_content_with_large_file(self): # Creates a 6 Gig file in the temp directory, then uploads it to # Swift. Once uploaded, then downloads to a new file in the temp # directory and compares the two files to see if they match. temp_dir = tempfile.gettempdir() file_name = '6GigTest.tmp' six_gig_file = os.path.join(temp_dir, file_name) with open(six_gig_file, "wb") as out: out.truncate(6 * 1024 * 1024 * 1024) # 6 Gig... with cb_helpers.cleanup_action(lambda: os.remove(six_gig_file)): download_file = "{0}/cbtestfile-{1}".format(temp_dir, file_name) bucket_name = "cbtestbucketlargeobjs-{0}".format( helpers.get_uuid()) test_bucket = self.provider.storage.buckets.create(bucket_name) with cb_helpers.cleanup_action(lambda: test_bucket.delete()): test_obj = test_bucket.objects.create(file_name) with cb_helpers.cleanup_action(lambda: test_obj.delete()): file_uploaded = test_obj.upload_from_file(six_gig_file) self.assertTrue(file_uploaded, "Could not upload object?") with cb_helpers.cleanup_action( lambda: os.remove(download_file)): with open(download_file, 'wb') as f: test_obj.save_content(f) self.assertTrue( filecmp.cmp(six_gig_file, download_file), "Uploaded file != downloaded")
def test_crud_bucket_object_properties(self): # Create a new bucket, upload some contents into the bucket, and # check whether list properly detects the new content. # Delete everything afterwards. name = "cbtestbucketobjs-{0}".format(helpers.get_uuid()) test_bucket = self.provider.storage.buckets.create(name) # ensure that the bucket is empty objects = test_bucket.objects.list() self.assertEqual([], objects) with cb_helpers.cleanup_action(lambda: test_bucket.delete()): obj_name_prefix = "hello" obj_name = obj_name_prefix + "_world.txt" obj = test_bucket.objects.create(obj_name) with cb_helpers.cleanup_action(lambda: obj.delete()): # TODO: This is wrong. We shouldn't have to have a separate # call to upload some content before being able to delete # the content. Maybe the create_object method should accept # the file content as a parameter. obj.upload("dummy content") objs = test_bucket.objects.list() self.assertTrue( isinstance(objs[0].size, int), "Object size property needs to be a int, not {0}".format( type(objs[0].size))) # GET an object as the size property implementation differs # for objects returned by LIST and GET. obj = test_bucket.objects.get(objs[0].id) self.assertTrue( isinstance(objs[0].size, int), "Object size property needs to be an int, not {0}".format( type(obj.size))) self.assertTrue( datetime.strptime(objs[0].last_modified[:23], "%Y-%m-%dT%H:%M:%S.%f"), "Object's last_modified field format {0} not matching.". format(objs[0].last_modified)) # check iteration iter_objs = list(test_bucket.objects) self.assertListEqual(iter_objs, objs) obj_too = test_bucket.objects.get(obj_name) self.assertTrue( isinstance(obj_too, BucketObject), "Did not get object {0} of expected type.".format(obj_too)) prefix_filtered_list = test_bucket.objects.list( prefix=obj_name_prefix) self.assertTrue( len(objs) == len(prefix_filtered_list) == 1, 'The number of objects returned by list function, ' 'with and without a prefix, are expected to be equal, ' 'but its detected otherwise.') sit.check_delete(self, test_bucket.objects, obj)
def test_volume_properties(self): label = "cb-volprops-{0}".format(helpers.get_uuid()) vol_desc = 'newvoldesc1' # Declare these variables and late binding will allow # the cleanup method access to the most current values test_instance = None with cb_helpers.cleanup_action(lambda: helpers.cleanup_test_resources( test_instance)): subnet = helpers.get_or_create_default_subnet( self.provider) test_instance = helpers.get_test_instance( self.provider, label, subnet=subnet) test_vol = self.provider.storage.volumes.create( label, 1, description=vol_desc) with cb_helpers.cleanup_action(lambda: test_vol.delete()): test_vol.wait_till_ready() self.assertTrue( isinstance(test_vol.size, six.integer_types) and test_vol.size >= 0, "Volume.size must be a positive number, but got %s" % test_vol.size) self.assertTrue( test_vol.description is None or isinstance(test_vol.description, six.string_types), "Volume.description must be None or a string. Got: %s" % test_vol.description) self.assertIsNone(test_vol.source) self.assertIsNone(test_vol.source) self.assertIsNotNone(test_vol.create_time) self.assertIsNotNone(test_vol.zone_id) self.assertIsNone(test_vol.attachments) test_vol.attach(test_instance, '/dev/sda2') test_vol.wait_for( [VolumeState.IN_USE], terminal_states=[VolumeState.ERROR, VolumeState.DELETED]) self.assertIsNotNone(test_vol.attachments) self.assertIsInstance(test_vol.attachments, AttachmentInfo) self.assertEqual(test_vol.attachments.volume, test_vol) self.assertEqual(test_vol.attachments.instance_id, test_instance.id) if (self.provider.PROVIDER_ID != 'azure' and self.provider.PROVIDER_ID != 'gcp'): self.assertEqual(test_vol.attachments.device, "/dev/sda2") test_vol.detach() test_vol.label = 'newvolname1' test_vol.wait_for( [VolumeState.AVAILABLE], terminal_states=[VolumeState.ERROR, VolumeState.DELETED]) self.assertEqual(test_vol.label, 'newvolname1') self.assertEqual(test_vol.description, vol_desc) self.assertIsNone(test_vol.attachments) test_vol.wait_for( [VolumeState.AVAILABLE], terminal_states=[VolumeState.ERROR, VolumeState.DELETED])
def test_network_properties(self): label = 'cb-propnetwork-{0}'.format(helpers.get_uuid()) subnet_label = 'cb-propsubnet-{0}'.format(helpers.get_uuid()) net = self.provider.networking.networks.create( label=label, cidr_block=BaseNetwork.CB_DEFAULT_IPV4RANGE) with cb_helpers.cleanup_action(lambda: helpers.cleanup_network(net)): net.wait_till_ready() self.assertEqual( net.state, 'available', "Network in state '%s', yet should be 'available'" % net.state) sit.check_repr(self, net) self.assertIn( net.cidr_block, ['', BaseNetwork.CB_DEFAULT_IPV4RANGE], "Network CIDR %s does not contain the expected value %s." % (net.cidr_block, BaseNetwork.CB_DEFAULT_IPV4RANGE)) cidr = '10.0.20.0/24' sn = net.subnets.create( label=subnet_label, cidr_block=cidr) with cb_helpers.cleanup_action(lambda: helpers.cleanup_subnet(sn)): self.assertTrue( sn in net.subnets, "Subnet ID %s should be listed in network subnets %s." % (sn.id, net.subnets)) self.assertTrue( sn in self.provider.networking.subnets.list(network=net), "Subnet ID %s should be included in the subnets list %s." % (sn.id, self.provider.networking.subnets.list(net)) ) self.assertListEqual( list(net.subnets), [sn], "Network should have exactly one subnet: %s." % sn.id) self.assertEqual( net.id, sn.network_id, "Network ID %s and subnet's network id %s should be" " equal." % (net.id, sn.network_id)) self.assertEqual( net, sn.network, "Network obj %s and subnet's parent net obj %s" " should be equal." % (net, sn.network)) self.assertEqual( cidr, sn.cidr_block, "Should be exact cidr block that was requested") self.assertTrue( BaseNetwork.cidr_blocks_overlap(cidr, sn.cidr_block), "Subnet's CIDR %s should overlap the specified one %s." % ( sn.cidr_block, cidr))
def _cleanup(net, subnet, router, gateway): with cb_helpers.cleanup_action( lambda: helpers.cleanup_network(net)): with cb_helpers.cleanup_action( lambda: helpers.cleanup_subnet(subnet)): with cb_helpers.cleanup_action( lambda: router.delete()): with cb_helpers.cleanup_action( lambda: helpers.cleanup_gateway(gateway)): router.detach_subnet(subnet) router.detach_gateway(gateway)
def cleanup_test_resources(instance=None, vm_firewall=None, key_pair=None, network=None): """Clean up any combination of supplied resources.""" with cb_helpers.cleanup_action(lambda: cleanup_network(network) if network else None): with cb_helpers.cleanup_action(lambda: key_pair.delete() if key_pair else None): with cb_helpers.cleanup_action(lambda: vm_firewall.delete() if vm_firewall else None): delete_instance(instance)
def create_instance_from_image(img): img_instance = None with cb_helpers.cleanup_action( lambda: helpers.cleanup_test_resources(img_instance)): img_instance = self.provider.compute.instances.create( img_inst_label, img, helpers.get_provider_test_data(self.provider, 'vm_type'), subnet=subnet) img_instance.wait_till_ready() self.assertIsInstance(img_instance, Instance) self.assertEqual( img_instance.label, img_inst_label, "Instance label {0} is not equal to the expected label" " {1}".format(img_instance.label, img_inst_label)) image_id = img.id self.assertEqual( img_instance.image_id, image_id, "Image id {0} is not equal to the expected id" " {1}".format(img_instance.image_id, image_id)) self.assertIsInstance(img_instance.public_ips, list) if img_instance.public_ips: self.assertTrue( img_instance.public_ips[0], "public ip should contain a" " valid value if a list of public_ips exist") self.assertIsInstance(img_instance.private_ips, list) self.assertTrue(img_instance.private_ips[0], "private ip should" " contain a valid value")
def test_crud_bucket_object(self): test_bucket = None def create_bucket_obj(name): obj = test_bucket.objects.create(name) # TODO: This is wrong. We shouldn't have to have a separate # call to upload some content before being able to delete # the content. Maybe the create_object method should accept # the file content as a parameter. obj.upload("dummy content") return obj def cleanup_bucket_obj(bucket_obj): if bucket_obj: bucket_obj.delete() with cb_helpers.cleanup_action(lambda: test_bucket.delete()): name = "cb-crudbucketobj-{0}".format(helpers.get_uuid()) test_bucket = self.provider.storage.buckets.create(name) sit.check_crud(self, test_bucket.objects, BucketObject, "cb-bucketobj", create_bucket_obj, cleanup_bucket_obj, skip_name_check=True)
def test_upload_download_bucket_content_from_file(self): name = "cbtestbucketobjs-{0}".format(helpers.get_uuid()) test_bucket = self.provider.storage.buckets.create(name) with cb_helpers.cleanup_action(lambda: test_bucket.delete()): obj_name = "hello_upload_download.txt" obj = test_bucket.objects.create(obj_name) with cb_helpers.cleanup_action(lambda: obj.delete()): test_file = os.path.join(helpers.get_test_fixtures_folder(), 'logo.jpg') obj.upload_from_file(test_file) target_stream = BytesIO() obj.save_content(target_stream) with open(test_file, 'rb') as f: self.assertEqual(target_stream.getvalue(), f.read())
def test_object_life_cycle(self): # Test object life cycle methods by using a volume. label = "cb-objlifecycle-{0}".format(helpers.get_uuid()) test_vol = None with cb_helpers.cleanup_action(lambda: test_vol.delete()): test_vol = self.provider.storage.volumes.create(label, 1) # Waiting for an invalid timeout should raise an exception with self.assertRaises(AssertionError): test_vol.wait_for([VolumeState.ERROR], timeout=-1, interval=1) with self.assertRaises(AssertionError): test_vol.wait_for([VolumeState.ERROR], timeout=1, interval=-1) # If interval < timeout, an exception should be raised with self.assertRaises(AssertionError): test_vol.wait_for([VolumeState.ERROR], timeout=10, interval=20) test_vol.wait_till_ready() # Hitting a terminal state should raise an exception with self.assertRaises(WaitStateException): test_vol.wait_for([VolumeState.ERROR], terminal_states=[VolumeState.AVAILABLE]) # Hitting the timeout should raise an exception with self.assertRaises(WaitStateException): test_vol.wait_for([VolumeState.ERROR], timeout=0, interval=0)
def test_snapshot_properties(self): label = "cb-snapprop-{0}".format(helpers.get_uuid()) test_vol = self.provider.storage.volumes.create( label, 1) with cb_helpers.cleanup_action(lambda: test_vol.delete()): test_vol.wait_till_ready() snap_label = "cb-snap-{0}".format(label) test_snap = test_vol.create_snapshot(label=snap_label, description=snap_label) def cleanup_snap(snap): if snap: snap.delete() snap.wait_for([SnapshotState.UNKNOWN], terminal_states=[SnapshotState.ERROR]) with cb_helpers.cleanup_action(lambda: cleanup_snap(test_snap)): test_snap.wait_till_ready() self.assertTrue(isinstance(test_vol.size, six.integer_types)) self.assertEqual( test_snap.size, test_vol.size, "Snapshot.size must match original volume's size: %s" " but is: %s" % (test_vol.size, test_snap.size)) self.assertTrue( test_vol.description is None or isinstance(test_vol.description, six.string_types), "Snapshot.description must be None or a string. Got: %s" % test_vol.description) self.assertEqual(test_vol.id, test_snap.volume_id) self.assertIsNotNone(test_vol.create_time) test_snap.label = 'snapnewname1' test_snap.description = 'snapnewdescription1' test_snap.refresh() self.assertEqual(test_snap.label, 'snapnewname1') self.assertEqual(test_snap.description, 'snapnewdescription1') # Test volume creation from a snapshot (via VolumeService) sv_label = "cb-snapvol-{0}".format(test_snap.name) snap_vol = self.provider.storage.volumes.create( sv_label, 1, snapshot=test_snap) with cb_helpers.cleanup_action(lambda: snap_vol.delete()): snap_vol.wait_till_ready() # Test volume creation from a snapshot (via Snapshot) snap_vol2 = test_snap.create_volume() with cb_helpers.cleanup_action(lambda: snap_vol2.delete()): snap_vol2.wait_till_ready()
def test_cleanup_action_body_has_no_exception(self): invoke_order = [""] def cleanup_func(): invoke_order[0] += "cleanup" with cb_helpers.cleanup_action(lambda: cleanup_func()): invoke_order[0] += "body_" self.assertEqual(invoke_order[0], "body_cleanup")
def test_generate_url(self): name = "cbtestbucketobjs-{0}".format(helpers.get_uuid()) test_bucket = self.provider.storage.buckets.create(name) with cb_helpers.cleanup_action(lambda: test_bucket.delete()): obj_name = "hello_upload_download.txt" obj = test_bucket.objects.create(obj_name) with cb_helpers.cleanup_action(lambda: obj.delete()): content = b"Hello World. Generate a url." obj.upload(content) target_stream = BytesIO() obj.save_content(target_stream) url = obj.generate_url(100) if isinstance(self.provider, TestMockHelperMixin): raise self.skipTest( "Skipping rest of test - mock providers can't" " access generated url") self.assertEqual(requests.get(url).content, content)
def test_upload_download_bucket_content(self): name = "cbtestbucketobjs-{0}".format(helpers.get_uuid()) test_bucket = self.provider.storage.buckets.create(name) with cb_helpers.cleanup_action(lambda: test_bucket.delete()): obj_name = "hello_upload_download.txt" obj = test_bucket.objects.create(obj_name) with cb_helpers.cleanup_action(lambda: obj.delete()): content = b"Hello World. Here's some content." # TODO: Upload and download methods accept different parameter # types. Need to make this consistent - possibly provider # multiple methods like upload_from_file, from_stream etc. obj.upload(content) target_stream = BytesIO() obj.save_content(target_stream) self.assertEqual(target_stream.getvalue(), content) target_stream2 = BytesIO() for data in obj.iter_content(): target_stream2.write(data) self.assertEqual(target_stream2.getvalue(), content)
def cleanup_network(network): """ Delete the supplied network, first deleting any contained subnets. """ if network: try: for sn in network.subnets: with cb_helpers.cleanup_action(lambda: cleanup_subnet(sn)): pass finally: network.delete() network.wait_for([NetworkState.UNKNOWN], terminal_states=[NetworkState.ERROR])
def test_cleanup_action_body_has_exception(self): invoke_order = [""] def cleanup_func(): invoke_order[0] += "cleanup" class CustomException(Exception): pass with self.assertRaises(CustomException): with cb_helpers.cleanup_action(lambda: cleanup_func()): invoke_order[0] += "body_" raise CustomException() self.assertEqual(invoke_order[0], "body_cleanup")
def test_floating_ip_properties(self): # Check floating IP address gw = helpers.get_test_gateway( self.provider) fip = gw.floating_ips.create() with cb_helpers.cleanup_action( lambda: helpers.cleanup_gateway(gw)): with cb_helpers.cleanup_action(lambda: fip.delete()): fipl = list(gw.floating_ips) self.assertIn(fip, fipl) # 2016-08: address filtering not implemented in moto # empty_ipl = self.provider.network.floating_ips('dummy-net') # self.assertFalse( # empty_ipl, # "Bogus network should not have any floating IPs: {0}" # .format(empty_ipl)) self.assertFalse( fip.private_ip, "Floating IP should not have a private IP value ({0})." .format(fip.private_ip)) self.assertFalse( fip.in_use, "Newly created floating IP address should not be in use.")
def test_attach_detach_volume(self): label = "cb-attachvol-{0}".format(helpers.get_uuid()) # Declare these variables and late binding will allow # the cleanup method access to the most current values test_instance = None with cb_helpers.cleanup_action(lambda: helpers.cleanup_test_resources( test_instance)): subnet = helpers.get_or_create_default_subnet( self.provider) test_instance = helpers.get_test_instance( self.provider, label, subnet=subnet) test_vol = self.provider.storage.volumes.create( label, 1) with cb_helpers.cleanup_action(lambda: test_vol.delete()): test_vol.wait_till_ready() test_vol.attach(test_instance, '/dev/sda2') test_vol.wait_for( [VolumeState.IN_USE], terminal_states=[VolumeState.ERROR, VolumeState.DELETED]) test_vol.detach() test_vol.wait_for( [VolumeState.AVAILABLE], terminal_states=[VolumeState.ERROR, VolumeState.DELETED])
def _check_fip_connectivity(self, external_net): # Due to current limitations in OpenStack: # https://bugs.launchpad.net/neutron/+bug/1743480, it's not # possible to differentiate between floating ip networks and provider # external networks. Therefore, we systematically step through # all available networks and perform an assignment test to infer valid # floating ip nets. dummy_router = self._provider.networking.routers.create( label='cb-conn-test-router', network=self._network) with cb_helpers.cleanup_action(lambda: dummy_router.delete()): try: dummy_router.attach_gateway(external_net) return True except Exception: return False
def test_crud_floating_ip(self): gw = helpers.get_test_gateway( self.provider) def create_fip(label): fip = gw.floating_ips.create() return fip def cleanup_fip(fip): if fip: gw.floating_ips.delete(fip.id) with cb_helpers.cleanup_action( lambda: helpers.cleanup_gateway(gw)): sit.check_crud(self, gw.floating_ips, FloatingIP, "cb-crudfip", create_fip, cleanup_fip, skip_name_check=True)
def test_crud_snapshot(self): # Create a new volume, create a snapshot of the volume, and check # whether list_snapshots properly detects the new snapshot. # Delete everything afterwards. label = "cb-crudsnap-{0}".format(helpers.get_uuid()) test_vol = self.provider.storage.volumes.create( label, 1) with cb_helpers.cleanup_action(lambda: test_vol.delete()): test_vol.wait_till_ready() def create_snap(label): return test_vol.create_snapshot(label=label, description=label) def cleanup_snap(snap): if snap: snap.delete() snap.wait_for([SnapshotState.UNKNOWN], terminal_states=[SnapshotState.ERROR]) snap.refresh() self.assertTrue( snap.state == SnapshotState.UNKNOWN, "Snapshot.state must be unknown when refreshing after " "a delete but got %s" % snap.state) sit.check_crud(self, self.provider.storage.snapshots, Snapshot, "cb-snap", create_snap, cleanup_snap) # Test creation of a snap via SnapshotService def create_snap2(label): return self.provider.storage.snapshots.create( label=label, volume=test_vol, description=label) if (self.provider.PROVIDER_ID == ProviderList.AWS and not isinstance(self.provider, TestMockHelperMixin)): time.sleep(15) # Or get SnapshotCreationPerVolumeRateExceeded sit.check_crud(self, self.provider.storage.snapshots, Snapshot, "cb-snaptwo", create_snap2, cleanup_snap)
def test_instance_properties(self): label = "cb-inst-props-{0}".format(helpers.get_uuid()) # Declare these variables and late binding will allow # the cleanup method access to the most current values test_instance = None fw = None kp = None with cb_helpers.cleanup_action(lambda: helpers.cleanup_test_resources( test_instance, fw, kp)): subnet = helpers.get_or_create_default_subnet(self.provider) net = subnet.network kp = self.provider.security.key_pairs.create(name=label) fw = self.provider.security.vm_firewalls.create( label=label, description=label, network=net.id) test_instance = helpers.get_test_instance(self.provider, label, key_pair=kp, vm_firewalls=[fw], subnet=subnet) self.assertEqual( test_instance.label, label, "Instance label {0} is not equal to the expected label" " {1}".format(test_instance.label, label)) image_id = helpers.get_provider_test_data(self.provider, "image") self.assertEqual(test_instance.image_id, image_id, "Image id {0} is not equal to the expected id" " {1}".format(test_instance.image_id, image_id)) self.assertIsInstance(test_instance.zone_id, six.string_types) self.assertEqual( test_instance.image_id, helpers.get_provider_test_data(self.provider, "image")) self.assertIsInstance(test_instance.public_ips, list) if test_instance.public_ips: self.assertTrue( test_instance.public_ips[0], "public ip should contain a" " valid value if a list of public_ips exist") self.assertIsInstance(test_instance.private_ips, list) self.assertTrue(test_instance.private_ips[0], "private ip should" " contain a valid value") self.assertEqual( test_instance.key_pair_id, kp.id) self.assertIsInstance(test_instance.vm_firewalls, list) self.assertEqual( test_instance.vm_firewalls[0], fw) self.assertIsInstance(test_instance.vm_firewall_ids, list) self.assertEqual( test_instance.vm_firewall_ids[0], fw.id) # Must have either a public or a private ip ip_private = test_instance.private_ips[0] \ if test_instance.private_ips else None ip_address = test_instance.public_ips[0] \ if test_instance.public_ips and test_instance.public_ips[0] \ else ip_private # Convert to unicode for py27 compatibility with ipaddress() ip_address = u"{}".format(ip_address) self.assertIsNotNone( ip_address, "Instance must have either a public IP or a private IP") self.assertTrue( self._is_valid_ip(ip_address), "Instance must have a valid IP address. Got: %s" % ip_address) self.assertIsInstance(test_instance.vm_type_id, six.string_types) vm_type = self.provider.compute.vm_types.get( test_instance.vm_type_id) self.assertEqual( vm_type, test_instance.vm_type, "VM type {0} does not match expected type {1}".format( vm_type.name, test_instance.vm_type)) self.assertIsInstance(vm_type, VMType) expected_type = helpers.get_provider_test_data(self.provider, 'vm_type') self.assertEqual( vm_type.name, expected_type, "VM type {0} does not match expected type {1}".format( vm_type.name, expected_type)) find_zone = [zone for zone in self.provider.compute.regions.current.zones if zone.id == test_instance.zone_id] self.assertEqual(len(find_zone), 1, "Instance's placement zone could not be " " found in zones list")
def cleanup_router(router, gateway): with cb_helpers.cleanup_action(lambda: router.delete()): with cb_helpers.cleanup_action(lambda: gateway.delete()): router.detach_subnet(subnet) router.detach_gateway(gateway)
def test_instance_methods(self): label = "cb-instmethods-{0}".format(helpers.get_uuid()) # Declare these variables and late binding will allow # the cleanup method access to the most current values net = None test_inst = None fw = None with cb_helpers.cleanup_action(lambda: helpers.cleanup_test_resources( instance=test_inst, vm_firewall=fw, network=net)): net = self.provider.networking.networks.create( label=label, cidr_block=BaseNetwork.CB_DEFAULT_IPV4RANGE) cidr = '10.0.1.0/24' subnet = net.subnets.create(label=label, cidr_block=cidr) test_inst = helpers.get_test_instance(self.provider, label, subnet=subnet) fw = self.provider.security.vm_firewalls.create( label=label, description=label, network=net.id) # Check adding a VM firewall to a running instance test_inst.add_vm_firewall(fw) test_inst.refresh() self.assertTrue( fw in test_inst.vm_firewalls, "Expected VM firewall '%s'" " to be among instance vm_firewalls: [%s]" % (fw, test_inst.vm_firewalls)) # Check removing a VM firewall from a running instance test_inst.remove_vm_firewall(fw) test_inst.refresh() self.assertTrue( fw not in test_inst.vm_firewalls, "Expected VM firewall" " '%s' to be removed from instance vm_firewalls: [%s]" % (fw, test_inst.vm_firewalls)) # check floating ips router = self.provider.networking.routers.create(label, net) gateway = net.gateways.get_or_create() def cleanup_router(router, gateway): with cb_helpers.cleanup_action(lambda: router.delete()): with cb_helpers.cleanup_action(lambda: gateway.delete()): router.detach_subnet(subnet) router.detach_gateway(gateway) with cb_helpers.cleanup_action(lambda: cleanup_router(router, gateway)): router.attach_subnet(subnet) router.attach_gateway(gateway) fip = None with cb_helpers.cleanup_action( lambda: helpers.cleanup_fip(fip)): # check whether adding an elastic ip works fip = gateway.floating_ips.create() self.assertFalse( fip.in_use, "Newly created floating IP %s should not be in use." % fip.public_ip) with cb_helpers.cleanup_action( lambda: test_inst.remove_floating_ip(fip)): test_inst.add_floating_ip(fip) test_inst.refresh() # On Devstack, FloatingIP is listed under private_ips. self.assertIn(fip.public_ip, test_inst.public_ips + test_inst.private_ips) fip.refresh() self.assertTrue( fip.in_use, "Attached floating IP %s address should be in use." % fip.public_ip) test_inst.refresh() test_inst.reboot() test_inst.wait_till_ready() self.assertNotIn( fip.public_ip, test_inst.public_ips + test_inst.private_ips)
def test_block_device_mapping_attachments(self): label = "cb-blkattch-{0}".format(helpers.get_uuid()) if self.provider.PROVIDER_ID == ProviderList.OPENSTACK: raise self.skipTest("Not running BDM tests because OpenStack is" " not stable enough yet") test_vol = self.provider.storage.volumes.create( label, 1) with cb_helpers.cleanup_action(lambda: test_vol.delete()): test_vol.wait_till_ready() test_snap = test_vol.create_snapshot(label=label, description=label) def cleanup_snap(snap): if snap: snap.delete() snap.wait_for([SnapshotState.UNKNOWN], terminal_states=[SnapshotState.ERROR]) with cb_helpers.cleanup_action(lambda: cleanup_snap(test_snap)): test_snap.wait_till_ready() lc = self.provider.compute.instances.create_launch_config() # Add a new blank volume lc.add_volume_device(size=1, delete_on_terminate=True) # Attach an existing volume lc.add_volume_device(size=1, source=test_vol, delete_on_terminate=True) # Add a new volume based on a snapshot lc.add_volume_device(size=1, source=test_snap, delete_on_terminate=True) # Override root volume size image_id = helpers.get_provider_test_data( self.provider, "image") img = self.provider.compute.images.get(image_id) # The size should be greater then the ami size # and therefore, img.min_disk is used. lc.add_volume_device( is_root=True, source=img, size=img.min_disk if img and img.min_disk else 30, delete_on_terminate=True) # Add all available ephemeral devices vm_type_name = helpers.get_provider_test_data( self.provider, "vm_type") vm_type = self.provider.compute.vm_types.find( name=vm_type_name)[0] # Some providers, e.g. GCP, has a limit on total number of # attached disks; it does not matter how many of them are # ephemeral or persistent. So, wee keep in mind that we have # attached 4 disks already, and add ephemeral disks accordingly # to not exceed the limit. for _ in range(vm_type.num_ephemeral_disks - 4): lc.add_ephemeral_device() subnet = helpers.get_or_create_default_subnet( self.provider) inst = None with cb_helpers.cleanup_action( lambda: helpers.delete_instance(inst)): inst = helpers.create_test_instance( self.provider, label, subnet=subnet, launch_config=lc) try: inst.wait_till_ready() except WaitStateException as e: self.fail("The block device mapped launch did not " " complete successfully: %s" % e)
def test_create_and_list_image(self): instance_label = "cb-crudimage-{0}".format(helpers.get_uuid()) img_inst_label = "cb-crudimage-{0}".format(helpers.get_uuid()) # Declare these variables and late binding will allow # the cleanup method access to the most current values test_instance = None subnet = None def create_img(label): return test_instance.create_image(label=label) def cleanup_img(img): if img: img.delete() img.wait_for( [MachineImageState.UNKNOWN, MachineImageState.ERROR]) img.refresh() self.assertTrue( img.state == MachineImageState.UNKNOWN, "MachineImage.state must be unknown when refreshing after " "a delete but got %s" % img.state) def extra_tests(img): # check image size img.refresh() self.assertGreater( img.min_disk, 0, "Minimum disk" " size required by image is invalid") create_instance_from_image(img) def create_instance_from_image(img): img_instance = None with cb_helpers.cleanup_action( lambda: helpers.cleanup_test_resources(img_instance)): img_instance = self.provider.compute.instances.create( img_inst_label, img, helpers.get_provider_test_data(self.provider, 'vm_type'), subnet=subnet) img_instance.wait_till_ready() self.assertIsInstance(img_instance, Instance) self.assertEqual( img_instance.label, img_inst_label, "Instance label {0} is not equal to the expected label" " {1}".format(img_instance.label, img_inst_label)) image_id = img.id self.assertEqual( img_instance.image_id, image_id, "Image id {0} is not equal to the expected id" " {1}".format(img_instance.image_id, image_id)) self.assertIsInstance(img_instance.public_ips, list) if img_instance.public_ips: self.assertTrue( img_instance.public_ips[0], "public ip should contain a" " valid value if a list of public_ips exist") self.assertIsInstance(img_instance.private_ips, list) self.assertTrue(img_instance.private_ips[0], "private ip should" " contain a valid value") with cb_helpers.cleanup_action( lambda: helpers.cleanup_test_resources(test_instance)): subnet = helpers.get_or_create_default_subnet(self.provider) test_instance = helpers.get_test_instance(self.provider, instance_label, subnet=subnet) sit.check_crud(self, self.provider.compute.images, MachineImage, "cb-listimg", create_img, cleanup_img, extra_test_func=extra_tests)
def test_crud_router(self): def _cleanup(net, subnet, router, gateway): with cb_helpers.cleanup_action( lambda: helpers.cleanup_network(net)): with cb_helpers.cleanup_action( lambda: helpers.cleanup_subnet(subnet)): with cb_helpers.cleanup_action( lambda: router.delete()): with cb_helpers.cleanup_action( lambda: helpers.cleanup_gateway(gateway)): router.detach_subnet(subnet) router.detach_gateway(gateway) label = 'cb-crudrouter-{0}'.format(helpers.get_uuid()) # Declare these variables and late binding will allow # the cleanup method access to the most current values net = None sn = None router = None gteway = None with cb_helpers.cleanup_action( lambda: _cleanup(net, sn, router, gteway)): net = self.provider.networking.networks.create( label=label, cidr_block=BaseNetwork.CB_DEFAULT_IPV4RANGE) router = self.provider.networking.routers.create(label=label, network=net) cidr = '10.0.15.0/24' sn = net.subnets.create(label=label, cidr_block=cidr) # Check basic router properties sit.check_standard_behaviour( self, self.provider.networking.routers, router) if (self.provider.PROVIDER_ID != 'gcp'): self.assertEqual( router.state, RouterState.DETACHED, "Router {0} state {1} should be {2}.".format( router.id, router.state, RouterState.DETACHED)) # self.assertEqual( # router.network_id, net.id, "Router {0} should be assoc." # " with network {1}, but is associated with {2}" # .format(router.id, net.id, router.network_id)) self.assertTrue( len(router.subnets) == 0, "No subnet should be attached to router {1}".format( sn, router) ) router.attach_subnet(sn) self.assertTrue( len(router.subnets) == 1, "Subnet {0} not attached to router {1}".format(sn, router) ) gteway = net.gateways.get_or_create() router.attach_gateway(gteway) # TODO: add a check for routes after that's been implemented sit.check_delete(self, self.provider.networking.routers, router) # Also make sure that linked resources were properly cleaned up sit.check_delete(self, self.provider.networking.subnets, sn) sit.check_delete(self, self.provider.networking.networks, net)
def check_crud(test, service, iface, label_prefix, create_func, cleanup_func, extra_test_func=None, custom_check_delete=None, skip_name_check=False): """ Checks crud behaviour of a given cloudbridge service. The create_func will be used as a factory function to create a service object and the cleanup_func will be used to destroy the object. Once an object is created using the create_func, all other standard behavioural tests can be run against that object. :type test: ``TestCase`` :param test: The TestCase object to use :type service: ``CloudService`` :param service: The CloudService object under test. For example, a VolumeService object. :type iface: ``type`` :param iface: The type to test behaviour against. This type must be a subclass of ``CloudResource``. :type label_prefix: ``str`` :param label_prefix: The label to prefix all created objects with. This function will generated a new label with the specified label_prefix for each test object created and pass that label into the create_func :type create_func: ``func`` :param create_func: The create_func must accept the label of the object to create as a parameter and return the constructed object. :type cleanup_func: ``func`` :param cleanup_func: The cleanup_func must accept the created object and perform all cleanup tasks required to delete the object. :type extra_test_func: ``func`` :param extra_test_func: This function will be called to perform additional tests after object construction and initialization, but before object cleanup. It will receive the created object as a parameter. :type custom_check_delete: ``func`` :param custom_check_delete: If provided, this function will be called instead of the standard check_delete function to make sure that the object has been deleted. :type skip_name_check: ``boolean`` :param skip_name_check: If True, the name related checking will be skipped. """ obj = None with cb_helpers.cleanup_action(lambda: cleanup_func(obj)): label = "{0}-{1}".format(label_prefix, helpers.get_uuid()) if not skip_name_check: check_create(test, service, iface, label_prefix, create_func, cleanup_func) obj = create_func(label) if issubclass(iface, ObjectLifeCycleMixin): obj.wait_till_ready() check_standard_behaviour(test, service, obj) if extra_test_func: extra_test_func(obj) if custom_check_delete: custom_check_delete(obj) else: check_delete(test, service, obj)
def cleanup_gateway(gateway): """ Delete the supplied network and gateway. """ with cb_helpers.cleanup_action(lambda: gateway.delete()): pass