Refactors code in OpenStack plugin
[osm/MON.git] / osm_mon / test / OpenStack / unit / test_metric_calls.py
1 # Copyright 2017 iIntel Research and Development Ireland Limited
2 # *************************************************************
3
4 # This file is part of OSM Monitoring module
5 # All Rights Reserved to Intel Corporation
6
7 # Licensed under the Apache License, Version 2.0 (the "License"); you may
8 # not use this file except in compliance with the License. You may obtain
9 # a copy of the License at
10
11 # http://www.apache.org/licenses/LICENSE-2.0
12
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16 # License for the specific language governing permissions and limitations
17 # under the License.
18
19 # For those usages not covered by the Apache License, Version 2.0 please
20 # contact: helena.mcgough@intel.com or adrian.hoban@intel.com
21 ##
22 """Tests for all metric request message keys."""
23
24 import json
25
26 import logging
27
28 import unittest
29
30 import mock
31
32 from osm_mon.core.auth import AuthManager
33 from osm_mon.plugins.OpenStack.Gnocchi import metrics as metric_req
34
35 from osm_mon.plugins.OpenStack.common import Common
36
37 log = logging.getLogger(__name__)
38
39 # Mock auth_token and endpoint
40 endpoint = mock.ANY
41 auth_token = mock.ANY
42
43 # Mock a valid metric list for some tests, and a resultant list
44 metric_list = [{"name": "disk.write.requests",
45 "id": "metric_id",
46 "unit": "units",
47 "resource_id": "r_id"}]
48 result_list = ["metric_id", "r_id", "units", "disk_write_ops"]
49
50
51 class Response(object):
52 """Mock a response object for requests."""
53
54 def __init__(self):
55 """Initialise test and status code values."""
56 self.text = json.dumps([{"id": "test_id"}])
57 self.status_code = "STATUS_CODE"
58
59
60 def perform_request_side_effect(*args, **kwargs):
61 resp = Response()
62 if 'marker' in args[0]:
63 resp.text = json.dumps([])
64 if 'resource/generic' in args[0]:
65 resp.text = json.dumps({'metrics': {'cpu_util': 'test_id'}})
66 return resp
67
68
69 class TestMetricCalls(unittest.TestCase):
70 """Integration test for metric request keys."""
71
72 def setUp(self):
73 """Setup the tests for metric request keys."""
74 super(TestMetricCalls, self).setUp()
75 self.metrics = metric_req.Metrics()
76 self.metrics._common = Common()
77
78 @mock.patch.object(metric_req.Metrics, "get_metric_id")
79 @mock.patch.object(Common, "perform_request")
80 def test_invalid_config_metric_req(
81 self, perf_req, get_metric):
82 """Test the configure metric function, for an invalid metric."""
83 # Test invalid configuration for creating a metric
84 values = {"metric_details": "invalid_metric"}
85
86 with self.assertRaises(ValueError):
87 self.metrics.configure_metric(endpoint, auth_token, values, verify_ssl=False)
88
89 perf_req.assert_not_called()
90
91 # Test with an invalid metric name, will not perform request
92 values = {"resource_uuid": "r_id"}
93
94 with self.assertRaises(ValueError):
95 self.metrics.configure_metric(endpoint, auth_token, values, verify_ssl=False)
96
97 perf_req.assert_not_called()
98
99 # If metric exists, it won't be recreated
100 get_metric.return_value = "metric_id"
101
102 with self.assertRaises(ValueError):
103 self.metrics.configure_metric(endpoint, auth_token, values, verify_ssl=False)
104
105 perf_req.assert_not_called()
106
107 @mock.patch.object(metric_req.Metrics, "get_metric_id")
108 @mock.patch.object(Common, "perform_request")
109 @mock.patch.object(AuthManager, "get_credentials")
110 def test_valid_config_metric_req(
111 self, get_creds, perf_req, get_metric):
112 """Test the configure metric function, for a valid metric."""
113 # Test valid configuration and payload for creating a metric
114 get_creds.return_value = type('obj', (object,), {'config': '{"insecure":true}'})
115 values = {"resource_uuid": "r_id",
116 "metric_unit": "units",
117 "metric_name": "cpu_util"}
118 get_metric.return_value = None
119 payload = {"id": "r_id",
120 "metrics": {"cpu_util":
121 {"archive_policy_name": "high",
122 "name": "cpu_util",
123 "unit": "units"}}}
124
125 perf_req.return_value = type('obj', (object,), {'text': '{"metrics":{"cpu_util":1}, "id":1}'})
126
127 self.metrics.configure_metric(endpoint, auth_token, values, verify_ssl=False)
128
129 perf_req.assert_called_with(
130 "<ANY>/v1/resource/generic", auth_token, req_type="post", verify_ssl=False,
131 payload=json.dumps(payload, sort_keys=True))
132
133 @mock.patch.object(Common, "perform_request")
134 def test_delete_metric_req(self, perf_req):
135 """Test the delete metric function."""
136 mock_response = Response()
137 mock_response.status_code = 200
138 perf_req.return_value = mock_response
139
140 self.metrics.delete_metric(endpoint, auth_token, "metric_id", verify_ssl=False)
141
142 perf_req.assert_called_with(
143 "<ANY>/v1/metric/metric_id", auth_token, req_type="delete", verify_ssl=False)
144
145 @mock.patch.object(Common, "perform_request")
146 def test_delete_metric_invalid_status(self, perf_req):
147 """Test invalid response for delete request."""
148 perf_req.return_value = type('obj', (object,), {"status_code": "404"})
149
150 with self.assertRaises(ValueError):
151 self.metrics.delete_metric(endpoint, auth_token, "metric_id", verify_ssl=False)
152
153 @mock.patch.object(metric_req.Metrics, "response_list")
154 @mock.patch.object(Common, "perform_request")
155 def test_complete_list_metric_req(self, perf_req, resp_list):
156 """Test the complete list metric function."""
157 # Test listing metrics without any configuration options
158 values = {}
159 perf_req.side_effect = perform_request_side_effect
160 self.metrics.list_metrics(endpoint, auth_token, values, verify_ssl=False)
161
162 perf_req.assert_any_call(
163 "<ANY>/v1/metric?sort=name:asc", auth_token, req_type="get", verify_ssl=False)
164 resp_list.assert_called_with([{u'id': u'test_id'}])
165
166 @mock.patch.object(metric_req.Metrics, "response_list")
167 @mock.patch.object(Common, "perform_request")
168 def test_resource_list_metric_req(self, perf_req, resp_list):
169 """Test the resource list metric function."""
170 # Test listing metrics with a resource id specified
171 values = {"resource_uuid": "resource_id"}
172 perf_req.side_effect = perform_request_side_effect
173 self.metrics.list_metrics(endpoint, auth_token, values, verify_ssl=False)
174
175 perf_req.assert_any_call(
176 "<ANY>/v1/metric/test_id", auth_token, req_type="get", verify_ssl=False)
177
178 @mock.patch.object(metric_req.Metrics, "response_list")
179 @mock.patch.object(Common, "perform_request")
180 def test_name_list_metric_req(self, perf_req, resp_list):
181 """Test the metric_name list metric function."""
182 # Test listing metrics with a metric_name specified
183 values = {"metric_name": "disk_write_bytes"}
184 perf_req.side_effect = perform_request_side_effect
185 self.metrics.list_metrics(endpoint, auth_token, values, verify_ssl=False)
186
187 perf_req.assert_any_call(
188 "<ANY>/v1/metric?sort=name:asc", auth_token, req_type="get", verify_ssl=False)
189 resp_list.assert_called_with(
190 [{u'id': u'test_id'}], metric_name="disk_write_bytes")
191
192 @mock.patch.object(metric_req.Metrics, "response_list")
193 @mock.patch.object(Common, "perform_request")
194 def test_combined_list_metric_req(self, perf_req, resp_list):
195 """Test the combined resource and metric list metric function."""
196 # Test listing metrics with a resource id and metric name specified
197
198 values = {"resource_uuid": "resource_id",
199 "metric_name": "cpu_utilization"}
200 perf_req.side_effect = perform_request_side_effect
201 self.metrics.list_metrics(endpoint, auth_token, values, verify_ssl=False)
202
203 perf_req.assert_any_call(
204 "<ANY>/v1/metric/test_id", auth_token, req_type="get", verify_ssl=False)
205
206 @mock.patch.object(Common, "perform_request")
207 def test_get_metric_id(self, perf_req):
208 """Test get_metric_id function."""
209 mock_response = Response()
210 mock_response.text = json.dumps({'metrics': {'my_metric': 'id'}})
211 perf_req.return_value = mock_response
212 self.metrics.get_metric_id(endpoint, auth_token, "my_metric", "r_id", verify_ssl=False)
213
214 perf_req.assert_called_with(
215 "<ANY>/v1/resource/generic/r_id", auth_token, req_type="get", verify_ssl=False)
216
217 @mock.patch.object(metric_req.Metrics, "get_metric_id")
218 @mock.patch.object(Common, "perform_request")
219 def test_valid_read_data_req(self, perf_req, get_metric):
220 """Test the read metric data function, for a valid call."""
221 values = {"metric_name": "disk_write_ops",
222 "resource_uuid": "resource_id",
223 "collection_unit": "DAY",
224 "collection_period": 1}
225
226 perf_req.return_value = type('obj', (object,), {'text': '{"metric_data":"[]"}'})
227
228 get_metric.return_value = "metric_id"
229 self.metrics.read_metric_data(endpoint, auth_token, values, verify_ssl=False)
230
231 perf_req.assert_called_once()
232
233 @mock.patch.object(Common, "perform_request")
234 def test_invalid_read_data_req(self, perf_req):
235 """Test the read metric data function for an invalid call."""
236 values = {}
237
238 with self.assertRaises(KeyError):
239 self.metrics.read_metric_data(endpoint, auth_token, values, verify_ssl=False)
240
241 def test_complete_response_list(self):
242 """Test the response list function for formatting metric lists."""
243 # Mock a list for testing purposes, with valid OSM metric
244 resp_list = self.metrics.response_list(metric_list)
245
246 # Check for the expected values in the resulting list
247 for l in result_list:
248 self.assertIn(l, resp_list[0].values())
249
250 def test_name_response_list(self):
251 """Test the response list with metric name configured."""
252 # Mock the metric name to test a metric name list
253 # Test with a name that is not in the list
254 invalid_name = "my_metric"
255 resp_list = self.metrics.response_list(
256 metric_list, metric_name=invalid_name)
257
258 self.assertEqual(resp_list, [])
259
260 # Test with a name on the list
261 valid_name = "disk_write_ops"
262 resp_list = self.metrics.response_list(
263 metric_list, metric_name=valid_name)
264
265 # Check for the expected values in the resulting list
266 for l in result_list:
267 self.assertIn(l, resp_list[0].values())
268
269 def test_resource_response_list(self):
270 """Test the response list with resource_id configured."""
271 # Mock a resource_id to test a resource list
272 # Test with resource not on the list
273 invalid_id = "mock_resource"
274 resp_list = self.metrics.response_list(metric_list, resource=invalid_id)
275
276 self.assertEqual(resp_list, [])
277
278 # Test with a resource on the list
279 valid_id = "r_id"
280 resp_list = self.metrics.response_list(metric_list, resource=valid_id)
281
282 # Check for the expected values in the resulting list
283 for l in result_list:
284 self.assertIn(l, resp_list[0].values())
285
286 def test_combined_response_list(self):
287 """Test the response list function with resource_id and metric_name."""
288 # Test for a combined resource and name list
289 # resource and name are on the list
290 valid_name = "disk_write_ops"
291 valid_id = "r_id"
292 resp_list = self.metrics.response_list(
293 metric_list, metric_name=valid_name, resource=valid_id)
294
295 # Check for the expected values in the resulting list
296 for l in result_list:
297 self.assertIn(l, resp_list[0].values())
298
299 # resource not on list
300 invalid_id = "mock_resource"
301 resp_list = self.metrics.response_list(
302 metric_list, metric_name=valid_name, resource=invalid_id)
303
304 self.assertEqual(resp_list, [])
305
306 # metric name not on list
307 invalid_name = "mock_metric"
308 resp_list = self.metrics.response_list(
309 metric_list, metric_name=invalid_name, resource=valid_id)
310
311 self.assertEqual(resp_list, [])