[Kimchi-devel] [PATCH V4 5/5] Storagepool SCSI/FC: Modifies mockmodel and implements tests for FC pool
Aline Manera
alinefm at linux.vnet.ibm.com
Mon Feb 10 14:32:37 UTC 2014
On 02/05/2014 12:18 PM, Rodrigo Trujillo wrote:
> This patch modifies the Mock model functions to allow user to create a
> SCSI FC pool in test environment. Then implements functions to test
> API and rest.
>
> Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo at linux.vnet.ibm.com>
> ---
> src/kimchi/mockmodel.py | 53 +++++++++++++++++++++++++++++++++++++++++------
> tests/test_rest.py | 47 +++++++++++++++++++++++++++++++++++++++++
> tests/test_storagepool.py | 21 +++++++++++++++++++
> 3 files changed, 115 insertions(+), 6 deletions(-)
>
> diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py
> index 4e276eb..f6400a4 100644
> --- a/src/kimchi/mockmodel.py
> +++ b/src/kimchi/mockmodel.py
> @@ -66,7 +66,8 @@ class MockModel(object):
> return {'libvirt_stream_protocols': ['http', 'https', 'ftp', 'ftps', 'tftp'],
> 'qemu_stream': True,
> 'screenshot': True,
> - 'system_report_tool': True}
> + 'system_report_tool': True,
> + 'fc_host_support': True}
As I said before you don't need to expose it as it is a backend information
> def reset(self):
> self._mock_vms = {}
> @@ -155,7 +156,15 @@ class MockModel(object):
> if icon:
> vm.info['icon'] = icon
>
> - vm.disk_paths = t.fork_vm_storage(vm_uuid)
> + pool = t._storage_validate()
> + if pool.info['type'] == 'scsi':
> + vm.disk_paths = []
> + if not params.get('volumes'):
> + raise InvalidOperation("Volume list (LUNs names) not given.")
It would be MissingParameter() error
> + for vol in params['volumes']:
> + vm.disk_paths.append(pool._volumes[vol].info['path'])
> + else:
> + vm.disk_paths = t.fork_vm_storage(vm_uuid)
> self._mock_vms[name] = vm
> return name
>
> @@ -298,8 +307,18 @@ class MockModel(object):
> name = params['name']
> pool = MockStoragePool(name)
> pool.info['type'] = params['type']
> - pool.info['path'] = params['path']
> - if params['type'] == 'dir':
> + if params['type'] == 'scsi':
> + pool.info['path'] = '/dev/disk/by-path'
> + pool.info['source'] = params['source']
> + if not pool.info['source'].get('adapter_name'):
> + raise KeyError('adapter_name')
raise MissingParameter()
> + for vol in ['unit:0:0:1','unit:0:0:2',
> + 'unit:0:0:3','unit:0:0:4']:
> + mockvol = MockStorageVolume(vol, name, self._def_lun(vol))
> + pool._volumes[vol] = mockvol
> + else:
> + pool.info['path'] = params['path']
> + if params['type'] in ['dir','scsi']:
> pool.info['autostart'] = True
> else:
> pool.info['autostart'] = False
> @@ -388,6 +407,27 @@ class MockModel(object):
> "Unable to list volumes of inactive storagepool %s" % pool)
> return res._volumes.keys()
> + def _def_lun(self, name):
> + capacity = int(random.uniform(100, 300)) << 20
> + path = "/dev/disk/by-path/pci-0000:0e:00.0-fc-0x20999980e52e4492-lun"
> + return {
> + "capacity": capacity,
> + "name": name,
> + "format": random.choice(['dos','unknown']),
> + "allocation": capacity,
> + "path": path + name[-1],
> + "type": "block" }
This function should be in MockStorageVolume() class
and while creating a new volume MockStorageVolume() it knows what to do
> +
> + def devices_get_list(self, _cap=None):
> + return ['scsi_host3', 'scsi_host4','scsi_host5']
> +
> + def device_lookup(self, nodedev_name):
> + return {
> + 'name': nodedev_name,
> + 'adapter_type': 'fc_host',
> + 'wwnn': uuid.uuid4().hex[:16],
> + 'wwpn': uuid.uuid4().hex[:16]}
> +
> def isopool_lookup(self, name):
> return {'state': 'active',
> 'type': 'kimchi-iso'}
> @@ -789,9 +829,10 @@ class MockStorageVolume(object):
> self.pool = pool
> fmt = params.get('format', 'raw')
> capacity = params.get('capacity', 1024)
> - self.info = {'type': 'disk',
> + self.info = {'type': params.get('type','disk'),
> 'capacity': capacity << 20,
> - 'allocation': 512,
> + 'allocation': params.get('allocation','512'),
> + 'path': params.get('path'),
> 'format': fmt}
> if fmt == 'iso':
> self.info['allocation'] = self.info['capacity']
> diff --git a/tests/test_rest.py b/tests/test_rest.py
> index 0ed293b..8b033ae 100644
> --- a/tests/test_rest.py
> +++ b/tests/test_rest.py
> @@ -23,6 +23,7 @@
> import base64
> import json
> import os
> +import random
> import time
> import unittest
>
> @@ -144,6 +145,18 @@ class RestTests(unittest.TestCase):
> h = {'Accept': 'text/plain'}
> self.assertHTTPStatus(406, "/", None, 'GET', h)
>
> + def test_host_devices(self):
> + nodedevs = json.loads(self.request('/host/devices').read())
> + # Mockmodel brings 3 preconfigured scsi fc_host
> + self.assertEquals(3, len(nodedevs))
> +
> + nodedev = json.loads(self.request('/host/devices/scsi_host4').read())
> + # Mockmodel generates random wwpn and wwnn
> + self.assertEquals('scsi_host4', nodedev['name'])
> + self.assertEquals('fc_host', nodedev['adapter_type'])
> + self.assertEquals(16, len(nodedev['wwpn']))
> + self.assertEquals(16, len(nodedev['wwnn']))
> +
> def test_get_vms(self):
> vms = json.loads(self.request('/vms').read())
> self.assertEquals(0, len(vms))
> @@ -440,6 +453,40 @@ class RestTests(unittest.TestCase):
> # Verify the volume was deleted
> self.assertHTTPStatus(404, vol_uri)
>
> + def test_scsi_fc_storage(self):
> + # Create scsi fc pool
> + req = json.dumps({'name': 'scsi_fc_pool',
> + 'type': 'scsi',
> + 'source': {'adapter_name': 'scsi_host3'}})
> + resp = self.request('/storagepools', req, 'POST')
> + self.assertEquals(201, resp.status)
> +
> + # Create template with this pool
> + req = json.dumps({'name': 'test_fc_pool', 'cdrom': '/nonexistent.iso',
> + 'storagepool': '/storagepools/scsi_fc_pool'})
> + resp = self.request('/templates', req, 'POST')
> + self.assertEquals(201, resp.status)
> +
> + # Test create vms using lun of this pool
> + ### activate the storage pool
> + resp = self.request('/storagepools/scsi_fc_pool/activate', '{}', 'POST')
> +
> + ### Get scsi pool luns and choose one
> + resp = self.request('/storagepools/scsi_fc_pool/storagevolumes')
> + luns = json.loads(resp.read())
> + lun_name = random.choice(luns).get('name')
> +
> + ### Create vm in scsi pool without volumes: Error
> + req = json.dumps({'template': '/templates/test_fc_pool'})
> + resp = self.request('/vms', req, 'POST')
> + self.assertEquals(400, resp.status)
> +
> + ### Create vm in scsi pool
> + req = json.dumps({'template': '/templates/test_fc_pool',
> + 'volumes': [lun_name]})
> + resp = self.request('/vms', req, 'POST')
> + self.assertEquals(201, resp.status)
> +
Please, add test to start/stop and delete the created VM
> def test_template_customise_storage(self):
> req = json.dumps({'name': 'test', 'cdrom': '/nonexistent.iso',
> 'disks': [{'size': 1}]})
> diff --git a/tests/test_storagepool.py b/tests/test_storagepool.py
> index a3f4983..700c66e 100644
> --- a/tests/test_storagepool.py
> +++ b/tests/test_storagepool.py
> @@ -141,6 +141,27 @@ class storagepoolTests(unittest.TestCase):
> <path>/dev/disk/by-id</path>
> </target>
> </pool>
> + """},
> + {'def':
> + {'type': 'scsi',
> + 'name': 'unitTestSCSIFCPool',
> + 'path': '/dev/disk/by-path',
> + 'source': {
> + 'name': 'scsi_host3',
> + 'adapter_type': 'fc_host',
> + 'wwpn': '0123456789abcdef',
> + 'wwnn': 'abcdef0123456789' }},
> + 'xml':
> + """
> + <pool type='scsi'>
> + <name>unitTestSCSIFCPool</name>
> + <source>
> + <adapter type='fc_host' name='scsi_host3' wwnn='abcdef0123456789' wwpn='0123456789abcdef'></adapter>
> + </source>
> + <target>
> + <path>/dev/disk/by-path</path>
> + </target>
> + </pool>
> """}]
>
> for poolDef in poolDefs:
More information about the Kimchi-devel
mailing list