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):