[Kimchi-devel] [PATCHv4 7/7] Storage volume upload: Change mockmodel and test

lvroyce at linux.vnet.ibm.com lvroyce at linux.vnet.ibm.com
Thu Sep 4 09:25:53 UTC 2014


From: Royce Lv <lvroyce at linux.vnet.ibm.com>

Change mockmodel and tests to support storagevolume upload.

Signed-off-by: Royce Lv <lvroyce at linux.vnet.ibm.com>
---
 src/kimchi/mockmodel.py | 23 +++++++++++++++++++++--
 tests/test_rest.py      | 43 ++++++++++++++++++++++++++++++++++++++++++-
 tests/utils.py          |  2 +-
 3 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py
index d7a21ed..a4f41da 100644
--- a/src/kimchi/mockmodel.py
+++ b/src/kimchi/mockmodel.py
@@ -482,7 +482,6 @@ class MockModel(object):
 
     def storagevolumes_create(self, pool_name, params):
         vol_source = ['file', 'url', 'capacity']
-
         index_list = list(i for i in range(len(vol_source))
                           if vol_source[i] in params)
         if len(index_list) != 1:
@@ -499,6 +498,27 @@ class MockModel(object):
         taskid = self.add_task('', create_func, params)
         return self.task_lookup(taskid)
 
+    def _create_volume_with_file(self, cb, params):
+        upload_file = params['file']
+        params['name'] = params['name']
+        params['format'] = 'raw'
+        params['capacity'] = upload_file.fp.length
+        size = 0
+        try:
+            while True:
+                data = upload_file.file.read(8192)
+                if not data:
+                        break
+                size += len(data)
+                cb('%s/%s' % (size, params['capacity']), True)
+        except Exception as e:
+            raise OperationFailed('KCHVOL0007E',
+                                  {'name': params['name'],
+                                   'pool': params['pool'],
+                                   'err': e.message})
+        self._create_volume_with_capacity(cb, params)
+        cb('%s/%s' % (size, params['capacity']), True)
+
     def _create_volume_with_capacity(self, cb, params):
         pool_name = params.pop('pool')
         pool = self._get_storagepool(pool_name)
@@ -506,7 +526,6 @@ class MockModel(object):
             raise InvalidOperation("KCHVOL0003E",
                                    {'pool': pool_name,
                                     'volume': params['name']})
-
         try:
             name = params['name']
             volume = MockStorageVolume(pool, name, params)
diff --git a/tests/test_rest.py b/tests/test_rest.py
index 9e14b6d..abc519f 100644
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -22,6 +22,7 @@ import base64
 import json
 import os
 import random
+import requests
 import shutil
 import time
 import unittest
@@ -1041,12 +1042,20 @@ class RestTests(unittest.TestCase):
         resp = self.request('/storagepools/pool-2/storagevolumes/',
                             req, 'POST')
         self.assertEquals(202, resp.status)
+        task_id = json.loads(resp.read())['id']
+        self._wait_task(task_id)
+        status = json.loads(self.request('/tasks/%s' % task_id).read())
+        self.assertEquals('failed', status['status'])
+
         resp = self.request('/storagepools/pool-2/activate', '{}', 'POST')
         self.assertEquals(200, resp.status)
         resp = self.request('/storagepools/pool-2/storagevolumes/',
                             req, 'POST')
         self.assertEquals(202, resp.status)
-        time.sleep(1)
+        task_id = json.loads(resp.read())['id']
+        self._wait_task(task_id)
+        status = json.loads(self.request('/tasks/%s' % task_id).read())
+        self.assertEquals('finished', status['status'])
 
         # Verify the storage volume
         resp = self.request('/storagepools/pool-2/storagevolumes/test-volume')
@@ -1872,6 +1881,38 @@ class RestTests(unittest.TestCase):
         resp = self.request('%s/fedora-fake' % base_uri, '{}', 'DELETE')
         self.assertEquals(204, resp.status)
 
+    def test_upload(self):
+        # If we use self.request, we may encode multipart formdata by ourselves
+        # requests lib take care of encode part, so use this lib instead
+        def fake_auth_header():
+            headers = {'Accept': 'application/json'}
+            user, pw = kimchi.mockmodel.fake_user.items()[0]
+            hdr = "Basic " + base64.b64encode("%s:%s" % (user, pw))
+            headers['AUTHORIZATION'] = hdr
+            return headers
+
+        with RollbackContext() as rollback:
+            upload_path = '/tmp/vol'
+            f = open(upload_path, 'w')
+            f.write('abcd')
+            f.close()
+            rollback.prependDefer(os.remove, upload_path)
+
+            vol = open(upload_path, 'rb')
+            url = "https://%s:%s/storagepools/default/storagevolumes" %\
+                (host, ssl_port)
+
+            r = requests.post(url,
+                              files={'file': vol},
+                              data={'name': 'new_vol2'},
+                              verify=False,
+                              headers=fake_auth_header())
+            self.assertEquals(r.status_code, 202)
+            time.sleep(1)
+            vol_list = json.loads(
+                self.request('/storagepools/default/storagevolumes').read())
+            self.assertEquals('new_vol2', vol_list[0]['name'])
+
 
 class HttpsRestTests(RestTests):
     """
diff --git a/tests/utils.py b/tests/utils.py
index 7fccae1..140bb1d 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -104,7 +104,7 @@ def run_server(host, port, ssl_port, test_mode, cherrypy_port=None,
 
     args = type('_', (object,),
                 {'host': host, 'port': port, 'ssl_port': ssl_port,
-                 'cherrypy_port': cherrypy_port,
+                 'cherrypy_port': cherrypy_port, 'max_body_size': '4*1024',
                  'ssl_cert': '', 'ssl_key': '',
                  'test': test_mode, 'access_log': '/dev/null',
                  'error_log': '/dev/null', 'environment': environment,
-- 
1.8.3.2




More information about the Kimchi-devel mailing list