:p
atchew
Login
Aline Manera (6): Specify objectstore location when running on test mode Update run_server() calls to do not pass model instance Bug fix: Set default host value while generating the virt-viewer config file Fix snapshots test case Fix memory hotplug test case Improve logic to identify if a network is in use or not i18n.py | 4 ++-- model/networks.py | 42 ++++++++++++++++++++++++--------------- model/virtviewerfile.py | 10 ++++------ root.py | 24 +++++++++++++--------- tests/test_authorization.py | 10 ++++------ tests/test_host.py | 15 +++----------- tests/test_livemigration.py | 6 +----- tests/test_mock_network.py | 10 ++++------ tests/test_mock_storagepool.py | 12 ++++------- tests/test_mock_storagevolume.py | 11 ++++------ tests/test_mockmodel.py | 8 +++----- tests/test_model.py | 15 ++++++++------ tests/test_model_network.py | 18 ++++++++++------- tests/test_model_storagepool.py | 18 +++++++++-------- tests/test_model_storagevolume.py | 18 ++++++++++------- tests/test_rest.py | 27 +++++++++++++------------ tests/test_template.py | 9 ++++----- 17 files changed, 129 insertions(+), 128 deletions(-) -- 2.9.3 _______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
That way, the objectstore file can be deleted on server shutting down and the system keeps clean of any changes while running on test mode. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- root.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/root.py b/root.py index XXXXXXX..XXXXXXX 100644 --- a/root.py +++ b/root.py @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json import os -import cherrypy +import tempfile from wok.plugins.kimchi import config, mockmodel, websocket from wok.plugins.kimchi.i18n import messages @@ -XXX,XX +XXX,XX @@ class Kimchi(WokRoot): if not os.path.isdir(directory): os.makedirs(directory) - if hasattr(wok_options, "model"): - self.model = wok_options.model - elif wok_options.test: - self.model = mockmodel.MockModel() + # When running on test mode, specify the objectstore location to + # remove the file on server shutting down. That way, the system will + # not suffer any change while running on test mode + if wok_options.test: + self.objectstore_loc = tempfile.mktemp() + self.model = mockmodel.MockModel(self.objectstore_loc) + def remove_objectstore(): + if os.path.exists(self.objectstore_loc): + os.unlink(self.objectstore_loc) + cherrypy.engine.subscribe('exit', remove_objectstore) else: self.model = kimchiModel.Model() + ws_proxy = websocket.new_ws_proxy() + cherrypy.engine.subscribe('exit', ws_proxy.terminate) dev_env = wok_options.environment != 'production' super(Kimchi, self).__init__(self.model, dev_env) @@ -XXX,XX +XXX,XX @@ class Kimchi(WokRoot): for ident, node in sub_nodes.items(): setattr(self, ident, node(self.model)) - if isinstance(self.model, kimchiModel.Model): - ws_proxy = websocket.new_ws_proxy() - cherrypy.engine.subscribe('exit', ws_proxy.terminate) - self.api_schema = json.load(open(os.path.join(os.path.dirname( os.path.abspath(__file__)), 'API.json'))) self.paths = config.kimchiPaths -- 2.9.3 _______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
The model instance will be gotten from cherrypy when needed. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- root.py | 3 ++- tests/test_authorization.py | 10 ++++------ tests/test_host.py | 15 +++------------ tests/test_livemigration.py | 6 +----- tests/test_mock_network.py | 10 ++++------ tests/test_mock_storagepool.py | 12 ++++-------- tests/test_mock_storagevolume.py | 11 ++++------- tests/test_mockmodel.py | 8 +++----- tests/test_model_network.py | 18 +++++++++++------- tests/test_model_storagepool.py | 18 ++++++++++-------- tests/test_model_storagevolume.py | 18 +++++++++++------- tests/test_rest.py | 7 +++---- tests/test_template.py | 9 ++++----- 13 files changed, 64 insertions(+), 81 deletions(-) diff --git a/root.py b/root.py index XXXXXXX..XXXXXXX 100644 --- a/root.py +++ b/root.py @@ -XXX,XX +XXX,XX @@ class Kimchi(WokRoot): # When running on test mode, specify the objectstore location to # remove the file on server shutting down. That way, the system will # not suffer any change while running on test mode - if wok_options.test: + if wok_options.test is True or wok_options.test.lower() == 'true': self.objectstore_loc = tempfile.mktemp() self.model = mockmodel.MockModel(self.objectstore_loc) + def remove_objectstore(): if os.path.exists(self.objectstore_loc): os.unlink(self.objectstore_loc) diff --git a/tests/test_authorization.py b/tests/test_authorization.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_authorization.py +++ b/tests/test_authorization.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2014-2016 +# Copyright IBM Corp, 2014-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json import os import unittest @@ -XXX,XX +XXX,XX @@ from functools import partial from tests.utils import get_fake_user, patch_auth from tests.utils import request, run_server, wait_task -from wok.plugins.kimchi import mockmodel - from iso_gen import construct_fake_iso @@ -XXX,XX +XXX,XX @@ def setUpModule(): global test_server, model patch_auth(sudo=False) - model = mockmodel.MockModel('/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model # Create fake ISO to do the tests construct_fake_iso(fake_iso, True, '12.04', 'ubuntu') @@ -XXX,XX +XXX,XX @@ def setUpModule(): def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') os.unlink(fake_iso) diff --git a/tests/test_host.py b/tests/test_host.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_host.py +++ b/tests/test_host.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import json -import os -import tempfile import unittest from functools import partial from tests.utils import patch_auth, request, run_server -from wok.plugins.kimchi.mockmodel import MockModel - test_server = None -model = None -tmpfile = None def setUpModule(): - global test_server, model, tmpfile + global test_server patch_auth() - tmpfile = tempfile.mktemp() - model = MockModel(tmpfile) - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) def tearDownModule(): test_server.stop() - os.unlink(tmpfile) class HostTests(unittest.TestCase): diff --git a/tests/test_livemigration.py b/tests/test_livemigration.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_livemigration.py +++ b/tests/test_livemigration.py @@ -XXX,XX +XXX,XX @@ class LiveMigrationTests(unittest.TestCase): 'not possible to test a live migration') def test_vm_livemigrate_persistent_API(self): patch_auth() - - inst = model.Model(libvirt_uri='qemu:///system', - objstore_loc=self.tmp_store) - with RollbackContext() as rollback: - test_server = run_server(test_mode=True, model=inst) + test_server = run_server() rollback.prependDefer(test_server.stop) self.request = partial(request) diff --git a/tests/test_mock_network.py b/tests/test_mock_network.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_mock_network.py +++ b/tests/test_mock_network.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json -import os import unittest from functools import partial from tests.utils import patch_auth, request, run_server -from wok.plugins.kimchi.mockmodel import MockModel from wok.plugins.kimchi.model.featuretests import FeatureTests from test_model_network import _do_network_test @@ -XXX,XX +XXX,XX @@ def setUpModule(): global test_server, model patch_auth() - model = MockModel('/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') class MockNetworkTests(unittest.TestCase): diff --git a/tests/test_mock_storagepool.py b/tests/test_mock_storagepool.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_mock_storagepool.py +++ b/tests/test_mock_storagepool.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json -import os import unittest from functools import partial from tests.utils import patch_auth, request, run_server -from wok.plugins.kimchi.mockmodel import MockModel - - model = None test_server = None @@ -XXX,XX +XXX,XX @@ def setUpModule(): global test_server, model patch_auth() - model = MockModel('/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') class MockStoragepoolTests(unittest.TestCase): diff --git a/tests/test_mock_storagevolume.py b/tests/test_mock_storagevolume.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_mock_storagevolume.py +++ b/tests/test_mock_storagevolume.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json -import os import unittest from functools import partial from tests.utils import patch_auth, request, run_server -from wok.plugins.kimchi.mockmodel import MockModel - from test_model_storagevolume import _do_volume_test @@ -XXX,XX +XXX,XX @@ def setUpModule(): global test_server, model patch_auth() - model = MockModel('/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') class MockStorageVolumeTests(unittest.TestCase): diff --git a/tests/test_mockmodel.py b/tests/test_mockmodel.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_mockmodel.py +++ b/tests/test_mockmodel.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2013-2016 +# Copyright IBM Corp, 2013-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ from tests.utils import patch_auth, request, run_server from tests.utils import wait_task from wok.exception import InvalidOperation -from wok.plugins.kimchi import mockmodel from wok.plugins.kimchi.osinfo import get_template_default import iso_gen @@ -XXX,XX +XXX,XX @@ fake_iso = None def setUpModule(): global model, test_server, fake_iso cherrypy.request.headers = {'Accept': 'application/json'} - model = mockmodel.MockModel('/tmp/obj-store-test') patch_auth() - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model fake_iso = '/tmp/fake.iso' iso_gen.construct_fake_iso(fake_iso, True, '12.04', 'ubuntu') def tearDown(): test_server.stop() - os.unlink('/tmp/obj-store-test') os.unlink(fake_iso) diff --git a/tests/test_model_network.py b/tests/test_model_network.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_model_network.py +++ b/tests/test_model_network.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json +import mock import os +import tempfile import unittest from functools import partial @@ -XXX,XX +XXX,XX @@ from tests.utils import run_server from wok.rollbackcontext import RollbackContext -from wok.plugins.kimchi.model.model import Model from wok.plugins.kimchi.model.featuretests import FeatureTests - model = None +objectstore_loc = tempfile.mktemp() test_server = None -def setUpModule(): +@mock.patch('wok.plugins.kimchi.config.get_object_store') +def setUpModule(func): + func.return_value = objectstore_loc global test_server, model patch_auth() - model = Model(None, '/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=False) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') + os.unlink(objectstore_loc) def _do_network_test(self, model, params): diff --git a/tests/test_model_storagepool.py b/tests/test_model_storagepool.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_model_storagepool.py +++ b/tests/test_model_storagepool.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json +import mock import os import shutil import tempfile @@ -XXX,XX +XXX,XX @@ from functools import partial from wok.rollbackcontext import RollbackContext -from wok.plugins.kimchi.model.model import Model - from tests.utils import patch_auth, request from tests.utils import run_server - model = None +objectstore_loc = tempfile.mktemp() test_server = None -def setUpModule(): +@mock.patch('wok.plugins.kimchi.config.get_object_store') +def setUpModule(func): + func.return_value = objectstore_loc global test_server, model patch_auth() - model = Model(None, '/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=False) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') + os.unlink(objectstore_loc) class StoragepoolTests(unittest.TestCase): diff --git a/tests/test_model_storagevolume.py b/tests/test_model_storagevolume.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_model_storagevolume.py +++ b/tests/test_model_storagevolume.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json +import mock import os import requests +import tempfile import unittest from functools import partial @@ -XXX,XX +XXX,XX @@ from wok.config import paths from wok.rollbackcontext import RollbackContext from wok.plugins.kimchi.config import READONLY_POOL_TYPE -from wok.plugins.kimchi.model.model import Model - model = None +objectstore_loc = tempfile.mktemp() test_server = None -def setUpModule(): +@mock.patch('wok.plugins.kimchi.config.get_object_store') +def setUpModule(func): + func.return_value = objectstore_loc global test_server, model patch_auth() - model = Model(None, '/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=False) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') + os.unlink(objectstore_loc) def _do_volume_test(self, model, pool_name): diff --git a/tests/test_rest.py b/tests/test_rest.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json import os import re @@ -XXX,XX +XXX,XX @@ from tests.utils import patch_auth, request, run_server, wait_task from wok.asynctask import AsyncTask from wok.rollbackcontext import RollbackContext -from wok.plugins.kimchi import mockmodel from wok.plugins.kimchi.osinfo import get_template_default import iso_gen @@ -XXX,XX +XXX,XX @@ def setUpModule(): global test_server, model patch_auth() - model = mockmodel.MockModel('/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model # Create fake ISO to do the tests iso_gen.construct_fake_iso(fake_iso, True, '12.04', 'ubuntu') @@ -XXX,XX +XXX,XX @@ def setUpModule(): def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') os.unlink(fake_iso) os.unlink("/var/lib/libvirt/images/fedora.iso") diff --git a/tests/test_template.py b/tests/test_template.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import iso_gen import json import os @@ -XXX,XX +XXX,XX @@ from functools import partial from tests.utils import patch_auth, request, run_server from wok.plugins.kimchi.config import READONLY_POOL_TYPE -from wok.plugins.kimchi.mockmodel import MockModel from wok.plugins.kimchi.model.featuretests import FeatureTests from wok.plugins.kimchi.model.templates import MAX_MEM_LIM @@ -XXX,XX +XXX,XX @@ def setUpModule(): global test_server, model patch_auth() - model = MockModel('/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model iso_gen.construct_fake_iso(MOCK_ISO, True, '14.04', 'ubuntu') def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') class TemplateTests(unittest.TestCase): -- 2.9.3 _______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
The test case was failing as below: ====================================================================== ERROR: test_vm_virtviewerfile_vmlifecycle (test_model.ModelTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched return func(*args, **keywargs) File "test_model.py", line 571, in test_vm_virtviewerfile_vmlifecycle vvmodel.lookup(vm_name.decode('utf-8')) File "/home/alinefm/wok/src/wok/plugins/kimchi/model/virtviewerfile.py", line 133, in lookup file_path = create_virt_viewer_file(name, graphics_info) File "/home/alinefm/wok/src/wok/plugins/kimchi/model/virtviewerfile.py", line 82, in create_virt_viewer_file {'name': vm_name, 'err': e.message}) OperationFailed: KCHVM0084E: KCHVM0084E Because the virt-viewer config file generation was relying on Wok configuration to get the host information but the host information is not part of Wok anymore. Instead of that, it is being configured on nginx. Set it to 'localhost' when that information is not part of request headers. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- model/virtviewerfile.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/model/virtviewerfile.py b/model/virtviewerfile.py index XXXXXXX..XXXXXXX 100644 --- a/model/virtviewerfile.py +++ b/model/virtviewerfile.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2016 +# Copyright IBM Corp, 2016-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ import cherrypy import libvirt import os -from wok.config import config as wok_config from wok.exception import InvalidOperation, OperationFailed from wok.plugins.kimchi import config as kimchi_config from wok.plugins.kimchi.model.vms import VMModel @@ -XXX,XX +XXX,XX @@ port=%(graphics_port)s def _get_request_host(): - host = cherrypy.request.headers.get('Host') - if not host: - host = wok_config.get("server", "host") + host = cherrypy.request.headers.get('Host', 'localhost') host = host.split(':')[0] return host @@ -XXX,XX +XXX,XX @@ class VMVirtViewerFileModel(object): vm_name = dom.name() self.firewall_mngr.remove_vm_graphics_port(vm_name) cb_id = self.vm_event_callbacks.pop(vm_name, None) - self.conn.get().domainEventDeregisterAny(cb_id) + if cb_id is not None: + self.conn.get().domainEventDeregisterAny(cb_id) def handleVMShutdownPowerOff(self, vm_name): try: -- 2.9.3 _______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
Commit a2063007 has added a new test to validate snapshot on running guest but it has not considered the whole test case in count and it was failing as below: ====================================================================== FAIL: test_vm_lifecycle (test_model.ModelTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "test_model.py", line 218, in test_vm_lifecycle self.assertEquals({}, empty_snap) AssertionError: {} != {'state': u'running', 'name': u'1486470484', 'parent': u'', 'created': u'1486470 [truncated]... - {} + {'created': u'1486470484', + 'name': u'1486470484', + 'parent': u'', + 'state': u'running'} So fix it. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- tests/test_model.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/test_model.py b/tests/test_model.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -XXX,XX +XXX,XX @@ class ModelTests(unittest.TestCase): inst.task_wait(task['id']) task = inst.task_lookup(task['id']) self.assertEquals('finished', task['status']) + snap_name = task['target_uri'].split('/')[-1] + created_snaps = [snap_name] inst.vm_poweroff(u'kimchi-vm') vm = inst.vm_lookup(u'kimchi-vm') - empty_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm') - self.assertEquals({}, empty_snap) + current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm') + self.assertEquals(created_snaps[0], current_snap['name']) # this snapshot should be deleted when its VM is deleted params = {'name': u'mysnap'} @@ -XXX,XX +XXX,XX @@ class ModelTests(unittest.TestCase): inst.task_wait(task['id']) task = inst.task_lookup(task['id']) self.assertEquals('finished', task['status']) + created_snaps.append(params['name']) self.assertRaises(NotFoundError, inst.vmsnapshot_lookup, u'kimchi-vm', u'foobar') @@ -XXX,XX +XXX,XX @@ class ModelTests(unittest.TestCase): self.assertTrue(int(time.time()) >= int(snap['created'])) self.assertEquals(vm['state'], snap['state']) self.assertEquals(params['name'], snap['name']) - self.assertEquals(u'', snap['parent']) + self.assertEquals(created_snaps[0], snap['parent']) snaps = inst.vmsnapshots_get_list(u'kimchi-vm') - self.assertEquals([params['name']], snaps) + self.assertEquals(created_snaps, snaps) current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm') self.assertEquals(snap, current_snap) @@ -XXX,XX +XXX,XX @@ class ModelTests(unittest.TestCase): inst.task_wait(task['id']) task = inst.task_lookup(task['id']) self.assertEquals('finished', task['status']) + created_snaps.append(snap_name) snaps = inst.vmsnapshots_get_list(u'kimchi-vm') - self.assertEquals(sorted([params['name'], snap_name], - key=unicode.lower), snaps) + self.assertEquals(sorted(created_snaps, key=unicode.lower), snaps) snap = inst.vmsnapshot_lookup(u'kimchi-vm', snap_name) current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm') -- 2.9.3 _______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
The memory hotplug support depends on libvirt and qemu support. The libvirt test driver does not support this type of configuration so update the test case to verify the system has its support or not. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- tests/test_rest.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/tests/test_rest.py b/tests/test_rest.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -XXX,XX +XXX,XX @@ class RestTests(unittest.TestCase): resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') self.assertEquals(400, resp.status) - if not os.uname()[4] == "s390x": + # Check if there is support to memory hotplug + resp = self.request('/plugins/kimchi/config/capabilities').read() + conf = json.loads(resp) + if os.uname()[4] != "s390x" and conf['mem_hotplug_support']: req = json.dumps({'memory': {'maxmemory': 3072}}) resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') self.assertEquals(200, resp.status) @@ -XXX,XX +XXX,XX @@ class RestTests(unittest.TestCase): resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') self.assertEquals(400, resp.status) - # Check if there is support to memory hotplug, once vm is running - resp = self.request('/plugins/kimchi/config/capabilities').read() - conf = json.loads(resp) + # Test memory hotplug req = json.dumps({'memory': {'current': 2048}}) resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') if conf['mem_hotplug_support']: @@ -XXX,XX +XXX,XX @@ class RestTests(unittest.TestCase): vm = json.loads( self.request('/plugins/kimchi/vms/vm-1', req).read() ) + + # The maxmemory will be automatically increased when the amount of + # memory value is greater than the current maxmemory value params = {'name': u'∨м-црdαtеd', 'cpu_info': {'vcpus': 5}, 'memory': {'current': 3072}} req = json.dumps(params) @@ -XXX,XX +XXX,XX @@ class RestTests(unittest.TestCase): # Memory was hot plugged vm['name'] = u'∨м-црdαtеd' vm['cpu_info'].update(params['cpu_info']) - if not os.uname()[4] == "s390x": - vm['memory'].update(params['memory']) - else: - vm['memory']['current'] = 3072 - vm['memory']['maxmemory'] = 3072 + vm['memory']['current'] = 3072 + vm['memory']['maxmemory'] = 3072 + for key in params.keys(): self.assertEquals(vm[key], vm_updated[key]) -- 2.9.3 _______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
The function get_vms_attach_to_a_network() to identify which virtual machines are using a given network was being called multiple times without need. So improve the logic. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- i18n.py | 4 ++-- model/networks.py | 42 ++++++++++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/i18n.py b/i18n.py index XXXXXXX..XXXXXXX 100644 --- a/i18n.py +++ b/i18n.py @@ -XXX,XX +XXX,XX @@ messages = { "KCHNET0014E": _("Network interfaces must be an array."), "KCHNET0015E": _("Network VLAN ID must be an integer between 1 and 4094"), "KCHNET0016E": _("Specify name and type to create a Network"), - "KCHNET0017E": _("Unable to delete or update network %(name)s. There are some virtual machines %(vms)s and/or templates linked to this network."), - "KCHNET0018E": _("Unable to deactivate network %(name)s. There are some virtual machines %(vms)s and/or templates linked to this network."), + "KCHNET0017E": _("Unable to delete or update network %(name)s as it is linked to some virtual machines (%(vms)s) and/or templates (%(tmpls)s)."), + "KCHNET0018E": _("Unable to deactivate network %(name)s as it is linked to are some virtual machines (%(vms)s) and/or templates (%(tmpls)s)."), "KCHNET0019E": _("Bridge device %(name)s can not be the trunk device of a VLAN."), "KCHNET0020E": _("Failed to activate interface %(iface)s: %(err)s."), "KCHNET0021E": _("Failed to activate interface %(iface)s. Please check the physical link status."), diff --git a/model/networks.py b/model/networks.py index XXXXXXX..XXXXXXX 100644 --- a/model/networks.py +++ b/model/networks.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ class NetworkModel(object): else: interfaces = [interface] + network_in_use, used_by_vms, _ = self._is_network_in_use(name) + return {'connection': connection, 'interfaces': interfaces, 'subnet': subnet, 'dhcp': dhcp, - 'vms': self._get_vms_attach_to_a_network(name), - 'in_use': self._is_network_in_use(name), + 'vms': used_by_vms, + 'in_use': network_in_use, 'autostart': network.autostart() == 1, 'state': network.isActive() and "active" or "inactive", 'persistent': True if network.isPersistent() else False} @@ -XXX,XX +XXX,XX @@ class NetworkModel(object): # All the networks listed as default in template.conf file should not # be deactivate or deleted. Otherwise, we will allow user create # inconsistent templates from scratch + vms = self._get_vms_attach_to_a_network(name) + tmpls = self._is_network_used_by_template(name) + if name in tmpl_defaults['networks']: - return True + return (True, vms, tmpls) - vms = self._get_vms_attach_to_a_network(name) - return bool(vms) or self._is_network_used_by_template(name) + return (bool(vms) or bool(tmpls), vms, tmpls) def _is_network_used_by_template(self, network): + tmpl_list = [] + with self.objstore as session: templates = session.get_list('template') for tmpl in templates: tmpl_net = session.get('template', tmpl)['networks'] if network in tmpl_net: - return True - return False + tmpl_list.append(tmpl) + return tmpl_list def _get_vms_attach_to_a_network(self, network, filter="all"): DOM_STATE_MAP = {'nostate': 0, 'running': 1, 'blocked': 2, @@ -XXX,XX +XXX,XX @@ class NetworkModel(object): 'err': e.message}) def deactivate(self, name): - if self._is_network_in_use(name): - vms = self._get_vms_attach_to_a_network(name) - vms.sort() + in_use, used_by_vms, used_by_tmpls = self._is_network_in_use(name) + vms = 'N/A' if len(used_by_vms) == 0 else ', '.join(used_by_vms) + tmpls = 'N/A' if len(used_by_tmpls) == 0 else ', '.join(used_by_tmpls) + if in_use: raise InvalidOperation("KCHNET0018E", {'name': name, - 'vms': ', '.join(vms)}) + 'vms': vms, + 'tmpls': tmpls}) network = self.get_network(self.conn.get(), name) network.destroy() def delete(self, name): - if self._is_network_in_use(name): - vms = self._get_vms_attach_to_a_network(name) - vms.sort() + in_use, used_by_vms, used_by_tmpls = self._is_network_in_use(name) + vms = 'N/A' if len(used_by_vms) == 0 else ', '.join(used_by_vms) + tmpls = 'N/A' if len(used_by_tmpls) == 0 else ', '.join(used_by_tmpls) + if in_use: raise InvalidOperation("KCHNET0017E", {'name': name, - 'vms': ', '.join(vms)}) + 'vms': vms, + 'tmpls': tmpls}) network = self.get_network(self.conn.get(), name) if network.isActive(): -- 2.9.3 _______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
Only patch 1/2 has changed from V1. Now it is checking if wok_options.test is not None before using its value. Aline Manera (6): Specify objectstore location when running on test mode Update run_server() calls to do not pass model instance Bug fix: Set default host value while generating the virt-viewer config file Fix snapshots test case Fix memory hotplug test case Improve logic to identify if a network is in use or not i18n.py | 4 ++-- model/networks.py | 42 ++++++++++++++++++++++++--------------- model/virtviewerfile.py | 10 ++++------ root.py | 25 ++++++++++++++--------- tests/test_authorization.py | 10 ++++------ tests/test_host.py | 15 +++----------- tests/test_livemigration.py | 6 +----- tests/test_mock_network.py | 10 ++++------ tests/test_mock_storagepool.py | 12 ++++------- tests/test_mock_storagevolume.py | 11 ++++------ tests/test_mockmodel.py | 8 +++----- tests/test_model.py | 15 ++++++++------ tests/test_model_network.py | 18 ++++++++++------- tests/test_model_storagepool.py | 18 +++++++++-------- tests/test_model_storagevolume.py | 18 ++++++++++------- tests/test_rest.py | 27 +++++++++++++------------ tests/test_template.py | 9 ++++----- 17 files changed, 130 insertions(+), 128 deletions(-) -- 2.9.3 _______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
That way, the objectstore file can be deleted on server shutting down and the system keeps clean of any changes while running on test mode. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- root.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/root.py b/root.py index XXXXXXX..XXXXXXX 100644 --- a/root.py +++ b/root.py @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json import os -import cherrypy +import tempfile from wok.plugins.kimchi import config, mockmodel, websocket from wok.plugins.kimchi.i18n import messages @@ -XXX,XX +XXX,XX @@ class Kimchi(WokRoot): if not os.path.isdir(directory): os.makedirs(directory) - if hasattr(wok_options, "model"): - self.model = wok_options.model - elif wok_options.test: - self.model = mockmodel.MockModel() + # When running on test mode, specify the objectstore location to + # remove the file on server shutting down. That way, the system will + # not suffer any change while running on test mode + if wok_options.test and (wok_options.test is True or + wok_options.test.lower() == 'true'): + self.objectstore_loc = tempfile.mktemp() + self.model = mockmodel.MockModel(self.objectstore_loc) + + def remove_objectstore(): + if os.path.exists(self.objectstore_loc): + os.unlink(self.objectstore_loc) + cherrypy.engine.subscribe('exit', remove_objectstore) else: self.model = kimchiModel.Model() + ws_proxy = websocket.new_ws_proxy() + cherrypy.engine.subscribe('exit', ws_proxy.terminate) dev_env = wok_options.environment != 'production' super(Kimchi, self).__init__(self.model, dev_env) @@ -XXX,XX +XXX,XX @@ class Kimchi(WokRoot): for ident, node in sub_nodes.items(): setattr(self, ident, node(self.model)) - if isinstance(self.model, kimchiModel.Model): - ws_proxy = websocket.new_ws_proxy() - cherrypy.engine.subscribe('exit', ws_proxy.terminate) - self.api_schema = json.load(open(os.path.join(os.path.dirname( os.path.abspath(__file__)), 'API.json'))) self.paths = config.kimchiPaths -- 2.9.3 _______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
The model instance will be gotten from cherrypy when needed. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- tests/test_authorization.py | 10 ++++------ tests/test_host.py | 15 +++------------ tests/test_livemigration.py | 6 +----- tests/test_mock_network.py | 10 ++++------ tests/test_mock_storagepool.py | 12 ++++-------- tests/test_mock_storagevolume.py | 11 ++++------- tests/test_mockmodel.py | 8 +++----- tests/test_model_network.py | 18 +++++++++++------- tests/test_model_storagepool.py | 18 ++++++++++-------- tests/test_model_storagevolume.py | 18 +++++++++++------- tests/test_rest.py | 7 +++---- tests/test_template.py | 9 ++++----- 12 files changed, 62 insertions(+), 80 deletions(-) diff --git a/tests/test_authorization.py b/tests/test_authorization.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_authorization.py +++ b/tests/test_authorization.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2014-2016 +# Copyright IBM Corp, 2014-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json import os import unittest @@ -XXX,XX +XXX,XX @@ from functools import partial from tests.utils import get_fake_user, patch_auth from tests.utils import request, run_server, wait_task -from wok.plugins.kimchi import mockmodel - from iso_gen import construct_fake_iso @@ -XXX,XX +XXX,XX @@ def setUpModule(): global test_server, model patch_auth(sudo=False) - model = mockmodel.MockModel('/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model # Create fake ISO to do the tests construct_fake_iso(fake_iso, True, '12.04', 'ubuntu') @@ -XXX,XX +XXX,XX @@ def setUpModule(): def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') os.unlink(fake_iso) diff --git a/tests/test_host.py b/tests/test_host.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_host.py +++ b/tests/test_host.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import json -import os -import tempfile import unittest from functools import partial from tests.utils import patch_auth, request, run_server -from wok.plugins.kimchi.mockmodel import MockModel - test_server = None -model = None -tmpfile = None def setUpModule(): - global test_server, model, tmpfile + global test_server patch_auth() - tmpfile = tempfile.mktemp() - model = MockModel(tmpfile) - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) def tearDownModule(): test_server.stop() - os.unlink(tmpfile) class HostTests(unittest.TestCase): diff --git a/tests/test_livemigration.py b/tests/test_livemigration.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_livemigration.py +++ b/tests/test_livemigration.py @@ -XXX,XX +XXX,XX @@ class LiveMigrationTests(unittest.TestCase): 'not possible to test a live migration') def test_vm_livemigrate_persistent_API(self): patch_auth() - - inst = model.Model(libvirt_uri='qemu:///system', - objstore_loc=self.tmp_store) - with RollbackContext() as rollback: - test_server = run_server(test_mode=True, model=inst) + test_server = run_server() rollback.prependDefer(test_server.stop) self.request = partial(request) diff --git a/tests/test_mock_network.py b/tests/test_mock_network.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_mock_network.py +++ b/tests/test_mock_network.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json -import os import unittest from functools import partial from tests.utils import patch_auth, request, run_server -from wok.plugins.kimchi.mockmodel import MockModel from wok.plugins.kimchi.model.featuretests import FeatureTests from test_model_network import _do_network_test @@ -XXX,XX +XXX,XX @@ def setUpModule(): global test_server, model patch_auth() - model = MockModel('/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') class MockNetworkTests(unittest.TestCase): diff --git a/tests/test_mock_storagepool.py b/tests/test_mock_storagepool.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_mock_storagepool.py +++ b/tests/test_mock_storagepool.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json -import os import unittest from functools import partial from tests.utils import patch_auth, request, run_server -from wok.plugins.kimchi.mockmodel import MockModel - - model = None test_server = None @@ -XXX,XX +XXX,XX @@ def setUpModule(): global test_server, model patch_auth() - model = MockModel('/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') class MockStoragepoolTests(unittest.TestCase): diff --git a/tests/test_mock_storagevolume.py b/tests/test_mock_storagevolume.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_mock_storagevolume.py +++ b/tests/test_mock_storagevolume.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json -import os import unittest from functools import partial from tests.utils import patch_auth, request, run_server -from wok.plugins.kimchi.mockmodel import MockModel - from test_model_storagevolume import _do_volume_test @@ -XXX,XX +XXX,XX @@ def setUpModule(): global test_server, model patch_auth() - model = MockModel('/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') class MockStorageVolumeTests(unittest.TestCase): diff --git a/tests/test_mockmodel.py b/tests/test_mockmodel.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_mockmodel.py +++ b/tests/test_mockmodel.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2013-2016 +# Copyright IBM Corp, 2013-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ from tests.utils import patch_auth, request, run_server from tests.utils import wait_task from wok.exception import InvalidOperation -from wok.plugins.kimchi import mockmodel from wok.plugins.kimchi.osinfo import get_template_default import iso_gen @@ -XXX,XX +XXX,XX @@ fake_iso = None def setUpModule(): global model, test_server, fake_iso cherrypy.request.headers = {'Accept': 'application/json'} - model = mockmodel.MockModel('/tmp/obj-store-test') patch_auth() - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model fake_iso = '/tmp/fake.iso' iso_gen.construct_fake_iso(fake_iso, True, '12.04', 'ubuntu') def tearDown(): test_server.stop() - os.unlink('/tmp/obj-store-test') os.unlink(fake_iso) diff --git a/tests/test_model_network.py b/tests/test_model_network.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_model_network.py +++ b/tests/test_model_network.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json +import mock import os +import tempfile import unittest from functools import partial @@ -XXX,XX +XXX,XX @@ from tests.utils import run_server from wok.rollbackcontext import RollbackContext -from wok.plugins.kimchi.model.model import Model from wok.plugins.kimchi.model.featuretests import FeatureTests - model = None +objectstore_loc = tempfile.mktemp() test_server = None -def setUpModule(): +@mock.patch('wok.plugins.kimchi.config.get_object_store') +def setUpModule(func): + func.return_value = objectstore_loc global test_server, model patch_auth() - model = Model(None, '/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=False) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') + os.unlink(objectstore_loc) def _do_network_test(self, model, params): diff --git a/tests/test_model_storagepool.py b/tests/test_model_storagepool.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_model_storagepool.py +++ b/tests/test_model_storagepool.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json +import mock import os import shutil import tempfile @@ -XXX,XX +XXX,XX @@ from functools import partial from wok.rollbackcontext import RollbackContext -from wok.plugins.kimchi.model.model import Model - from tests.utils import patch_auth, request from tests.utils import run_server - model = None +objectstore_loc = tempfile.mktemp() test_server = None -def setUpModule(): +@mock.patch('wok.plugins.kimchi.config.get_object_store') +def setUpModule(func): + func.return_value = objectstore_loc global test_server, model patch_auth() - model = Model(None, '/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=False) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') + os.unlink(objectstore_loc) class StoragepoolTests(unittest.TestCase): diff --git a/tests/test_model_storagevolume.py b/tests/test_model_storagevolume.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_model_storagevolume.py +++ b/tests/test_model_storagevolume.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json +import mock import os import requests +import tempfile import unittest from functools import partial @@ -XXX,XX +XXX,XX @@ from wok.config import paths from wok.rollbackcontext import RollbackContext from wok.plugins.kimchi.config import READONLY_POOL_TYPE -from wok.plugins.kimchi.model.model import Model - model = None +objectstore_loc = tempfile.mktemp() test_server = None -def setUpModule(): +@mock.patch('wok.plugins.kimchi.config.get_object_store') +def setUpModule(func): + func.return_value = objectstore_loc global test_server, model patch_auth() - model = Model(None, '/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=False) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') + os.unlink(objectstore_loc) def _do_volume_test(self, model, pool_name): diff --git a/tests/test_rest.py b/tests/test_rest.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import json import os import re @@ -XXX,XX +XXX,XX @@ from tests.utils import patch_auth, request, run_server, wait_task from wok.asynctask import AsyncTask from wok.rollbackcontext import RollbackContext -from wok.plugins.kimchi import mockmodel from wok.plugins.kimchi.osinfo import get_template_default import iso_gen @@ -XXX,XX +XXX,XX @@ def setUpModule(): global test_server, model patch_auth() - model = mockmodel.MockModel('/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model # Create fake ISO to do the tests iso_gen.construct_fake_iso(fake_iso, True, '12.04', 'ubuntu') @@ -XXX,XX +XXX,XX @@ def setUpModule(): def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') os.unlink(fake_iso) os.unlink("/var/lib/libvirt/images/fedora.iso") diff --git a/tests/test_template.py b/tests/test_template.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ # 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 cherrypy import iso_gen import json import os @@ -XXX,XX +XXX,XX @@ from functools import partial from tests.utils import patch_auth, request, run_server from wok.plugins.kimchi.config import READONLY_POOL_TYPE -from wok.plugins.kimchi.mockmodel import MockModel from wok.plugins.kimchi.model.featuretests import FeatureTests from wok.plugins.kimchi.model.templates import MAX_MEM_LIM @@ -XXX,XX +XXX,XX @@ def setUpModule(): global test_server, model patch_auth() - model = MockModel('/tmp/obj-store-test') - test_server = run_server(test_mode=True, model=model) + test_server = run_server(test_mode=True) + model = cherrypy.tree.apps['/plugins/kimchi'].root.model iso_gen.construct_fake_iso(MOCK_ISO, True, '14.04', 'ubuntu') def tearDownModule(): test_server.stop() - os.unlink('/tmp/obj-store-test') class TemplateTests(unittest.TestCase): -- 2.9.3 _______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
The test case was failing as below: ====================================================================== ERROR: test_vm_virtviewerfile_vmlifecycle (test_model.ModelTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched return func(*args, **keywargs) File "test_model.py", line 571, in test_vm_virtviewerfile_vmlifecycle vvmodel.lookup(vm_name.decode('utf-8')) File "/home/alinefm/wok/src/wok/plugins/kimchi/model/virtviewerfile.py", line 133, in lookup file_path = create_virt_viewer_file(name, graphics_info) File "/home/alinefm/wok/src/wok/plugins/kimchi/model/virtviewerfile.py", line 82, in create_virt_viewer_file {'name': vm_name, 'err': e.message}) OperationFailed: KCHVM0084E: KCHVM0084E Because the virt-viewer config file generation was relying on Wok configuration to get the host information but the host information is not part of Wok anymore. Instead of that, it is being configured on nginx. Set it to 'localhost' when that information is not part of request headers. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- model/virtviewerfile.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/model/virtviewerfile.py b/model/virtviewerfile.py index XXXXXXX..XXXXXXX 100644 --- a/model/virtviewerfile.py +++ b/model/virtviewerfile.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2016 +# Copyright IBM Corp, 2016-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ import cherrypy import libvirt import os -from wok.config import config as wok_config from wok.exception import InvalidOperation, OperationFailed from wok.plugins.kimchi import config as kimchi_config from wok.plugins.kimchi.model.vms import VMModel @@ -XXX,XX +XXX,XX @@ port=%(graphics_port)s def _get_request_host(): - host = cherrypy.request.headers.get('Host') - if not host: - host = wok_config.get("server", "host") + host = cherrypy.request.headers.get('Host', 'localhost') host = host.split(':')[0] return host @@ -XXX,XX +XXX,XX @@ class VMVirtViewerFileModel(object): vm_name = dom.name() self.firewall_mngr.remove_vm_graphics_port(vm_name) cb_id = self.vm_event_callbacks.pop(vm_name, None) - self.conn.get().domainEventDeregisterAny(cb_id) + if cb_id is not None: + self.conn.get().domainEventDeregisterAny(cb_id) def handleVMShutdownPowerOff(self, vm_name): try: -- 2.9.3 _______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
Commit a2063007 has added a new test to validate snapshot on running guest but it has not considered the whole test case in count and it was failing as below: ====================================================================== FAIL: test_vm_lifecycle (test_model.ModelTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "test_model.py", line 218, in test_vm_lifecycle self.assertEquals({}, empty_snap) AssertionError: {} != {'state': u'running', 'name': u'1486470484', 'parent': u'', 'created': u'1486470 [truncated]... - {} + {'created': u'1486470484', + 'name': u'1486470484', + 'parent': u'', + 'state': u'running'} So fix it. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- tests/test_model.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/test_model.py b/tests/test_model.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -XXX,XX +XXX,XX @@ class ModelTests(unittest.TestCase): inst.task_wait(task['id']) task = inst.task_lookup(task['id']) self.assertEquals('finished', task['status']) + snap_name = task['target_uri'].split('/')[-1] + created_snaps = [snap_name] inst.vm_poweroff(u'kimchi-vm') vm = inst.vm_lookup(u'kimchi-vm') - empty_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm') - self.assertEquals({}, empty_snap) + current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm') + self.assertEquals(created_snaps[0], current_snap['name']) # this snapshot should be deleted when its VM is deleted params = {'name': u'mysnap'} @@ -XXX,XX +XXX,XX @@ class ModelTests(unittest.TestCase): inst.task_wait(task['id']) task = inst.task_lookup(task['id']) self.assertEquals('finished', task['status']) + created_snaps.append(params['name']) self.assertRaises(NotFoundError, inst.vmsnapshot_lookup, u'kimchi-vm', u'foobar') @@ -XXX,XX +XXX,XX @@ class ModelTests(unittest.TestCase): self.assertTrue(int(time.time()) >= int(snap['created'])) self.assertEquals(vm['state'], snap['state']) self.assertEquals(params['name'], snap['name']) - self.assertEquals(u'', snap['parent']) + self.assertEquals(created_snaps[0], snap['parent']) snaps = inst.vmsnapshots_get_list(u'kimchi-vm') - self.assertEquals([params['name']], snaps) + self.assertEquals(created_snaps, snaps) current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm') self.assertEquals(snap, current_snap) @@ -XXX,XX +XXX,XX @@ class ModelTests(unittest.TestCase): inst.task_wait(task['id']) task = inst.task_lookup(task['id']) self.assertEquals('finished', task['status']) + created_snaps.append(snap_name) snaps = inst.vmsnapshots_get_list(u'kimchi-vm') - self.assertEquals(sorted([params['name'], snap_name], - key=unicode.lower), snaps) + self.assertEquals(sorted(created_snaps, key=unicode.lower), snaps) snap = inst.vmsnapshot_lookup(u'kimchi-vm', snap_name) current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm') -- 2.9.3 _______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
The memory hotplug support depends on libvirt and qemu support. The libvirt test driver does not support this type of configuration so update the test case to verify the system has its support or not. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- tests/test_rest.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/tests/test_rest.py b/tests/test_rest.py index XXXXXXX..XXXXXXX 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -XXX,XX +XXX,XX @@ class RestTests(unittest.TestCase): resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') self.assertEquals(400, resp.status) - if not os.uname()[4] == "s390x": + # Check if there is support to memory hotplug + resp = self.request('/plugins/kimchi/config/capabilities').read() + conf = json.loads(resp) + if os.uname()[4] != "s390x" and conf['mem_hotplug_support']: req = json.dumps({'memory': {'maxmemory': 3072}}) resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') self.assertEquals(200, resp.status) @@ -XXX,XX +XXX,XX @@ class RestTests(unittest.TestCase): resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') self.assertEquals(400, resp.status) - # Check if there is support to memory hotplug, once vm is running - resp = self.request('/plugins/kimchi/config/capabilities').read() - conf = json.loads(resp) + # Test memory hotplug req = json.dumps({'memory': {'current': 2048}}) resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') if conf['mem_hotplug_support']: @@ -XXX,XX +XXX,XX @@ class RestTests(unittest.TestCase): vm = json.loads( self.request('/plugins/kimchi/vms/vm-1', req).read() ) + + # The maxmemory will be automatically increased when the amount of + # memory value is greater than the current maxmemory value params = {'name': u'∨м-црdαtеd', 'cpu_info': {'vcpus': 5}, 'memory': {'current': 3072}} req = json.dumps(params) @@ -XXX,XX +XXX,XX @@ class RestTests(unittest.TestCase): # Memory was hot plugged vm['name'] = u'∨м-црdαtеd' vm['cpu_info'].update(params['cpu_info']) - if not os.uname()[4] == "s390x": - vm['memory'].update(params['memory']) - else: - vm['memory']['current'] = 3072 - vm['memory']['maxmemory'] = 3072 + vm['memory']['current'] = 3072 + vm['memory']['maxmemory'] = 3072 + for key in params.keys(): self.assertEquals(vm[key], vm_updated[key]) -- 2.9.3 _______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
The function get_vms_attach_to_a_network() to identify which virtual machines are using a given network was being called multiple times without need. So improve the logic. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- i18n.py | 4 ++-- model/networks.py | 42 ++++++++++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/i18n.py b/i18n.py index XXXXXXX..XXXXXXX 100644 --- a/i18n.py +++ b/i18n.py @@ -XXX,XX +XXX,XX @@ messages = { "KCHNET0014E": _("Network interfaces must be an array."), "KCHNET0015E": _("Network VLAN ID must be an integer between 1 and 4094"), "KCHNET0016E": _("Specify name and type to create a Network"), - "KCHNET0017E": _("Unable to delete or update network %(name)s. There are some virtual machines %(vms)s and/or templates linked to this network."), - "KCHNET0018E": _("Unable to deactivate network %(name)s. There are some virtual machines %(vms)s and/or templates linked to this network."), + "KCHNET0017E": _("Unable to delete or update network %(name)s as it is linked to some virtual machines (%(vms)s) and/or templates (%(tmpls)s)."), + "KCHNET0018E": _("Unable to deactivate network %(name)s as it is linked to are some virtual machines (%(vms)s) and/or templates (%(tmpls)s)."), "KCHNET0019E": _("Bridge device %(name)s can not be the trunk device of a VLAN."), "KCHNET0020E": _("Failed to activate interface %(iface)s: %(err)s."), "KCHNET0021E": _("Failed to activate interface %(iface)s. Please check the physical link status."), diff --git a/model/networks.py b/model/networks.py index XXXXXXX..XXXXXXX 100644 --- a/model/networks.py +++ b/model/networks.py @@ -XXX,XX +XXX,XX @@ # # Project Kimchi # -# Copyright IBM Corp, 2015-2016 +# Copyright IBM Corp, 2015-2017 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -XXX,XX +XXX,XX @@ class NetworkModel(object): else: interfaces = [interface] + network_in_use, used_by_vms, _ = self._is_network_in_use(name) + return {'connection': connection, 'interfaces': interfaces, 'subnet': subnet, 'dhcp': dhcp, - 'vms': self._get_vms_attach_to_a_network(name), - 'in_use': self._is_network_in_use(name), + 'vms': used_by_vms, + 'in_use': network_in_use, 'autostart': network.autostart() == 1, 'state': network.isActive() and "active" or "inactive", 'persistent': True if network.isPersistent() else False} @@ -XXX,XX +XXX,XX @@ class NetworkModel(object): # All the networks listed as default in template.conf file should not # be deactivate or deleted. Otherwise, we will allow user create # inconsistent templates from scratch + vms = self._get_vms_attach_to_a_network(name) + tmpls = self._is_network_used_by_template(name) + if name in tmpl_defaults['networks']: - return True + return (True, vms, tmpls) - vms = self._get_vms_attach_to_a_network(name) - return bool(vms) or self._is_network_used_by_template(name) + return (bool(vms) or bool(tmpls), vms, tmpls) def _is_network_used_by_template(self, network): + tmpl_list = [] + with self.objstore as session: templates = session.get_list('template') for tmpl in templates: tmpl_net = session.get('template', tmpl)['networks'] if network in tmpl_net: - return True - return False + tmpl_list.append(tmpl) + return tmpl_list def _get_vms_attach_to_a_network(self, network, filter="all"): DOM_STATE_MAP = {'nostate': 0, 'running': 1, 'blocked': 2, @@ -XXX,XX +XXX,XX @@ class NetworkModel(object): 'err': e.message}) def deactivate(self, name): - if self._is_network_in_use(name): - vms = self._get_vms_attach_to_a_network(name) - vms.sort() + in_use, used_by_vms, used_by_tmpls = self._is_network_in_use(name) + vms = 'N/A' if len(used_by_vms) == 0 else ', '.join(used_by_vms) + tmpls = 'N/A' if len(used_by_tmpls) == 0 else ', '.join(used_by_tmpls) + if in_use: raise InvalidOperation("KCHNET0018E", {'name': name, - 'vms': ', '.join(vms)}) + 'vms': vms, + 'tmpls': tmpls}) network = self.get_network(self.conn.get(), name) network.destroy() def delete(self, name): - if self._is_network_in_use(name): - vms = self._get_vms_attach_to_a_network(name) - vms.sort() + in_use, used_by_vms, used_by_tmpls = self._is_network_in_use(name) + vms = 'N/A' if len(used_by_vms) == 0 else ', '.join(used_by_vms) + tmpls = 'N/A' if len(used_by_tmpls) == 0 else ', '.join(used_by_tmpls) + if in_use: raise InvalidOperation("KCHNET0017E", {'name': name, - 'vms': ', '.join(vms)}) + 'vms': vms, + 'tmpls': tmpls}) network = self.get_network(self.conn.get(), name) if network.isActive(): -- 2.9.3 _______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel