Răsfoiți Sursa

Merged in bclaudiub/coriolis-core/bug-fixes-2 (pull request #86)

Bug fixes 2

Approved-by: Nashwan Azhari <nazhari@cloudbasesolutions.com>
Claudiu Belu 8 ani în urmă
părinte
comite
5f80dd0f27

+ 1 - 1
coriolis/conductor/rpc/server.py

@@ -314,7 +314,7 @@ class ConductorServerEndpoint(object):
 
         has_tasks = False
         for instance in replica.instances:
-            if (instance in replica.instances and
+            if (instance in replica.info and
                     "volumes_info" in replica.info[instance]):
                 self._create_task(
                     instance, constants.TASK_TYPE_DELETE_REPLICA_DISKS,

+ 2 - 0
coriolis/db/api.py

@@ -84,6 +84,8 @@ def add_endpoint(context, endpoint):
 @enginefacade.writer
 def update_endpoint(context, endpoint_id, updated_values):
     endpoint = get_endpoint(context, endpoint_id)
+    if not endpoint:
+        raise exception.NotFound("Endpoint not found")
     for n in ["name", "description", "connection_info"]:
         if n in updated_values:
             setattr(endpoint, n, updated_values[n])

+ 40 - 0
coriolis/tests/conductor/rpc/test_server.py

@@ -0,0 +1,40 @@
+# Copyright 2017 Cloudbase Solutions Srl
+# All Rights Reserved.
+
+import ddt
+import mock
+
+from coriolis.conductor.rpc import server
+from coriolis import exception
+from coriolis.tests import test_base
+
+
+@ddt.ddt
+class ConductorServerEndpointTestCase(test_base.CoriolisBaseTestCase):
+    """Test suite for the Coriolis Conductor RPC server."""
+
+    def setUp(self):
+        super(ConductorServerEndpointTestCase, self).setUp()
+        self.server = server.ConductorServerEndpoint()
+
+    @ddt.data({}, {mock.sentinel.instance: {}})
+    @mock.patch.object(server.ConductorServerEndpoint, '_create_task')
+    @mock.patch.object(server.ConductorServerEndpoint,
+                       '_check_replica_running_executions')
+    @mock.patch.object(server.ConductorServerEndpoint, '_get_replica')
+    def test_update_endpoint_not_found(self, replica_info, mock_get_replica,
+                                       mock_check_replica_running,
+                                       mock_create_task):
+        mock_replica = mock_get_replica.return_value
+        mock_replica.instances = [mock.sentinel.instance]
+        mock_replica.info = {}
+
+        self.assertRaises(exception.InvalidReplicaState,
+                          self.server.delete_replica_disks,
+                          mock.sentinel.context, mock.sentinel.replica_id)
+
+        mock_get_replica.assert_called_once_with(mock.sentinel.context,
+                                                 mock.sentinel.replica_id)
+        mock_check_replica_running.assert_called_once_with(
+            mock.sentinel.context, mock_replica)
+        mock_create_task.assert_not_called()

+ 51 - 0
coriolis/tests/db/test_api.py

@@ -0,0 +1,51 @@
+# Copyright 2017 Cloudbase Solutions Srl
+# All Rights Reserved.
+
+import mock
+
+from coriolis.db import api
+from coriolis import exception
+from coriolis.tests import test_base
+
+
+def get_wrapped_function(function):
+    """Get the method at the bottom of a stack of decorators."""
+    if not hasattr(function, '__closure__') or not function.__closure__:
+        return function
+
+    def _get_wrapped_function(function):
+        if not hasattr(function, '__closure__') or not function.__closure__:
+            return None
+
+        for closure in function.__closure__:
+            func = closure.cell_contents
+
+            deeper_func = _get_wrapped_function(func)
+            if deeper_func:
+                return deeper_func
+            elif hasattr(closure.cell_contents, '__call__'):
+                return closure.cell_contents
+
+        return function
+
+    return _get_wrapped_function(function)
+
+
+class DBAPITestCase(test_base.CoriolisBaseTestCase):
+    """Test suite for the Coriolis DB API."""
+
+    @mock.patch.object(api, 'get_endpoint')
+    def test_update_endpoint_not_found(self, mock_get_endpoint):
+        mock_get_endpoint.return_value = None
+
+        # We only need to test the unwrapped functions. Without this,
+        # when calling a coriolis.db.api function, it will try to
+        # establish an SQL connection.
+        update_endpoint = get_wrapped_function(api.update_endpoint)
+
+        self.assertRaises(exception.NotFound, update_endpoint,
+                          mock.sentinel.context, mock.sentinel.endpoint_id,
+                          mock.sentinel.updated_values)
+
+        mock_get_endpoint.assert_called_once_with(mock.sentinel.context,
+                                                  mock.sentinel.endpoint_id)

+ 1 - 0
test-requirements.txt

@@ -1,4 +1,5 @@
 coverage
+ddt
 discover
 oslotest