[Kimchi-devel] [PATCH 1/2] move RollbackContext from tests/utils to src/kimchi/rollbackcontext
Aline Manera
alinefm at linux.vnet.ibm.com
Tue Dec 31 10:24:45 UTC 2013
Needs rebase
On 12/27/2013 08:40 AM, shaohef at linux.vnet.ibm.com wrote:
> From: ShaoHe Feng <shaohef at linux.vnet.ibm.com>
>
> Then kimchi source code can make use of it
> Also add src/kimchi/rollbackcontext.py in dist list
>
> Signed-off-by: Zhou Zheng Sheng <zhshzhou at linux.vnet.ibm.com>
> Signed-off-by: ShaoHe Feng <shaohef at linux.vnet.ibm.com>
> ---
> src/kimchi/Makefile.am | 59 +++++++++++++++++------------------
> src/kimchi/rollbackcontext.py | 71 +++++++++++++++++++++++++++++++++++++++++++
> tests/test_model.py | 25 +++++++--------
> tests/test_rest.py | 3 +-
> tests/utils.py | 45 ---------------------------
> 5 files changed, 116 insertions(+), 87 deletions(-)
> create mode 100644 src/kimchi/rollbackcontext.py
>
> diff --git a/src/kimchi/Makefile.am b/src/kimchi/Makefile.am
> index 47a3bd2..2f05ab7 100644
> --- a/src/kimchi/Makefile.am
> +++ b/src/kimchi/Makefile.am
> @@ -21,35 +21,36 @@
> # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>
> kimchi_PYTHON = \
> - asynctask.py \
> - auth.py \
> - controller.py \
> - disks.py \
> - distroloader.py \
> - exception.py \
> - __init__.py \
> - isoinfo.py \
> - netinfo.py \
> - network.py \
> - networkxml.py \
> - mockmodel.py \
> - model.py \
> - objectstore.py \
> - osinfo.py \
> - root.py \
> - scan.py \
> - screenshot.py \
> - server.py \
> - sslcert.py \
> - template.py \
> - vmtemplate.py \
> - vnc.py \
> - websocket.py \
> - websockify.py \
> - xmlutils.py \
> - utils.py \
> - cachebust.py \
> - featuretests.py
> + __init__.py \
> + asynctask.py \
> + auth.py \
> + cachebust.py \
> + controller.py \
> + disks.py \
> + distroloader.py \
> + exception.py \
> + featuretests.py \
> + isoinfo.py \
> + mockmodel.py \
> + model.py \
> + netinfo.py \
> + network.py \
> + networkxml.py \
> + objectstore.py \
> + osinfo.py \
> + rollbackcontext.py \
> + root.py \
> + scan.py \
> + screenshot.py \
> + server.py \
> + sslcert.py \
> + template.py \
> + utils.py \
> + vmtemplate.py \
> + vnc.py \
> + websocket.py \
> + websockify.py \
> + xmlutils.py
>
> nodist_kimchi_PYTHON = config.py
>
> diff --git a/src/kimchi/rollbackcontext.py b/src/kimchi/rollbackcontext.py
> new file mode 100644
> index 0000000..2afd114
> --- /dev/null
> +++ b/src/kimchi/rollbackcontext.py
> @@ -0,0 +1,71 @@
> +#
> +# Project Kimchi
> +#
> +# Copyright IBM, Corp. 2013
> +#
> +# Authors:
> +# Adam Litke <agl at linux.vnet.ibm.com>
> +# ShaoHe Feng <shaohef at linux.vnet.ibm.com>
> +#
> +# This library is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU Lesser General Public
> +# License as published by the Free Software Foundation; either
> +# version 2.1 of the License, or (at your option) any later version.
> +#
> +# This library is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +# Lesser General Public License for more details.
> +#
> +# You should have received a copy of the GNU Lesser General Public
> +# License along with this library; if not, write to the Free Software
> +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> +#
> +
> +import sys
> +
> +
> +class RollbackContext(object):
> + '''
> + A context manager for recording and playing rollback.
> + The first exception will be remembered and re-raised after rollback
> +
> + Sample usage:
> + with RollbackContext() as rollback:
> + step1()
> + rollback.prependDefer(lambda: undo step1)
> + def undoStep2(arg): pass
> + step2()
> + rollback.prependDefer(undoStep2, arg)
> + '''
> + def __init__(self, *args):
> + self._finally = []
> +
> + def __enter__(self):
> + return self
> +
> + def __exit__(self, exc_type, exc_value, traceback):
> + firstException = exc_value
> +
> + for undo, args, kwargs in self._finally:
> + try:
> + undo(*args, **kwargs)
> + except Exception as e:
> + # keep the earliest exception info
> + if not firstException:
> + firstException = e
> + # keep the original traceback info
> + traceback = sys.exc_info()[2]
> +
> + # re-raise the earliest exception
> + if firstException is not None:
> + if type(firstException) is str:
> + sys.stderr.write(firstException)
> + else:
> + raise firstException, None, traceback
> +
> + def defer(self, func, *args, **kwargs):
> + self._finally.append((func, args, kwargs))
> +
> + def prependDefer(self, func, *args, **kwargs):
> + self._finally.insert(0, (func, args, kwargs))
> diff --git a/tests/test_model.py b/tests/test_model.py
> index e19364f..7ecd8c6 100644
> --- a/tests/test_model.py
> +++ b/tests/test_model.py
> @@ -38,6 +38,7 @@ import utils
> from kimchi import netinfo
> from kimchi.exception import InvalidOperation, InvalidParameter
> from kimchi.exception import NotFoundError, OperationFailed
> +from kimchi.rollbackcontext import RollbackContext
>
>
> class ModelTests(unittest.TestCase):
> @@ -72,7 +73,7 @@ class ModelTests(unittest.TestCase):
> def test_vm_lifecycle(self):
> inst = kimchi.model.Model(objstore_loc=self.tmp_store)
>
> - with utils.RollbackContext() as rollback:
> + with RollbackContext() as rollback:
> params = {'name': 'test', 'disks': []}
> inst.templates_create(params)
> rollback.prependDefer(inst.template_delete, 'test')
> @@ -97,7 +98,7 @@ class ModelTests(unittest.TestCase):
> def test_vm_storage_provisioning(self):
> inst = kimchi.model.Model(objstore_loc=self.tmp_store)
>
> - with utils.RollbackContext() as rollback:
> + with RollbackContext() as rollback:
> params = {'name': 'test', 'disks': [{'size': 1}]}
> inst.templates_create(params)
> rollback.prependDefer(inst.template_delete, 'test')
> @@ -115,7 +116,7 @@ class ModelTests(unittest.TestCase):
> def test_storagepool(self):
> inst = kimchi.model.Model('qemu:///system', self.tmp_store)
>
> - with utils.RollbackContext() as rollback:
> + with RollbackContext() as rollback:
> path = '/tmp/kimchi-images'
> name = 'test-pool'
> if not os.path.exists(path):
> @@ -168,7 +169,7 @@ class ModelTests(unittest.TestCase):
> def test_storagevolume(self):
> inst = kimchi.model.Model('qemu:///system', self.tmp_store)
>
> - with utils.RollbackContext() as rollback:
> + with RollbackContext() as rollback:
> path = '/tmp/kimchi-images'
> pool = 'test-pool'
> vol = 'test-volume.img'
> @@ -223,7 +224,7 @@ class ModelTests(unittest.TestCase):
> def test_template_storage_customise(self):
> inst = kimchi.model.Model(objstore_loc=self.tmp_store)
>
> - with utils.RollbackContext() as rollback:
> + with RollbackContext() as rollback:
> path = '/tmp/kimchi-images'
> pool = 'test-pool'
> if not os.path.exists(path):
> @@ -295,7 +296,7 @@ class ModelTests(unittest.TestCase):
> orig_params = {'name': 'test', 'memory': '1024', 'cpus': '1'}
> inst.templates_create(orig_params)
>
> - with utils.RollbackContext() as rollback:
> + with RollbackContext() as rollback:
> params_1 = {'name': 'kimchi-vm1', 'template': '/templates/test'}
> params_2 = {'name': 'kimchi-vm2', 'template': '/templates/test'}
> inst.vms_create(params_1)
> @@ -326,7 +327,7 @@ class ModelTests(unittest.TestCase):
> def test_network(self):
> inst = kimchi.model.Model('qemu:///system', self.tmp_store)
>
> - with utils.RollbackContext() as rollback:
> + with RollbackContext() as rollback:
> name = 'test-network'
>
> networks = inst.networks_get_list()
> @@ -480,7 +481,7 @@ class ModelTests(unittest.TestCase):
> def test_delete_running_vm(self):
> inst = kimchi.model.Model(objstore_loc=self.tmp_store)
>
> - with utils.RollbackContext() as rollback:
> + with RollbackContext() as rollback:
> params = {'name': u'test', 'disks': []}
> inst.templates_create(params)
> rollback.prependDefer(inst.template_delete, 'test')
> @@ -501,7 +502,7 @@ class ModelTests(unittest.TestCase):
> def test_vm_list_sorted(self):
> inst = kimchi.model.Model(objstore_loc=self.tmp_store)
>
> - with utils.RollbackContext() as rollback:
> + with RollbackContext() as rollback:
> params = {'name': 'test', 'disks': []}
> inst.templates_create(params)
> rollback.prependDefer(inst.template_delete, 'test')
> @@ -517,7 +518,7 @@ class ModelTests(unittest.TestCase):
> def test_use_test_host(self):
> inst = kimchi.model.Model('test:///default', objstore_loc=self.tmp_store)
>
> - with utils.RollbackContext() as rollback:
> + with RollbackContext() as rollback:
> params = {'name': 'test', 'disks': [],
> 'storagepool': '/storagepools/default-pool',
> 'domain': 'test',
> @@ -546,7 +547,7 @@ class ModelTests(unittest.TestCase):
> inst.debugreport_delete(namePrefix + '*')
> except NotFoundError:
> pass
> - with utils.RollbackContext() as rollback:
> + with RollbackContext() as rollback:
> report_list = inst.debugreports_get_list()
> self.assertFalse(reportName in report_list)
> try:
> @@ -617,7 +618,7 @@ class ModelTests(unittest.TestCase):
> @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
> def test_deep_scan(self):
> inst = kimchi.model.Model('qemu:///system', objstore_loc=self.tmp_store)
> - with utils.RollbackContext() as rollback:
> + with RollbackContext() as rollback:
> path = '/tmp/kimchi-images/tmpdir'
> if not os.path.exists(path):
> os.makedirs(path)
> diff --git a/tests/test_rest.py b/tests/test_rest.py
> index 73946c0..1b7312f 100644
> --- a/tests/test_rest.py
> +++ b/tests/test_rest.py
> @@ -33,8 +33,9 @@ from functools import partial
> import kimchi.mockmodel
> import kimchi.server
> from kimchi.asynctask import AsyncTask
> +from kimchi.rollbackcontext import RollbackContext
> from utils import fake_user, get_free_port, https_request, patch_auth, request
> -from utils import RollbackContext, run_server
> +from utils import run_server
>
>
> test_server = None
> diff --git a/tests/utils.py b/tests/utils.py
> index a7596e8..960e0be 100644
> --- a/tests/utils.py
> +++ b/tests/utils.py
> @@ -140,51 +140,6 @@ def https_request(host, port, path, data=None, method='GET', headers=None):
> return _request(conn, path, data, method, headers)
>
>
> -class RollbackContext(object):
> - '''
> - A context manager for recording and playing rollback.
> - The first exception will be remembered and re-raised after rollback
> -
> - Sample usage:
> - with RollbackContext() as rollback:
> - step1()
> - rollback.prependDefer(lambda: undo step1)
> - def undoStep2(arg): pass
> - step2()
> - rollback.prependDefer(undoStep2, arg)
> - '''
> - def __init__(self, *args):
> - self._finally = []
> -
> - def __enter__(self):
> - return self
> -
> - def __exit__(self, exc_type, exc_value, traceback):
> - firstException = exc_value
> -
> - for undo, args, kwargs in self._finally:
> - try:
> - undo(*args, **kwargs)
> - except Exception as e:
> - # keep the earliest exception info
> - if not firstException:
> - firstException = e
> - # keep the original traceback info
> - traceback = sys.exc_info()[2]
> -
> - # re-raise the earliest exception
> - if firstException is not None:
> - if type(firstException) is str:
> - sys.stderr.write(firstException)
> - else:
> - raise firstException, None, traceback
> -
> - def defer(self, func, *args, **kwargs):
> - self._finally.append((func, args, kwargs))
> -
> - def prependDefer(self, func, *args, **kwargs):
> - self._finally.insert(0, (func, args, kwargs))
> -
> def patch_auth():
> """
> Override the authenticate function with a simple test against an
More information about the Kimchi-devel
mailing list