Reformat POL to standardized format
[osm/POL.git] / osm_policy_module / tests / unit / autoscaling / test_autoscaling_service.py
1 # -*- coding: utf-8 -*-
2
3 # Copyright 2018 Whitestack, LLC
4 # *************************************************************
5
6 # This file is part of OSM Monitoring module
7 # All Rights Reserved to Whitestack, LLC
8
9 # Licensed under the Apache License, Version 2.0 (the "License"); you may
10 # not use this file except in compliance with the License. You may obtain
11 # a copy of the License at
12
13 # http://www.apache.org/licenses/LICENSE-2.0
14
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18 # License for the specific language governing permissions and limitations
19 # under the License.
20
21 # For those usages not covered by the Apache License, Version 2.0 please
22 # contact: bdiaz@whitestack.com or glavado@whitestack.com
23 ##
24 import asyncio
25 import datetime
26 from unittest import TestCase, mock
27
28 from osm_policy_module.autoscaling.service import AutoscalingService
29 from osm_policy_module.common.common_db_client import CommonDbClient
30 from osm_policy_module.common.lcm_client import LcmClient
31 from osm_policy_module.common.mon_client import MonClient
32 from osm_policy_module.core.config import Config
33 from osm_policy_module.core.database import ScalingAlarmRepository
34
35
36 @mock.patch.object(LcmClient, "__init__", lambda *args, **kwargs: None)
37 @mock.patch.object(MonClient, "__init__", lambda *args, **kwargs: None)
38 @mock.patch.object(CommonDbClient, "__init__", lambda *args, **kwargs: None)
39 class TestAutoscalingService(TestCase):
40 def setUp(self):
41 self.config = Config()
42 self.loop = asyncio.new_event_loop()
43
44 @mock.patch.object(ScalingAlarmRepository, "get")
45 @mock.patch("osm_policy_module.core.database.db")
46 def test_update_alarm_status(self, database, get_alarm):
47 mock_alarm = mock.Mock()
48 mock_alarm.last_status = "insufficient_data"
49 get_alarm.return_value = mock_alarm
50
51 service = AutoscalingService(self.config)
52 self.loop.run_until_complete(service.update_alarm_status("test_uuid", "alarm"))
53 self.assertEqual(mock_alarm.last_status, "alarm")
54 mock_alarm.save.assert_called_with()
55
56 service = AutoscalingService(self.config)
57 self.loop.run_until_complete(service.update_alarm_status("test_uuid", "ok"))
58 self.assertEqual(mock_alarm.last_status, "ok")
59 mock_alarm.save.assert_called_with()
60
61 service = AutoscalingService(self.config)
62 self.loop.run_until_complete(
63 service.update_alarm_status("test_uuid", "insufficient_data")
64 )
65 self.assertEqual(mock_alarm.last_status, "insufficient_data")
66 mock_alarm.save.assert_called_with()
67
68 @mock.patch.object(ScalingAlarmRepository, "list")
69 @mock.patch.object(ScalingAlarmRepository, "get")
70 @mock.patch("osm_policy_module.core.database.db")
71 def test_evaluate_policy_not_enabled(self, database, get_alarm, list_alarms):
72 mock_alarm = mock.Mock()
73 mock_alarm.scaling_criteria.scaling_policy.enabled = False
74 get_alarm.return_value = mock_alarm
75
76 service = AutoscalingService(self.config)
77 self.loop.run_until_complete(service.evaluate_policy("test_uuid"))
78 list_alarms.assert_not_called()
79
80 @mock.patch.object(ScalingAlarmRepository, "list")
81 @mock.patch.object(ScalingAlarmRepository, "get")
82 @mock.patch.object(LcmClient, "scale")
83 @mock.patch("osm_policy_module.core.database.db")
84 def test_evaluate_policy_scale_in_and_equal(
85 self, database, scale, get_alarm, list_alarms
86 ):
87 """
88 Tests scale in with AND operation, both alarms triggered
89 """
90 future = asyncio.Future(loop=self.loop)
91 future.set_result("mock")
92 scale.return_value = future
93
94 mock_alarm = self._build_mock_alarm(
95 action="scale_in", last_status="alarm", enabled=True, scale_in_op="AND"
96 )
97 get_alarm.return_value = mock_alarm
98
99 mock_alarm_2 = self._build_mock_alarm(
100 action="scale_in", last_status="alarm", enabled=True, scale_in_op="AND"
101 )
102
103 list_alarms.return_value = [mock_alarm, mock_alarm_2]
104
105 service = AutoscalingService(self.config)
106 self.loop.run_until_complete(service.evaluate_policy("test_uuid"))
107 scale.assert_called_with("test_nsr_id", "test_group", "1", "scale_in")
108
109 @mock.patch.object(ScalingAlarmRepository, "list")
110 @mock.patch.object(ScalingAlarmRepository, "get")
111 @mock.patch.object(LcmClient, "scale")
112 @mock.patch("osm_policy_module.core.database.db")
113 def test_evaluate_policy_scale_in_and_diff(
114 self, database, scale, get_alarm, list_alarms
115 ):
116 """
117 Tests scale in with AND operation, only one alarm triggered.
118 """
119 future = asyncio.Future(loop=self.loop)
120 future.set_result("mock")
121 scale.return_value = future
122
123 mock_alarm = self._build_mock_alarm(
124 action="scale_in", last_status="alarm", enabled=True, scale_in_op="AND"
125 )
126 get_alarm.return_value = mock_alarm
127
128 mock_alarm_2 = self._build_mock_alarm(
129 action="scale_in", last_status="ok", enabled=True, scale_in_op="OR"
130 )
131
132 list_alarms.return_value = [mock_alarm, mock_alarm_2]
133
134 service = AutoscalingService(self.config)
135 self.loop.run_until_complete(service.evaluate_policy("test_uuid"))
136 scale.assert_not_called()
137
138 @mock.patch.object(ScalingAlarmRepository, "list")
139 @mock.patch.object(ScalingAlarmRepository, "get")
140 @mock.patch.object(LcmClient, "scale")
141 @mock.patch("osm_policy_module.core.database.db")
142 def test_evaluate_policy_scale_in_or_equal(
143 self, database, scale, get_alarm, list_alarms
144 ):
145 """
146 Tests scale in with OR operation, both alarms triggered
147 """
148 future = asyncio.Future(loop=self.loop)
149 future.set_result("mock")
150 scale.return_value = future
151
152 mock_alarm = self._build_mock_alarm(
153 action="scale_in", last_status="alarm", enabled=True, scale_in_op="OR"
154 )
155 get_alarm.return_value = mock_alarm
156
157 mock_alarm_2 = self._build_mock_alarm(
158 action="scale_in", last_status="alarm", enabled=True, scale_in_op="OR"
159 )
160
161 list_alarms.return_value = [mock_alarm, mock_alarm_2]
162
163 service = AutoscalingService(self.config)
164 self.loop.run_until_complete(service.evaluate_policy("test_uuid"))
165 scale.assert_called_with("test_nsr_id", "test_group", "1", "scale_in")
166
167 @mock.patch.object(ScalingAlarmRepository, "list")
168 @mock.patch.object(ScalingAlarmRepository, "get")
169 @mock.patch.object(LcmClient, "scale")
170 @mock.patch("osm_policy_module.core.database.db")
171 def test_evaluate_policy_scale_in_or_diff(
172 self, database, scale, get_alarm, list_alarms
173 ):
174 """
175 Tests scale in with OR operation, only one alarm triggered
176 """
177 future = asyncio.Future(loop=self.loop)
178 future.set_result("mock")
179 scale.return_value = future
180
181 mock_alarm = self._build_mock_alarm(
182 action="scale_in", last_status="alarm", enabled=True, scale_in_op="OR"
183 )
184 get_alarm.return_value = mock_alarm
185
186 mock_alarm_2 = self._build_mock_alarm(
187 action="scale_in", last_status="ok", enabled=True, scale_in_op="OR"
188 )
189
190 list_alarms.return_value = [mock_alarm, mock_alarm_2]
191
192 service = AutoscalingService(self.config)
193 self.loop.run_until_complete(service.evaluate_policy("test_uuid"))
194 scale.assert_called_with("test_nsr_id", "test_group", "1", "scale_in")
195
196 @mock.patch.object(ScalingAlarmRepository, "list")
197 @mock.patch.object(ScalingAlarmRepository, "get")
198 @mock.patch.object(LcmClient, "scale")
199 @mock.patch("osm_policy_module.core.database.db")
200 def test_evaluate_policy_scale_out_and_equal(
201 self, database, scale, get_alarm, list_alarms
202 ):
203 """
204 Tests scale out with AND operation, both alarms triggered
205 """
206 future = asyncio.Future(loop=self.loop)
207 future.set_result("mock")
208 scale.return_value = future
209
210 mock_alarm = self._build_mock_alarm(
211 action="scale_out", last_status="alarm", enabled=True, scale_out_op="AND"
212 )
213 get_alarm.return_value = mock_alarm
214
215 mock_alarm_2 = self._build_mock_alarm(
216 action="scale_out", last_status="alarm", enabled=True, scale_out_op="AND"
217 )
218
219 list_alarms.return_value = [mock_alarm, mock_alarm_2]
220
221 service = AutoscalingService(self.config)
222 self.loop.run_until_complete(service.evaluate_policy("test_uuid"))
223 scale.assert_called_with("test_nsr_id", "test_group", "1", "scale_out")
224
225 @mock.patch.object(ScalingAlarmRepository, "list")
226 @mock.patch.object(ScalingAlarmRepository, "get")
227 @mock.patch.object(LcmClient, "scale")
228 @mock.patch("osm_policy_module.core.database.db")
229 def test_evaluate_policy_scale_out_and_diff(
230 self, database, scale, get_alarm, list_alarms
231 ):
232 """
233 Tests scale out with AND operation, only one alarm triggered.
234 """
235 future = asyncio.Future(loop=self.loop)
236 future.set_result("mock")
237 scale.return_value = future
238
239 mock_alarm = self._build_mock_alarm(
240 action="scale_out", last_status="alarm", enabled=True, scale_out_op="AND"
241 )
242 get_alarm.return_value = mock_alarm
243
244 mock_alarm_2 = self._build_mock_alarm(
245 action="scale_out", last_status="ok", enabled=True, scale_out_op="OR"
246 )
247
248 list_alarms.return_value = [mock_alarm, mock_alarm_2]
249
250 service = AutoscalingService(self.config)
251 self.loop.run_until_complete(service.evaluate_policy("test_uuid"))
252 scale.assert_not_called()
253
254 @mock.patch.object(ScalingAlarmRepository, "list")
255 @mock.patch.object(ScalingAlarmRepository, "get")
256 @mock.patch.object(LcmClient, "scale")
257 @mock.patch("osm_policy_module.core.database.db")
258 def test_evaluate_policy_scale_out_or_equal(
259 self, database, scale, get_alarm, list_alarms
260 ):
261 """
262 Tests scale out with OR operation, both alarms triggered
263 """
264 future = asyncio.Future(loop=self.loop)
265 future.set_result("mock")
266 scale.return_value = future
267
268 mock_alarm = self._build_mock_alarm(
269 action="scale_out", last_status="alarm", enabled=True, scale_out_op="OR"
270 )
271 get_alarm.return_value = mock_alarm
272
273 mock_alarm_2 = self._build_mock_alarm(
274 action="scale_out", last_status="alarm", enabled=True, scale_out_op="OR"
275 )
276
277 list_alarms.return_value = [mock_alarm, mock_alarm_2]
278
279 service = AutoscalingService(self.config)
280 self.loop.run_until_complete(service.evaluate_policy("test_uuid"))
281 scale.assert_called_with("test_nsr_id", "test_group", "1", "scale_out")
282
283 @mock.patch.object(ScalingAlarmRepository, "list")
284 @mock.patch.object(ScalingAlarmRepository, "get")
285 @mock.patch.object(LcmClient, "scale")
286 @mock.patch("osm_policy_module.core.database.db")
287 def test_evaluate_policy_scale_out_or_diff(
288 self, database, scale, get_alarm, list_alarms
289 ):
290 """
291 Tests scale out with OR operation, only one alarm triggered
292 """
293 future = asyncio.Future(loop=self.loop)
294 future.set_result("mock")
295 scale.return_value = future
296
297 mock_alarm = self._build_mock_alarm(
298 action="scale_out", last_status="alarm", enabled=True, scale_out_op="OR"
299 )
300 get_alarm.return_value = mock_alarm
301
302 mock_alarm_2 = self._build_mock_alarm(
303 action="scale_out", last_status="ok", enabled=True, scale_out_op="OR"
304 )
305
306 list_alarms.return_value = [mock_alarm, mock_alarm_2]
307
308 service = AutoscalingService(self.config)
309 self.loop.run_until_complete(service.evaluate_policy("test_uuid"))
310 scale.assert_called_with("test_nsr_id", "test_group", "1", "scale_out")
311
312 def _build_mock_alarm(
313 self,
314 action="scale_in",
315 last_status="alarm",
316 last_scale=datetime.datetime.min,
317 cooldown_time=10,
318 enabled=True,
319 scale_in_op="AND",
320 scale_out_op="AND",
321 ):
322 mock_alarm = mock.Mock()
323 mock_alarm.action = action
324 mock_alarm.last_status = last_status
325 mock_alarm.vnf_member_index = "1"
326 mock_alarm.scaling_criteria.scaling_policy.last_scale = last_scale
327 mock_alarm.scaling_criteria.scaling_policy.cooldown_time = cooldown_time
328 mock_alarm.scaling_criteria.scaling_policy.enabled = enabled
329 mock_alarm.scaling_criteria.scaling_policy.scale_in_operation = scale_in_op
330 mock_alarm.scaling_criteria.scaling_policy.scale_out_operation = scale_out_op
331 mock_alarm.scaling_criteria.scaling_policy.scaling_group.nsr_id = "test_nsr_id"
332 mock_alarm.scaling_criteria.scaling_policy.scaling_group.name = "test_group"
333 return mock_alarm