diff --git a/watcher/tests/api/v1/test_data_model.py b/watcher/tests/api/v1/test_data_model.py index 0fff21265..d6e59e490 100644 --- a/watcher/tests/api/v1/test_data_model.py +++ b/watcher/tests/api/v1/test_data_model.py @@ -18,8 +18,10 @@ from unittest import mock from http import HTTPStatus from oslo_serialization import jsonutils +from watcher.api.controllers.v1 import versions from watcher.decision_engine import rpcapi as deapi from watcher.tests.api import base as api_base +from watcher.tests.decision_engine.model import faker_cluster_state class TestListDataModel(api_base.FunctionalTest): @@ -46,6 +48,82 @@ class TestListDataModel(api_base.FunctionalTest): self.assertEqual(HTTPStatus.NOT_ACCEPTABLE, response.status_int) +class TestListDataModelResponse(api_base.FunctionalTest): + + NODE_FIELDS_1_3 = [ + 'node_disabled_reason', + 'node_hostname', + 'node_status', + 'node_state', + 'node_memory', + 'node_memory_mb_reserved', + 'node_disk', + 'node_disk_gb_reserved', + 'node_vcpus', + 'node_vcpu_reserved', + 'node_memory_ratio', + 'node_vcpu_ratio', + 'node_disk_ratio', + 'node_uuid' + ] + + SERVER_FIELDS_1_3 = [ + 'server_watcher_exclude', + 'server_name', + 'server_state', + 'server_memory', + 'server_disk', + 'server_vcpus', + 'server_metadata', + 'server_project_id', + 'server_locked', + 'server_uuid' + ] + + NODE_FIELDS_LATEST = NODE_FIELDS_1_3 + SERVER_FIELDS_LATEST = SERVER_FIELDS_1_3 + + def setUp(self): + super(TestListDataModelResponse, self).setUp() + p_dcapi = mock.patch.object(deapi, 'DecisionEngineAPI') + self.mock_dcapi = p_dcapi.start() + self.addCleanup(p_dcapi.stop) + + def test_model_list_compute_no_instance(self): + fake_cluster = faker_cluster_state.FakerModelCollector() + model = fake_cluster.generate_scenario_11_with_1_node_no_instance() + get_model_resp = {'context': model.to_list()} + + self.mock_dcapi().get_data_model_info.return_value = get_model_resp + infra_max_version = 'infra-optim ' + versions.max_version_string() + response = self.get_json( + '/data_model/?data_model_type=compute', + headers={'OpenStack-API-Version': infra_max_version}) + + server_info = response.get("context")[0] + expected_keys = self.NODE_FIELDS_LATEST + + self.assertEqual(len(response.get("context")), 1) + self.assertEqual(set(expected_keys), set(server_info.keys())) + + def test_model_list_compute_with_instances(self): + fake_cluster = faker_cluster_state.FakerModelCollector() + model = fake_cluster.generate_scenario_11_with_2_nodes_2_instances() + get_model_resp = {'context': model.to_list()} + + self.mock_dcapi().get_data_model_info.return_value = get_model_resp + infra_max_version = 'infra-optim ' + versions.max_version_string() + response = self.get_json( + '/data_model/?data_model_type=compute', + headers={'OpenStack-API-Version': infra_max_version}) + + server_info = response.get("context")[0] + expected_keys = self.NODE_FIELDS_LATEST + self.SERVER_FIELDS_LATEST + + self.assertEqual(len(response.get("context")), 2) + self.assertEqual(set(expected_keys), set(server_info.keys())) + + class TestDataModelPolicyEnforcement(api_base.FunctionalTest): def setUp(self): diff --git a/watcher/tests/decision_engine/model/data/scenario_11_with_1_node_no_instance.xml b/watcher/tests/decision_engine/model/data/scenario_11_with_1_node_no_instance.xml new file mode 100644 index 000000000..8be4a2c02 --- /dev/null +++ b/watcher/tests/decision_engine/model/data/scenario_11_with_1_node_no_instance.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/watcher/tests/decision_engine/model/data/scenario_11_with_2_nodes_2_instances.xml b/watcher/tests/decision_engine/model/data/scenario_11_with_2_nodes_2_instances.xml new file mode 100644 index 000000000..edcf2588e --- /dev/null +++ b/watcher/tests/decision_engine/model/data/scenario_11_with_2_nodes_2_instances.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/watcher/tests/decision_engine/model/faker_cluster_state.py b/watcher/tests/decision_engine/model/faker_cluster_state.py index f184ad6f4..26e1e3cb8 100644 --- a/watcher/tests/decision_engine/model/faker_cluster_state.py +++ b/watcher/tests/decision_engine/model/faker_cluster_state.py @@ -174,6 +174,12 @@ class FakerModelCollector(base.BaseClusterDataModelCollector): def generate_scenario_10(self): return self.load_model('scenario_10.xml') + def generate_scenario_11_with_1_node_no_instance(self): + return self.load_model('scenario_11_with_1_node_no_instance.xml') + + def generate_scenario_11_with_2_nodes_2_instances(self): + return self.load_model('scenario_11_with_2_nodes_2_instances.xml') + class FakerStorageModelCollector(base.BaseClusterDataModelCollector):