[Kimchi-devel] [PATCH v6 (BACKEND) 4/5] Storagepool SCSI/FC: Modifies mockmodel and implements tests for FC pool
Rodrigo Trujillo
rodrigo.trujillo at linux.vnet.ibm.com
Thu Feb 13 18:33:00 UTC 2014
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 | 55 +++++++++++++++++++++++++++++++++++++----
tests/test_rest.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++
tests/test_storagepool.py | 21 ++++++++++++++++
3 files changed, 133 insertions(+), 5 deletions(-)
diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py
index f0f96eb..98715af 100644
--- a/src/kimchi/mockmodel.py
+++ b/src/kimchi/mockmodel.py
@@ -156,7 +156,16 @@ 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 MissingParameter("Volume list (LUNs names) not given.")
+ for vol in params['volumes']:
+ vm.disk_paths.append({'pool': pool.name,
+ 'volume': vol})
+ else:
+ vm.disk_paths = t.fork_vm_storage(vm_uuid)
self._mock_vms[name] = vm
return name
@@ -302,8 +311,19 @@ 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 MissingParameter('adapter_name')
+ for vol in ['unit:0:0:1','unit:0:0:2',
+ 'unit:0:0:3','unit:0:0:4']:
+ mockvol = MockStorageVolume(name, vol,
+ dict([('type','lun')]))
+ 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
@@ -405,6 +425,16 @@ class MockModel(object):
raise InvalidOperation("KCHVOL0006E", {'pool': pool})
return res._volumes.keys()
+ 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'}
@@ -873,11 +903,15 @@ class MockStorageVolume(object):
def __init__(self, pool, name, params={}):
self.name = name
self.pool = pool
+ # Check if volume should be scsi lun
+ if params.get('type') == 'lun':
+ params = self._def_lun(name)
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']
@@ -885,6 +919,17 @@ class MockStorageVolume(object):
self.info['os_distro'] = 'fedora'
self.info['bootable'] = True
+ 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" }
+
class MockVMScreenshot(VMScreenshot):
OUTDATED_SECS = 5
diff --git a/tests/test_rest.py b/tests/test_rest.py
index cd3a462..ce3e471 100644
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -24,6 +24,7 @@
import base64
import json
import os
+import random
import time
import unittest
@@ -145,6 +146,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))
@@ -514,6 +527,55 @@ 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({'name': 'test-vm',
+ 'template': '/templates/test_fc_pool',
+ 'volumes': [lun_name]})
+ resp = self.request('/vms', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Start the VM
+ resp = self.request('/vms/test-vm/start', '{}', 'POST')
+ vm = json.loads(self.request('/vms/test-vm').read())
+ self.assertEquals('running', vm['state'])
+
+ # Force stop the VM
+ resp = self.request('/vms/test-vm/stop', '{}', 'POST')
+ vm = json.loads(self.request('/vms/test-vm').read())
+ self.assertEquals('shutoff', vm['state'])
+
+ # Delete the VM
+ resp = self.request('/vms/test-vm', '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
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:
--
1.8.5.3
More information about the Kimchi-devel
mailing list