diff --git a/watcher/decision_engine/scope/baremetal.py b/watcher/decision_engine/scope/baremetal.py index 26c328ffd..d355dc60a 100644 --- a/watcher/decision_engine/scope/baremetal.py +++ b/watcher/decision_engine/scope/baremetal.py @@ -31,6 +31,8 @@ class BaremetalScope(base.BaseScope): for scope in self.scope: baremetal_scope = scope.get('baremetal') + if baremetal_scope: + break if not baremetal_scope: return cluster_model diff --git a/watcher/decision_engine/scope/compute.py b/watcher/decision_engine/scope/compute.py index 8348b1512..def63e877 100644 --- a/watcher/decision_engine/scope/compute.py +++ b/watcher/decision_engine/scope/compute.py @@ -175,6 +175,8 @@ class ComputeScope(base.BaseScope): for scope in self.scope: compute_scope = scope.get('compute') + if compute_scope: + break if not compute_scope: return cluster_model diff --git a/watcher/decision_engine/scope/storage.py b/watcher/decision_engine/scope/storage.py index 7a36694b5..7f9eb56b2 100644 --- a/watcher/decision_engine/scope/storage.py +++ b/watcher/decision_engine/scope/storage.py @@ -133,6 +133,8 @@ class StorageScope(base.BaseScope): for scope in self.scope: storage_scope = scope.get('storage') + if storage_scope: + break if not storage_scope: return cluster_model diff --git a/watcher/tests/decision_engine/scope/test_compute.py b/watcher/tests/decision_engine/scope/test_compute.py index 89b654355..41e91ea2a 100644 --- a/watcher/tests/decision_engine/scope/test_compute.py +++ b/watcher/tests/decision_engine/scope/test_compute.py @@ -294,3 +294,22 @@ class TestComputeScope(base.TestCase): model = compute.ComputeScope(audit_scope, mock.Mock(), osc=mock.Mock()).get_scoped_model(cluster) self.assertEqual(0, len(model.edges())) + + @mock.patch.object(nova_helper.NovaHelper, 'get_service_list') + def test_get_scoped_model_with_multi_scopes(self, mock_zone_list): + cluster = self.fake_cluster.generate_scenario_1() + # includes compute and storage scope + audit_scope = [] + audit_scope.extend(fake_scopes.fake_scope_1) + audit_scope.extend(fake_scopes.fake_scope_2) + mock_zone_list.return_value = [ + mock.Mock(zone='AZ{0}'.format(i), + host={'Node_{0}'.format(i): {}}) + for i in range(4)] + model = compute.ComputeScope(audit_scope, mock.Mock(), + osc=mock.Mock()).get_scoped_model(cluster) + + # NOTE(adisky):INSTANCE_6 is not excluded from model it will be tagged + # as 'exclude' TRUE, blueprint compute-cdm-include-all-instances + expected_edges = [('INSTANCE_2', 'Node_1'), (u'INSTANCE_6', u'Node_3')] + self.assertEqual(sorted(expected_edges), sorted(model.edges())) diff --git a/watcher/tests/decision_engine/scope/test_storage.py b/watcher/tests/decision_engine/scope/test_storage.py index 241e4e3d6..8b459acf1 100644 --- a/watcher/tests/decision_engine/scope/test_storage.py +++ b/watcher/tests/decision_engine/scope/test_storage.py @@ -192,3 +192,20 @@ class TestStorageScope(base.TestCase): nodes_to_remove, cluster) self.assertEqual(['host_1@backend_1'], list(cluster.get_all_storage_nodes())) + + @mock.patch.object(cinder_helper.CinderHelper, 'get_storage_node_list') + def test_get_scoped_model_with_multi_scopes(self, mock_zone_list): + cluster = self.fake_cluster.generate_scenario_1() + # includes storage and compute scope + audit_scope = [] + audit_scope.extend(fake_scopes.fake_scope_2) + audit_scope.extend(fake_scopes.fake_scope_1) + mock_zone_list.return_value = [ + mock.Mock(zone='zone_{0}'.format(i), + host='host_{0}@backend_{1}'.format(i, i)) + for i in range(2)] + model = storage.StorageScope(audit_scope, mock.Mock(), + osc=mock.Mock()).get_scoped_model(cluster) + expected_edges = [('VOLUME_0', 'host_0@backend_0#pool_0'), + ('host_0@backend_0#pool_0', 'host_0@backend_0')] + self.assertEqual(sorted(expected_edges), sorted(model.edges()))