diff --git a/tests/unit/test_api.py b/tests/unit/test_api.py index 4d9f2f1c..bf778a87 100644 --- a/tests/unit/test_api.py +++ b/tests/unit/test_api.py @@ -65,8 +65,7 @@ def test_api_sessions(self): self.assertEqual(self.platform, session.platform) self.assertEqual(200, body['metacode']) - with patch('vmpool.endpoint.delete_vm', new=Mock()): - session.failed() + session.failed() def test_api_platforms(self): response = self.vmmaster_client.get('/api/platforms') @@ -92,8 +91,7 @@ def test_api_stop_session(self): body = json.loads(response.data) self.assertEqual(200, body['metacode']) - with patch('vmpool.endpoint.delete_vm', new=Mock()): - session.failed.assert_any_call() + session.failed.assert_any_call() @patch('core.db.database', Mock()) def test_get_screenshots(self): @@ -235,3 +233,68 @@ def test_get_vnc_info_if_session_not_found(self): vnc_proxy_port = body['result'] self.assertDictEqual({}, vnc_proxy_port) self.assertEqual(500, body['metacode']) + + + @patch('core.db.database', Mock()) + def test_api_success_delete_endpoint(self): + vm_for_delete = Mock(name='test_vm_1', delete=Mock()) + success_answer = "Endpoint %s was deleted" % vm_for_delete.name + + with patch( + 'vmpool.virtual_machines_pool.pool.get_by_name', + Mock(return_value=vm_for_delete) + ): + response = self.vmmaster_client.delete("/api/pool/%s" + % vm_for_delete.name) + + body = json.loads(response.data) + self.assertEqual(200, body['metacode']) + self.assertEqual(success_answer, body['result']) + + + @patch('core.db.database', Mock()) + def test_api_failed_delete_endpoint(self): + error = 'Failed' + vm_for_delete = Mock(name='test_vm_1', delete=Mock(side_effect=Exception(error))) + failed_answer = 'Got error during deleting vm %s. ' \ + '\n\n %s' % (vm_for_delete.name, error) + + with patch( + 'vmpool.virtual_machines_pool.pool.get_by_name', + Mock(return_value=vm_for_delete) + ): + response = self.vmmaster_client.delete("/api/pool/%s" + % vm_for_delete.name) + + body = json.loads(response.data) + self.assertEqual(200, body['metacode']) + self.assertEqual(failed_answer, body['result']) + + @patch('core.db.database', Mock()) + def test_api_success_and_failed_delete_all_endpoints(self): + vm_name_1 = "test_vm_1" + class VM(): + def __repr__(self): + return "test_vm_1" + + def __init__(self, name): + self.name = name + + def delete(self): pass + + fake_pool = [ + VM(vm_name_1), + Mock(name='test_vm_2', delete=Mock(side_effect=Exception)) + ] + + with patch( + 'vmpool.virtual_machines_pool.pool.pool', fake_pool + ), patch( + 'vmpool.virtual_machines_pool.pool.using', [] + ): + response = self.vmmaster_client.delete("/api/pool") + + body = json.loads(response.data) + self.assertEqual(200, body['metacode']) + self.assertEqual("This endpoints were deleted from pool: " + "[%s]" % vm_name_1, body['result']) diff --git a/tests/unit/test_commands.py b/tests/unit/test_commands.py index 6707c209..1fa35c61 100644 --- a/tests/unit/test_commands.py +++ b/tests/unit/test_commands.py @@ -87,8 +87,6 @@ def tearDown(self): 'flask.current_app.sessions', Mock() ), patch( 'flask.current_app.database', Mock() - ), patch( - 'vmpool.endpoint.delete_vm', Mock() ): self.session.delete() self.ctx.pop() diff --git a/tests/unit/test_vnc_recorder.py b/tests/unit/test_vnc_recorder.py index 0273dfb8..1cb3cd15 100644 --- a/tests/unit/test_vnc_recorder.py +++ b/tests/unit/test_vnc_recorder.py @@ -51,8 +51,6 @@ def test_run_recorder(self): "core.connection.Virsh", Mock() ), patch( 'core.db.database', DatabaseMock() - ), patch( - 'vmpool.endpoint.delete_vm', Mock() ): from core.sessions import Session self.session = Session(dc=dc) diff --git a/vmmaster/api/__init__.py b/vmmaster/api/__init__.py index c98b97e1..5b6c58bb 100644 --- a/vmmaster/api/__init__.py +++ b/vmmaster/api/__init__.py @@ -4,6 +4,8 @@ import helpers from flask import Blueprint, jsonify, request + +from core.logger import log from vmpool.api import helpers as vmpool_helpers from core.auth.api_auth import auth from core.config import config @@ -150,3 +152,40 @@ def get_vnc_info(session_id): ) return render_json(result=result, code=code) + + +@api.route('/pool/', methods=['DELETE']) +def delete_vm_from_pool(endpoint_name): + from vmpool.virtual_machines_pool import pool + result = "Endpoint %s not found in pool" % endpoint_name + + endpoint = pool.get_by_name(endpoint_name) + + if endpoint: + try: + endpoint.delete() + result = "Endpoint %s was deleted" % endpoint_name + except Exception, e: + log.info("Cannot delete vm %s through api method" % endpoint.name) + result = "Got error during deleting vm %s. " \ + "\n\n %s" % (endpoint_name, e.message) + + return render_json(result=result, code=200) + + +@api.route('/pool', methods=['DELETE']) +def delete_all_vm_from_pool(): + from vmpool.virtual_machines_pool import pool + results = [] + failed = [] + + for endpoint in pool.pool + pool.using: + try: + endpoint.delete() + results.append(endpoint) + except: + log.info("Cannot delete vm %s through api method" % endpoint.name) + failed.append(endpoint) + + return render_json(result="This endpoints were deleted from " + "pool: %s" % results, code=200) diff --git a/vmpool/endpoint.py b/vmpool/endpoint.py index 4ba796a5..73b05fe4 100644 --- a/vmpool/endpoint.py +++ b/vmpool/endpoint.py @@ -3,23 +3,13 @@ from core.utils import generator_wait_for from core.logger import log_pool from core.config import config -from core.exceptions import PlatformException, NoSuchEndpoint, \ +from core.exceptions import PlatformException, \ CreationException -from vmpool.virtual_machines_pool import pool from vmpool.platforms import Platforms from vmpool.vmqueue import q -def get_vm_from_pool(endpoint_name): - vm = pool.get_by_name(endpoint_name) - if vm: - log_pool.debug('Got vm with params: %s' % vm.info) - return vm - else: - raise NoSuchEndpoint('No such endpoint: %s' % endpoint_name) - - def new_vm(desired_caps): platform = desired_caps.get("platform", None) @@ -71,17 +61,3 @@ def new_vm(desired_caps): log_pool.info('Got vm for request with params: %s' % delayed_vm.vm.info) yield delayed_vm.vm - -def delete_vm(endpoint_name): - vm = pool.get_by_name(endpoint_name) - if vm: - if vm.is_preloaded(): - vm.rebuild() - else: - vm.delete() - - msg = "Vm %s has been deleted" % endpoint_name - log_pool.info(msg) - else: - msg = "Vm %s not found in pool or vm is busy" % endpoint_name - log_pool.info(msg) diff --git a/vmpool/virtual_machines_pool.py b/vmpool/virtual_machines_pool.py index 2b6ea0b6..51e54b9d 100644 --- a/vmpool/virtual_machines_pool.py +++ b/vmpool/virtual_machines_pool.py @@ -97,7 +97,7 @@ def get_by_name(cls, _name=None): if _name: log_pool.debug('Getting VM: %s' % _name) for vm in cls.pool + cls.using: - if vm.ready and vm.name == _name: + if vm.name == _name: return vm @classmethod