blob: 598ef2b51f09b68910356cc6b3894bacb910a3f8 [file] [log] [blame]
Helena McGoughfe92f842017-11-17 14:57:08 +00001# 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 alarm request message keys."""
23
24import json
Helena McGoughfe92f842017-11-17 14:57:08 +000025import logging
Helena McGoughfe92f842017-11-17 14:57:08 +000026import unittest
27
28import mock
29
Helena McGougheffeb7c2017-11-23 15:54:08 +000030from osm_mon.plugins.OpenStack.Aodh import alarming as alarm_req
31from osm_mon.plugins.OpenStack.common import Common
Benjamin Diaz181cce82018-03-28 21:12:11 -030032from osm_mon.plugins.OpenStack.settings import Config
Helena McGoughfe92f842017-11-17 14:57:08 +000033
34log = logging.getLogger(__name__)
35
36auth_token = mock.ANY
Benjamin Diaz181cce82018-03-28 21:12:11 -030037alarm_endpoint = "alarm_endpoint"
38metric_endpoint = "metric_endpoint"
Helena McGoughfe92f842017-11-17 14:57:08 +000039
40
41class Response(object):
42 """Mock a response message class."""
43
44 def __init__(self, result):
45 """Initialise the response text and status code."""
46 self.text = json.dumps(result)
47 self.status_code = "MOCK_STATUS_CODE"
48
49
50class TestAlarming(unittest.TestCase):
51 """Tests for alarming class functions."""
52
Helena McGough94f93f72017-11-23 17:29:54 +000053 maxDiff = None
54
Helena McGoughfe92f842017-11-17 14:57:08 +000055 def setUp(self):
56 """Setup for tests."""
57 super(TestAlarming, self).setUp()
58 self.alarming = alarm_req.Alarming()
Helena McGoughfe92f842017-11-17 14:57:08 +000059
60 @mock.patch.object(alarm_req.Alarming, "check_payload")
61 @mock.patch.object(alarm_req.Alarming, "check_for_metric")
Benjamin Diaz181cce82018-03-28 21:12:11 -030062 @mock.patch.object(Common, "perform_request")
Helena McGoughfe92f842017-11-17 14:57:08 +000063 def test_config_invalid_alarm_req(self, perf_req, check_metric, check_pay):
64 """Test configure an invalid alarm request."""
65 # Configuring with invalid alarm name results in failure
66 values = {"alarm_name": "my_alarm",
67 "metric_name": "my_metric",
68 "resource_uuid": "my_r_id"}
Benjamin Diaz181cce82018-03-28 21:12:11 -030069 self.alarming.configure_alarm(alarm_endpoint, metric_endpoint, auth_token, values)
70 perf_req.assert_not_called()
Helena McGoughfe92f842017-11-17 14:57:08 +000071 perf_req.reset_mock()
72
73 # Correct alarm_name will check for metric in Gnocchi
74 # If there isn't one an alarm won;t be created
75 values = {"alarm_name": "disk_write_ops",
76 "metric_name": "disk_write_ops",
77 "resource_uuid": "my_r_id"}
78
79 check_metric.return_value = None
80
Benjamin Diaz181cce82018-03-28 21:12:11 -030081 self.alarming.configure_alarm(alarm_endpoint, metric_endpoint, auth_token, values)
82 perf_req.assert_not_called()
Helena McGoughfe92f842017-11-17 14:57:08 +000083
84 @mock.patch.object(alarm_req.Alarming, "check_payload")
85 @mock.patch.object(alarm_req.Alarming, "check_for_metric")
Benjamin Diaz181cce82018-03-28 21:12:11 -030086 @mock.patch.object(Common, "perform_request")
Helena McGoughfe92f842017-11-17 14:57:08 +000087 def test_config_valid_alarm_req(self, perf_req, check_metric, check_pay):
88 """Test config a valid alarm."""
89 # Correct alarm_name will check for metric in Gnocchi
90 # And conform that the payload is configured correctly
91 values = {"alarm_name": "disk_write_ops",
92 "metric_name": "disk_write_ops",
93 "resource_uuid": "my_r_id"}
94
95 check_metric.return_value = "my_metric_id"
96 check_pay.return_value = "my_payload"
97
Benjamin Diaz181cce82018-03-28 21:12:11 -030098 self.alarming.configure_alarm(alarm_endpoint, metric_endpoint, auth_token, values)
Helena McGoughfe92f842017-11-17 14:57:08 +000099 perf_req.assert_called_with(
Benjamin Diaz181cce82018-03-28 21:12:11 -0300100 "alarm_endpoint/v2/alarms/", auth_token,
Helena McGoughfe92f842017-11-17 14:57:08 +0000101 req_type="post", payload="my_payload")
102
Benjamin Diaz181cce82018-03-28 21:12:11 -0300103 @mock.patch.object(Common, "perform_request")
Helena McGoughfe92f842017-11-17 14:57:08 +0000104 def test_delete_alarm_req(self, perf_req):
105 """Test delete alarm request."""
Benjamin Diaz181cce82018-03-28 21:12:11 -0300106 self.alarming.delete_alarm(alarm_endpoint, auth_token, "my_alarm_id")
Helena McGoughfe92f842017-11-17 14:57:08 +0000107
108 perf_req.assert_called_with(
Benjamin Diaz181cce82018-03-28 21:12:11 -0300109 "alarm_endpoint/v2/alarms/my_alarm_id", auth_token, req_type="delete")
Helena McGoughfe92f842017-11-17 14:57:08 +0000110
Benjamin Diaz181cce82018-03-28 21:12:11 -0300111 @mock.patch.object(Common, "perform_request")
Helena McGoughfe92f842017-11-17 14:57:08 +0000112 def test_invalid_list_alarm_req(self, perf_req):
113 """Test invalid list alarm_req."""
114 # Request will not be performed with out a resoure_id
115 list_details = {"mock_details": "invalid_details"}
Benjamin Diaz181cce82018-03-28 21:12:11 -0300116 self.alarming.list_alarms(alarm_endpoint, auth_token, list_details)
Helena McGoughfe92f842017-11-17 14:57:08 +0000117
Benjamin Diaz181cce82018-03-28 21:12:11 -0300118 perf_req.assert_not_called()
Helena McGoughfe92f842017-11-17 14:57:08 +0000119
Benjamin Diaz181cce82018-03-28 21:12:11 -0300120 @mock.patch.object(Common, "perform_request")
Helena McGoughfe92f842017-11-17 14:57:08 +0000121 def test_valid_list_alarm_req(self, perf_req):
122 """Test valid list alarm request."""
123 # Minimum requirement for an alarm list is resource_id
124 list_details = {"resource_uuid": "mock_r_id"}
Benjamin Diaz181cce82018-03-28 21:12:11 -0300125 self.alarming.list_alarms(alarm_endpoint, auth_token, list_details)
Helena McGoughfe92f842017-11-17 14:57:08 +0000126
127 perf_req.assert_called_with(
Benjamin Diaz181cce82018-03-28 21:12:11 -0300128 "alarm_endpoint/v2/alarms/", auth_token, req_type="get")
Helena McGoughfe92f842017-11-17 14:57:08 +0000129 perf_req.reset_mock()
130
131 # Check list with alarm_name defined
132 list_details = {"resource_uuid": "mock_r_id",
133 "alarm_name": "my_alarm",
134 "severity": "critical"}
Benjamin Diaz181cce82018-03-28 21:12:11 -0300135 self.alarming.list_alarms(alarm_endpoint, auth_token, list_details)
Helena McGoughfe92f842017-11-17 14:57:08 +0000136
137 perf_req.assert_called_with(
Benjamin Diaz181cce82018-03-28 21:12:11 -0300138 "alarm_endpoint/v2/alarms/", auth_token, req_type="get")
Helena McGoughfe92f842017-11-17 14:57:08 +0000139
Benjamin Diaz181cce82018-03-28 21:12:11 -0300140 @mock.patch.object(Common, "perform_request")
Helena McGoughfe92f842017-11-17 14:57:08 +0000141 def test_ack_alarm_req(self, perf_req):
142 """Test update alarm state for acknowledge alarm request."""
Benjamin Diaz181cce82018-03-28 21:12:11 -0300143 self.alarming.update_alarm_state(alarm_endpoint, auth_token, "my_alarm_id")
Helena McGoughfe92f842017-11-17 14:57:08 +0000144
145 perf_req.assert_called_with(
Benjamin Diaz181cce82018-03-28 21:12:11 -0300146 "alarm_endpoint/v2/alarms/my_alarm_id/state", auth_token, req_type="put",
Helena McGoughfe92f842017-11-17 14:57:08 +0000147 payload=json.dumps("ok"))
148
149 @mock.patch.object(alarm_req.Alarming, "check_payload")
Benjamin Diaz181cce82018-03-28 21:12:11 -0300150 @mock.patch.object(Common, "perform_request")
Helena McGoughfe92f842017-11-17 14:57:08 +0000151 def test_update_alarm_invalid(self, perf_req, check_pay):
152 """Test update alarm with invalid get response."""
153 values = {"alarm_uuid": "my_alarm_id"}
154
Benjamin Diaz181cce82018-03-28 21:12:11 -0300155 self.alarming.update_alarm(alarm_endpoint, auth_token, values)
Helena McGoughfe92f842017-11-17 14:57:08 +0000156
157 perf_req.assert_called_with(mock.ANY, auth_token, req_type="get")
Benjamin Diaz181cce82018-03-28 21:12:11 -0300158 check_pay.assert_not_called()
Helena McGoughfe92f842017-11-17 14:57:08 +0000159
160 @mock.patch.object(alarm_req.Alarming, "check_payload")
Benjamin Diaz181cce82018-03-28 21:12:11 -0300161 @mock.patch.object(Common, "perform_request")
Helena McGoughfe92f842017-11-17 14:57:08 +0000162 def test_update_alarm_invalid_payload(self, perf_req, check_pay):
163 """Test update alarm with invalid payload."""
164 resp = Response({"name": "my_alarm",
165 "state": "alarm",
166 "gnocchi_resources_threshold_rule":
167 {"resource_id": "my_resource_id",
168 "metric": "my_metric"}})
169 perf_req.return_value = resp
170 check_pay.return_value = None
171 values = {"alarm_uuid": "my_alarm_id"}
172
Benjamin Diaz181cce82018-03-28 21:12:11 -0300173 self.alarming.update_alarm(alarm_endpoint, auth_token, values)
Helena McGoughfe92f842017-11-17 14:57:08 +0000174
175 perf_req.assert_called_with(mock.ANY, auth_token, req_type="get")
176 self.assertEqual(perf_req.call_count, 1)
177
178 @mock.patch.object(alarm_req.Alarming, "check_payload")
Benjamin Diaz181cce82018-03-28 21:12:11 -0300179 @mock.patch.object(Common, "perform_request")
Helena McGoughfe92f842017-11-17 14:57:08 +0000180 def test_update_alarm_valid(self, perf_req, check_pay):
181 """Test valid update alarm request."""
182 resp = Response({"name": "my_alarm",
183 "state": "alarm",
184 "gnocchi_resources_threshold_rule":
185 {"resource_id": "my_resource_id",
Benjamin Diaz181cce82018-03-28 21:12:11 -0300186 "metric": "disk.write.requests"}})
Helena McGoughfe92f842017-11-17 14:57:08 +0000187 perf_req.return_value = resp
188 values = {"alarm_uuid": "my_alarm_id"}
189
Benjamin Diaz181cce82018-03-28 21:12:11 -0300190 self.alarming.update_alarm(alarm_endpoint, auth_token, values)
Helena McGoughfe92f842017-11-17 14:57:08 +0000191
Benjamin Diaz181cce82018-03-28 21:12:11 -0300192 check_pay.assert_called_with(values, "disk_write_ops", "my_resource_id",
Helena McGoughfe92f842017-11-17 14:57:08 +0000193 "my_alarm", alarm_state="alarm")
194
195 self.assertEqual(perf_req.call_count, 2)
196 # Second call is the update request
197 perf_req.assert_called_with(
Benjamin Diaz181cce82018-03-28 21:12:11 -0300198 'alarm_endpoint/v2/alarms/my_alarm_id', auth_token,
Helena McGoughfe92f842017-11-17 14:57:08 +0000199 req_type="put", payload=check_pay.return_value)
200
Benjamin Diaz181cce82018-03-28 21:12:11 -0300201 @mock.patch.object(Config, "instance")
202 def test_check_valid_payload(self, cfg):
Helena McGoughfe92f842017-11-17 14:57:08 +0000203 """Test the check payload function for a valid payload."""
204 values = {"severity": "warning",
205 "statistic": "COUNT",
206 "threshold_value": 12,
Benjamin Diaz0e57d112018-03-25 14:43:52 -0300207 "operation": "GT",
208 "granularity": 300,
209 "resource_type": "generic"}
Benjamin Diaz181cce82018-03-28 21:12:11 -0300210 cfg.return_value.OS_NOTIFIER_URI = "http://localhost:8662"
Helena McGoughfe92f842017-11-17 14:57:08 +0000211 payload = self.alarming.check_payload(
Benjamin Diaz0e57d112018-03-25 14:43:52 -0300212 values, "disk_write_ops", "r_id", "alarm_name")
Helena McGoughfe92f842017-11-17 14:57:08 +0000213
Benjamin Diaz0e57d112018-03-25 14:43:52 -0300214 self.assertDictEqual(
Helena McGoughfe92f842017-11-17 14:57:08 +0000215 json.loads(payload), {"name": "alarm_name",
216 "gnocchi_resources_threshold_rule":
217 {"resource_id": "r_id",
Benjamin Diaz181cce82018-03-28 21:12:11 -0300218 "metric": "disk.write.requests",
Helena McGoughfe92f842017-11-17 14:57:08 +0000219 "comparison_operator": "gt",
220 "aggregation_method": "count",
221 "threshold": 12,
Benjamin Diaz0e57d112018-03-25 14:43:52 -0300222 "granularity": 300,
Helena McGoughfe92f842017-11-17 14:57:08 +0000223 "resource_type": "generic"},
224 "severity": "low",
225 "state": "ok",
Helena McGough94f93f72017-11-23 17:29:54 +0000226 "type": "gnocchi_resources_threshold",
227 "alarm_actions": ["http://localhost:8662"]})
Helena McGoughfe92f842017-11-17 14:57:08 +0000228
Benjamin Diaz181cce82018-03-28 21:12:11 -0300229 @mock.patch.object(Config, "instance")
230 @mock.patch.object(Common, "perform_request")
231 def test_check_valid_state_payload(self, perform_req, cfg):
Helena McGoughfe92f842017-11-17 14:57:08 +0000232 """Test the check payload function for a valid payload with state."""
233 values = {"severity": "warning",
234 "statistic": "COUNT",
235 "threshold_value": 12,
Benjamin Diaz0e57d112018-03-25 14:43:52 -0300236 "operation": "GT",
237 "granularity": 300,
238 "resource_type": "generic"}
Benjamin Diaz181cce82018-03-28 21:12:11 -0300239 cfg.return_value.OS_NOTIFIER_URI = "http://localhost:8662"
Helena McGoughfe92f842017-11-17 14:57:08 +0000240 payload = self.alarming.check_payload(
Benjamin Diaz0e57d112018-03-25 14:43:52 -0300241 values, "disk_write_ops", "r_id", "alarm_name", alarm_state="alarm")
Helena McGoughfe92f842017-11-17 14:57:08 +0000242
243 self.assertEqual(
244 json.loads(payload), {"name": "alarm_name",
245 "gnocchi_resources_threshold_rule":
246 {"resource_id": "r_id",
Benjamin Diaz181cce82018-03-28 21:12:11 -0300247 "metric": "disk.write.requests",
Helena McGoughfe92f842017-11-17 14:57:08 +0000248 "comparison_operator": "gt",
249 "aggregation_method": "count",
250 "threshold": 12,
Benjamin Diaz0e57d112018-03-25 14:43:52 -0300251 "granularity": 300,
Helena McGoughfe92f842017-11-17 14:57:08 +0000252 "resource_type": "generic"},
253 "severity": "low",
254 "state": "alarm",
Helena McGough94f93f72017-11-23 17:29:54 +0000255 "type": "gnocchi_resources_threshold",
256 "alarm_actions": ["http://localhost:8662"]})
Helena McGoughfe92f842017-11-17 14:57:08 +0000257
258 def test_check_invalid_payload(self):
259 """Test the check payload function for an invalid payload."""
260 values = {"alarm_values": "mock_invalid_details"}
261 payload = self.alarming.check_payload(
262 values, "my_metric", "r_id", "alarm_name")
263
264 self.assertEqual(payload, None)
265
Benjamin Diaz181cce82018-03-28 21:12:11 -0300266 @mock.patch.object(Common, "perform_request")
Helena McGoughfe92f842017-11-17 14:57:08 +0000267 def test_get_alarm_state(self, perf_req):
268 """Test the get alarm state function."""
Benjamin Diaz181cce82018-03-28 21:12:11 -0300269 self.alarming.get_alarm_state(alarm_endpoint, auth_token, "alarm_id")
Helena McGoughfe92f842017-11-17 14:57:08 +0000270
271 perf_req.assert_called_with(
Benjamin Diaz181cce82018-03-28 21:12:11 -0300272 "alarm_endpoint/v2/alarms/alarm_id/state", auth_token, req_type="get")
Helena McGoughfe92f842017-11-17 14:57:08 +0000273
274 @mock.patch.object(Common, "get_endpoint")
Benjamin Diaz181cce82018-03-28 21:12:11 -0300275 @mock.patch.object(Common, "perform_request")
Helena McGoughfe92f842017-11-17 14:57:08 +0000276 def test_check_for_metric(self, perf_req, get_endpoint):
277 """Test the check for metric function."""
278 get_endpoint.return_value = "gnocchi_endpoint"
279
Benjamin Diaz181cce82018-03-28 21:12:11 -0300280 self.alarming.check_for_metric(auth_token, metric_endpoint, "metric_name", "r_id")
Helena McGoughfe92f842017-11-17 14:57:08 +0000281
282 perf_req.assert_called_with(
Benjamin Diaz181cce82018-03-28 21:12:11 -0300283 "metric_endpoint/v1/metric?sort=name:asc", auth_token, req_type="get")