[Kimchi-devel] [PATCH v4 4/6] CDROM Management: Guest vm storage devices mockmodel and rest api test cases
Daniel H Barboza
danielhb at linux.vnet.ibm.com
Fri Feb 14 00:35:04 UTC 2014
On 02/13/2014 10:23 PM, Daniel H Barboza wrote:
>
> On 02/13/2014 10:19 PM, Aline Manera wrote:
>> On 02/13/2014 04:47 PM, Daniel Barboza wrote:
>>> From: Rodrigo Trujillo <rodrigo.trujillo at linux.vnet.ibm.com>
>>>
>>> This patch implements the mockmodel class to simulate lookup, add,
>>> remove, update of devices in a guest vm. Also, it adds test cases to
>>> test the rest API.
>>>
>>> Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo at linux.vnet.ibm.com>
>>>
>>> Minor changes/improvements based on ML feedback
>>> Removing hard disk tests from tests/tests_rest.py
>>>
>>> Signed-off-by: Daniel Henrique Barboza <danielhb at linux.vnet.ibm.com>
>>> ---
>>> src/kimchi/mockmodel.py | 66
>>> +++++++++++++++++++++++++++++++++++++++++++++++++
>>> tests/test_rest.py | 56
>>> +++++++++++++++++++++++++++++++++++++++++
>>> 2 files changed, 122 insertions(+)
>>>
>>> diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py
>>> index be0ae4b..934f66a 100644
>>> --- a/src/kimchi/mockmodel.py
>>> +++ b/src/kimchi/mockmodel.py
>>> @@ -539,6 +539,51 @@ class MockModel(object):
>>> def networks_get_list(self):
>>> return sorted(self._mock_networks.keys())
>>>
>>> + def storages_create(self, vm_name, params):
>>> + path = params.get('path')
>>> + if path.startswith('/') and not os.path.exists(path):
>>> + msg = "Path specified for device is not valid"
>>> + raise InvalidParameter(msg)
>>> +
>>
>> You need to change the error message to the refactor expection method
> Yeah I forgot to check out mockmodel.py exceptions
>
> I'll fix it in v5.
>
Actually I did this but it was on a different patch ... the one you said
to "join it". I didn't notice that patch 4 and 5 changed the same file.
Anyway, v5 will fix it :)
>>
>>> + dom = self._get_vm(vm_name)
>>> + dev = params.get('dev', None)
>>> + if dev and dev in self.storages_get_list(vm_name):
>>> + return OperationFailed('Device name already in use.')
>>> + if not dev:
>>> + return OperationFailed('Must specify a device name.')
>>
>> Same here and all cases you raise an exception
>>
>>> + vmdev = MockVMStorageDevice(params)
>>> + dom.storagedevices[params['dev']] = vmdev
>>> + return params['dev']
>>> +
>>> + def storages_get_list(self, vm_name):
>>> + dom = self._get_vm(vm_name)
>>> + return dom.storagedevices.keys()
>>> +
>>> + def storage_lookup(self, vm_name, dev_name):
>>> + dom = self._get_vm(vm_name)
>>> + if dev_name not in self.storages_get_list(vm_name):
>>> + msg = 'The storage device "%s" does not exist in the
>>> guest "%s"' \
>>> + % (dev_name,vm_name)
>>> + raise NotFoundError(msg)
>>
>> ^
>>
>>> + return dom.storagedevices.get('dev_name').info
>>> +
>>> + def storage_delete(self, vm_name, dev_name):
>>> + dom = self._get_vm(vm_name)
>>> + if dev_name not in self.storages_get_list(vm_name):
>>> + msg = 'The storage device "%s" does not exist in the
>>> guest "%s"' \
>>> + % (dev_name,vm_name)
>>> + raise NotFoundError(msg)
>>
>> ^
>>
>>> + dom.storagedevices.pop(dev_name)
>>> +
>>> + def storage_update(self, vm_name, dev_name, params):
>>> + try:
>>> + dom = self._get_vm(vm_name)
>>> + dom.storagedevices[dev_name].info.update(params)
>>> + except Exception as e:
>>> + msg = 'Was not possible to update storage device: %s' %
>>> e.message
>>> + raise OperationFailed(e.message)
>>
>> ^
>>
>>> + return dev_name
>>> +
>>> def vmifaces_create(self, vm, params):
>>> if (params["type"] == "network" and
>>> params["network"] not in self.networks_get_list()):
>>> @@ -721,6 +766,24 @@ class MockVMTemplate(VMTemplate):
>>> return disk_paths
>>>
>>>
>>> +class MockVMStorageDevice(object):
>>> + def __init__(self, params):
>>> + # Defaults
>>> + if params['dev'] == 'hda':
>>> + self.info = {'dev': params.get('dev'),
>>> + 'type': 'disk',
>>> + 'path': '/tmp/myimage.img'}
>>> + elif params['dev'] == 'hdc':
>>> + self.info = {'dev': params.get('dev'),
>>> + 'type': 'cdrom',
>>> + 'path': ''}
>>> + # New devices
>>> + else:
>>> + self.info = {'dev': params.get('dev'),
>>> + 'type': params.get('type'),
>>> + 'path': params.get('path')}
>>> +
>>> +
>>> class MockVMIface(object):
>>> counter = 0
>>>
>>> @@ -746,6 +809,9 @@ class MockVM(object):
>>> self.disk_paths = []
>>> self.networks = template_info['networks']
>>> ifaces = [MockVMIface(net) for net in self.networks]
>>> + default_devices = [{'dev':'hda'}, {'dev':'hdc'}]
>>> + self.storagedevices = dict([(dev['dev'],
>>> MockVMStorageDevice(dev)) \
>>> + for dev in default_devices])
>>> self.ifaces = dict([(iface.info['mac'], iface) for iface
>>> in ifaces])
>>> self.info = {'state': 'shutoff',
>>> 'stats': "{'cpu_utilization': 20,
>>> 'net_throughput' : 35, \
>>> diff --git a/tests/test_rest.py b/tests/test_rest.py
>>> index b72ff0b..62973fa 100644
>>> --- a/tests/test_rest.py
>>> +++ b/tests/test_rest.py
>>> @@ -341,6 +341,62 @@ class RestTests(unittest.TestCase):
>>> resp = self.request('/templates/test', '{}', 'DELETE')
>>> self.assertEquals(204, resp.status)
>>>
>>> + def test_vm_storage_devices(self):
>>> +
>>> + with RollbackContext() as rollback:
>>> + # Create a template as a base for our VMs
>>> + req = json.dumps({'name': 'test', 'cdrom':
>>> '/nonexistent.iso'})
>>> + resp = self.request('/templates', req, 'POST')
>>> + self.assertEquals(201, resp.status)
>>> + # Delete the template
>>> + rollback.prependDefer(self.request,
>>> + '/templates/test', '{}', 'DELETE')
>>> +
>>> + # Create a VM with default args
>>> + req = json.dumps({'name': 'test-vm',
>>> + 'template': '/templates/test'})
>>> + resp = self.request('/vms', req, 'POST')
>>> + self.assertEquals(201, resp.status)
>>> + # Delete the VM
>>> + rollback.prependDefer(self.request,
>>> + '/vms/test-vm', '{}', 'DELETE')
>>> +
>>> + # Attach cdrom with nonexistent iso
>>> + req = json.dumps({'dev': 'hdx',
>>> + 'type': 'cdrom',
>>> + 'path': '/tmp/nonexistent.iso'})
>>> + resp = self.request('/vms/test-vm/storages', req, 'POST')
>>> + self.assertEquals(400, resp.status)
>>> +
>>> + # Attach a cdrom with existent dev name
>>> + open('/tmp/existent.iso', 'w').close()
>>> + req = json.dumps({'dev': 'hdx',
>>> + 'type': 'cdrom',
>>> + 'path': '/tmp/existent.iso'})
>>> + resp = self.request('/vms/test-vm/storages', req, 'POST')
>>> + self.assertEquals(201, resp.status)
>>> + # Delete the file and cdrom
>>> + rollback.prependDefer(self.request,
>>> + '/vms/test-vm/storages/hdx', '{}', 'DELETE')
>>> + os.remove('/tmp/existent.iso')
>>> +
>>> + # Change path of storage cdrom
>>> + req = json.dumps({'path':
>>> 'http://myserver.com/myiso.iso'})
>>> + resp = self.request('/vms/test-vm/storages/hdx', req,
>>> 'PUT')
>>> + self.assertEquals(200, resp.status)
>>> +
>>> + # Test GET
>>> + devs =
>>> json.loads(self.request('/vms/test-vm/storages').read())
>>> + self.assertEquals(3, len(devs))
>>> +
>>> + # Detach storage cdrom
>>> + resp = self.request('/vms/test-vm/storages/hdx', '{}',
>>> 'DELETE')
>>> + self.assertEquals(204, resp.status)
>>> +
>>> + # Test GET
>>> + devs =
>>> json.loads(self.request('/vms/test-vm/storages').read())
>>> + self.assertEquals(2, len(devs))
>>> +
>>> def test_vm_iface(self):
>>>
>>> with RollbackContext() as rollback:
>>
>
> _______________________________________________
> Kimchi-devel mailing list
> Kimchi-devel at ovirt.org
> http://lists.ovirt.org/mailman/listinfo/kimchi-devel
>
More information about the Kimchi-devel
mailing list