def test_delete_deletes_bcache(self): self.become_admin() node = factory.make_Node(status=NODE_STATUS.READY) bcache = factory.make_FilesystemGroup( node=node, group_type=FILESYSTEM_GROUP_TYPE.BCACHE) uri = get_bcache_device_uri(bcache) response = self.client.delete(uri) self.assertEqual(http.client.NO_CONTENT, response.status_code, response.content) self.assertIsNone(reload_object(bcache))
def test_add_valid_spare_device(self): raid = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.RAID_6 ) # Add 5 new blockdevices to the node. bd_ids = [ factory.make_BlockDevice(node=raid.get_node()).id for _ in range(5) ] form = UpdateRaidForm(raid, data={"add_spare_devices": bd_ids}) self.assertTrue(form.is_valid(), form.errors)
def test_add_valid_partition(self): raid = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.RAID_6 ) # Add 5 new partitions to the node. part_ids = [ factory.make_Partition(node=raid.get_node()).id for _ in range(5) ] form = UpdateRaidForm(raid, data={"add_partitions": part_ids}) self.assertTrue(form.is_valid(), form.errors)
def test_add_invalid_spare_partition_fails(self): raid = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.RAID_6) # Add 5 new partitions to other nodes. part_ids = [factory.make_Partition().id for _ in range(5)] form = UpdateRaidForm(raid, data={'add_spare_partitions': part_ids}) self.assertFalse(form.is_valid(), form.errors) self.assertIn('add_spare_partitions', form.errors) self.assertIn('is not one of the available choices.', form.errors['add_spare_partitions'][0])
def test_DELETE_404_when_not_vmfs(self): self.become_admin() node = factory.make_Machine(status=NODE_STATUS.READY) not_vmfs = factory.make_FilesystemGroup( node=node, group_type=factory.pick_enum(FILESYSTEM_GROUP_TYPE, but_not=FILESYSTEM_GROUP_TYPE.VMFS6), ) response = self.client.delete(self.get_vmfs_uri(not_vmfs)) self.assertThat(response, HasStatusCode(http.client.NOT_FOUND))
def test_delete_logical_volume_404_when_not_volume_group(self): self.become_admin() node = factory.make_Node(status=NODE_STATUS.READY) not_volume_group = factory.make_FilesystemGroup( node=node, group_type=factory.pick_enum(FILESYSTEM_GROUP_TYPE, but_not=FILESYSTEM_GROUP_TYPE.LVM_VG)) uri = get_volume_group_uri(not_volume_group) response = self.client.post(uri, {"op": "delete_logical_volume"}) self.assertEqual(http.client.NOT_FOUND, response.status_code, response.content)
def test_user_can_lock_owned_FilesystemGroup_node_rbac(self): self.enable_rbac() user = factory.make_User() node = factory.make_Node(owner=user) filesystem_group = factory.make_FilesystemGroup(node=node) backend = MAASAuthorizationBackend() self.rbac_store.add_pool(node.pool) self.rbac_store.allow(user.username, node.pool, 'view') self.rbac_store.allow(user.username, node.pool, 'deploy-machines') self.assertTrue( backend.has_perm(user, NodePermission.lock, filesystem_group))
def test_create_or_update_for_bcache_creates_block_device(self): # This will create the filesystem group and a virtual block device. filesystem_group = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.BCACHE) self.assertThat( filesystem_group.virtual_device, MatchesStructure.byEquality( name=filesystem_group.name, size=filesystem_group.get_size(), block_size=( filesystem_group.get_virtual_block_device_block_size())))
def test_read_404_when_not_bcache(self): not_bcache = factory.make_FilesystemGroup( group_type=factory.pick_enum( FILESYSTEM_GROUP_TYPE, but_not=FILESYSTEM_GROUP_TYPE.BCACHE ) ) uri = get_bcache_device_uri(not_bcache) response = self.client.get(uri) self.assertEqual( http.client.NOT_FOUND, response.status_code, response.content )
def test_add_invalid_spare_device_fails(self): self.become_admin() node = factory.make_Node(status=NODE_STATUS.READY) raid = factory.make_FilesystemGroup( node=node, group_type=FILESYSTEM_GROUP_TYPE.RAID_6) device = factory.make_PhysicalBlockDevice() # From another node. uri = get_raid_device_uri(raid, node) response = self.client.put(uri, {'add_spare_devices': [device.id]}) self.assertEqual(http.client.BAD_REQUEST, response.status_code, response.content) self.assertIsNone(device.get_effective_filesystem())
def test_remove_invalid_partition_fails(self): self.become_admin() node = factory.make_Node(status=NODE_STATUS.READY) raid = factory.make_FilesystemGroup( node=node, group_type=FILESYSTEM_GROUP_TYPE.RAID_6) partition = factory.make_PartitionTable( block_device=factory.make_PhysicalBlockDevice()).add_partition() uri = get_raid_device_uri(raid, node) response = self.client.put(uri, {'remove_partitions': [partition.id]}) self.assertEqual(http.client.BAD_REQUEST, response.status_code, response.content)
def test_delete_404_when_not_bcache(self): self.become_admin() node = factory.make_Node(status=NODE_STATUS.READY) not_bcache = factory.make_FilesystemGroup( node=node, group_type=factory.pick_enum(FILESYSTEM_GROUP_TYPE, but_not=FILESYSTEM_GROUP_TYPE.BCACHE)) uri = get_bcache_device_uri(not_bcache) response = self.client.delete(uri) self.assertEqual(http.client.NOT_FOUND, response.status_code, response.content)
def test_updates_filesystem_group_name_when_not_volume_group(self): filesystem_group = factory.make_FilesystemGroup( group_type=factory.pick_enum( FILESYSTEM_GROUP_TYPE, but_not=FILESYSTEM_GROUP_TYPE.LVM_VG ) ) virtual_device = filesystem_group.virtual_device newname = factory.make_name("name") virtual_device.name = newname virtual_device.save() self.assertEqual(newname, reload_object(filesystem_group).name)
def test_raid_active(self): filesystem_group = factory.make_FilesystemGroup( group_type=factory.pick_choice(FILESYSTEM_GROUP_RAID_TYPE_CHOICES) ) self.assertEqual( ( "Active %s device for %s" % (filesystem_group.group_type, filesystem_group.name) ), used_for(filesystem_group.filesystems.first().block_device), )
def test_read_404_when_not_volume_group(self): not_volume_group = factory.make_FilesystemGroup( group_type=factory.pick_enum( FILESYSTEM_GROUP_TYPE, but_not=FILESYSTEM_GROUP_TYPE.LVM_VG ) ) uri = get_volume_group_uri(not_volume_group) response = self.client.get(uri) self.assertEqual( http.client.NOT_FOUND, response.status_code, response.content )
def test__raid_spare(self): filesystem_group = factory.make_FilesystemGroup( group_type=factory.pick_choice(FILESYSTEM_GROUP_RAID_TYPE_CHOICES)) slave_block_device = factory.make_PhysicalBlockDevice() factory.make_Filesystem(block_device=slave_block_device, fstype=FILESYSTEM_TYPE.RAID_SPARE, filesystem_group=filesystem_group) self.assertEqual( ("Spare %s device for %s" % (filesystem_group.group_type, filesystem_group.name)), used_for(slave_block_device))
def test_delete_409_when_not_ready(self): self.become_admin() node = factory.make_Node(status=NODE_STATUS.ALLOCATED) bcache = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.BCACHE, node=node ) uri = get_bcache_device_uri(bcache) response = self.client.delete(uri) self.assertEqual( http.client.CONFLICT, response.status_code, response.content )
def test_create_or_update_for_lvm_does_nothing(self): # This will create the filesystem group but not a virtual block # device since its a volume group. filesystem_group = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.LVM_VG ) self.assertItemsEqual( [], VirtualBlockDevice.objects.filter( filesystem_group=filesystem_group ), )
def test_is_not_valid_if_substrate_in_filesystem_group(self): substrate = self.make_substrate() filesystem = factory.make_Filesystem(fstype=FILESYSTEM_TYPE.LVM_PV, **substrate) factory.make_FilesystemGroup(group_type=FILESYSTEM_GROUP_TYPE.LVM_VG, filesystems=[filesystem]) data = {"mount_point": factory.make_absolute_path()} form = MountFilesystemForm(filesystem, data=data) self.assertFalse( form.is_valid(), "Should be invalid because block device is in a filesystem group.", ) self.assertEqual( { "__all__": [ "Filesystem is part of a filesystem group, and cannot be " "mounted." ] }, form._errors, )
def test_rename_raid(self): self.become_admin() node = factory.make_Node(status=NODE_STATUS.READY) raid = factory.make_FilesystemGroup( node=node, group_type=FILESYSTEM_GROUP_TYPE.RAID_5) uri = get_raid_device_uri(raid, node) response = self.client.put(uri, {'name': 'raid0'}) self.assertEqual(http.client.OK, response.status_code, response.content) parsed_device = json.loads( response.content.decode(settings.DEFAULT_CHARSET)) self.assertEqual('raid0', parsed_device['name'])
def test_add_invalid_spare_blockdevice_fails(self): raid = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.RAID_6) # Add 5 new blockdevices to other nodes. bd_ids = [factory.make_BlockDevice().id for _ in range(5)] form = UpdateRaidForm(raid, data={"add_spare_devices": bd_ids}) self.assertFalse(form.is_valid(), form.errors) self.assertIn("add_spare_devices", form.errors) self.assertIn( "is not one of the available choices.", form.errors["add_spare_devices"][0], )
def test_clean_no_partition_table_on_bcache(self): node = factory.make_Node() bcache_group = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.BCACHE, node=node) bcache_device = bcache_group.virtual_device error = self.assertRaises(ValidationError, factory.make_PartitionTable, block_device=bcache_device) self.assertEqual( { "block_device": ["Cannot create a partition table on a Bcache volume."], }, error.message_dict)
def test_add_valid_spare_boot_disk(self): node = factory.make_Node(with_boot_disk=False) boot_disk = factory.make_PhysicalBlockDevice(node=node) raid = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.RAID_6, node=node) raid = RAID.objects.get(id=raid.id) form = UpdateRaidForm(raid, data={'add_spare_devices': [boot_disk.id]}) self.assertTrue(form.is_valid(), form.errors) raid = form.save() boot_partition = boot_disk.get_partitiontable().partitions.first() self.assertEqual( boot_partition.get_effective_filesystem().filesystem_group.id, raid.id)
def test_read(self): node = factory.make_Node() bcaches = [ factory.make_FilesystemGroup( node=node, group_type=FILESYSTEM_GROUP_TYPE.BCACHE) for _ in range(3) ] # Not bcache. Should not be in the output. for _ in range(3): factory.make_FilesystemGroup( node=node, group_type=factory.pick_enum( FILESYSTEM_GROUP_TYPE, but_not=FILESYSTEM_GROUP_TYPE.BCACHE)) uri = get_bcache_devices_uri(node) response = self.client.get(uri) self.assertEqual(http.client.OK, response.status_code, response.content) expected_ids = [bcache.id for bcache in bcaches] result_ids = [ bcache["id"] for bcache in json_load_bytes(response.content) ] self.assertItemsEqual(expected_ids, result_ids)
def test_choices_are_being_populated_correctly(self): node = factory.make_Node(with_boot_disk=False) device_size = 1 * 1000**4 # Make 10 block devices. bds = [ factory.make_PhysicalBlockDevice(node=node, size=device_size) for _ in range(10) ] # Make 3 cache sets. cache_sets = [factory.make_CacheSet(node=node) for _ in range(3)] cache_set_choices = [cache_set.id for cache_set in cache_sets ] + [cache_set.name for cache_set in cache_sets] # Partition the last 5 devices with a single partition. partitions = [ factory.make_PartitionTable(block_device=bd).add_partition() for bd in bds[5:] ] partition_choices = [p.id for p in partitions ] + [p.name for p in partitions] # Get the chocies of the non-partitioned devices. block_device_choices = [ bd.id for bd in bds if bd.get_partitiontable() is None ] + [bd.name for bd in bds if bd.get_partitiontable() is None] # Use one of the cache sets and one of the backing devices. filesystems = [ factory.make_Filesystem(partition=partitions[0], fstype=FILESYSTEM_TYPE.BCACHE_BACKING) ] bcache = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.BCACHE, cache_set=cache_sets[0], filesystems=filesystems, ) form = UpdateBcacheForm(bcache=bcache, data={}) # Should allow all devices and partitions, including the ones currently # allocated for bcache. self.assertItemsEqual( cache_set_choices, [k for (k, v) in form.fields["cache_set"].choices], ) self.assertItemsEqual( block_device_choices, [k for (k, v) in form.fields["backing_device"].choices], ) self.assertItemsEqual( partition_choices, [k for (k, v) in form.fields["backing_partition"].choices], )
def test_read(self): node = factory.make_Node() cache_set = factory.make_CacheSet(node=node) backing_block_device = factory.make_PhysicalBlockDevice(node=node) backing_filesystem = factory.make_Filesystem( fstype=FILESYSTEM_TYPE.BCACHE_BACKING, block_device=backing_block_device, ) bcache = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.BCACHE, cache_set=cache_set, filesystems=[backing_filesystem], ) uri = get_bcache_device_uri(bcache) response = self.client.get(uri) self.assertEqual( http.client.OK, response.status_code, response.content ) parsed_bcache = json_load_bytes(response.content) self.assertThat( parsed_bcache, ContainsDict( { "id": Equals(bcache.id), "uuid": Equals(bcache.uuid), "name": Equals(bcache.name), "size": Equals(bcache.get_size()), "human_size": Equals( human_readable_bytes(bcache.get_size()) ), "resource_uri": Equals(get_bcache_device_uri(bcache)), "virtual_device": ContainsDict( {"id": Equals(bcache.virtual_device.id)} ), "cache_set": ContainsDict( { "id": Equals(cache_set.id), "name": Equals(cache_set.name), } ), "backing_device": ContainsDict( {"id": Equals(backing_block_device.id)} ), "system_id": Equals(bcache.get_node().system_id), } ), )
def test_get_partitions_in_filesystem_group(self): node = factory.make_Node() filesystem_group = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.LVM_VG) block_device_with_partitions = factory.make_PhysicalBlockDevice( node=node) partition_table = factory.make_PartitionTable( block_device=block_device_with_partitions) partition = factory.make_Partition(partition_table=partition_table) factory.make_Filesystem(fstype=FILESYSTEM_TYPE.LVM_PV, partition=partition, filesystem_group=filesystem_group) partitions_in_filesystem_group = ( Partition.objects.get_partitions_in_filesystem_group( filesystem_group)) self.assertItemsEqual([partition], partitions_in_filesystem_group)
def test_update_403_if_not_admin(self): node = factory.make_Node(status=NODE_STATUS.READY) bcache = factory.make_FilesystemGroup( node=node, group_type=FILESYSTEM_GROUP_TYPE.BCACHE, cache_mode=CACHE_MODE_TYPE.WRITEBACK) uri = get_bcache_device_uri(bcache) uuid = str(uuid4()) response = self.client.put( uri, { 'name': 'new_name', 'uuid': uuid, 'cache_mode': CACHE_MODE_TYPE.WRITEAROUND, }) self.assertEqual(http.client.FORBIDDEN, response.status_code, response.content)
def test_cannot_save_if_size_larger_than_volume_group(self): filesystem_group = factory.make_FilesystemGroup( group_type=FILESYSTEM_GROUP_TYPE.LVM_VG) factory.make_VirtualBlockDevice(filesystem_group=filesystem_group, size=filesystem_group.get_size() / 2) new_block_device_size = filesystem_group.get_size() human_readable_size = human_readable_bytes(new_block_device_size) with ExpectedException( ValidationError, re.escape("{'__all__': ['There is not enough free space (%s) " "on volume group %s.']}" % ( human_readable_size, filesystem_group.name, ))): factory.make_VirtualBlockDevice(filesystem_group=filesystem_group, size=new_block_device_size)
def test_update_bcache(self): """Tests update bcache method by changing the name, UUID and cache mode of a bcache.""" mock_create_audit_event = self.patch( bcache_module, "create_audit_event" ) self.become_admin() node = factory.make_Node(status=NODE_STATUS.READY) bcache = factory.make_FilesystemGroup( node=node, group_type=FILESYSTEM_GROUP_TYPE.BCACHE, cache_mode=CACHE_MODE_TYPE.WRITEBACK, ) uri = get_bcache_device_uri(bcache) uuid = str(uuid4()) filesystem_ids = [fs.id for fs in bcache.filesystems.all()] response = self.client.put( uri, { "name": "new_name", "uuid": uuid, "cache_mode": CACHE_MODE_TYPE.WRITEAROUND, }, ) self.assertEqual( http.client.OK, response.status_code, response.content ) parsed_device = json_load_bytes(response.content) self.assertEqual("new_name", parsed_device["name"]) self.assertEqual(uuid, parsed_device["uuid"]) self.assertEqual( CACHE_MODE_TYPE.WRITEAROUND, parsed_device["cache_mode"] ) # Ensure the filesystems were not changed. self.assertListEqual( filesystem_ids, [fs.id for fs in bcache.filesystems.all()] ) self.assertThat( mock_create_audit_event, MockCalledOnceWith( EVENT_TYPES.NODE, ENDPOINT.API, ANY, node.system_id, "Updated bcache.", ), )