Updates for Python 3.10 and Ubuntu 22.04
[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
43 @mock.patch.object(ScalingAlarmRepository, "get")
44 @mock.patch("osm_policy_module.core.database.db")
45 def test_update_alarm_status(self, database, get_alarm):
46 mock_alarm = mock.Mock()
47 mock_alarm.last_status = "insufficient_data"
48 get_alarm.return_value = mock_alarm
49
50 service = AutoscalingService(self.config)
51 asyncio.run(service.update_alarm_status("test_uuid", "alarm"))
52 self.assertEqual(mock_alarm.last_status, "alarm")
53 mock_alarm.save.assert_called_with()
54
55 service = AutoscalingService(self.config)
56 asyncio.run(service.update_alarm_status("test_uuid", "ok"))
57 self.assertEqual(mock_alarm.last_status, "ok")
58 mock_alarm.save.assert_called_with()
59
60 service = AutoscalingService(self.config)
61 asyncio.run(service.update_alarm_status("test_uuid", "insufficient_data"))
62 self.assertEqual(mock_alarm.last_status, "insufficient_data")
63 mock_alarm.save.assert_called_with()
64
65 @mock.patch.object(ScalingAlarmRepository, "list")
66 @mock.patch.object(ScalingAlarmRepository, "get")
67 @mock.patch("osm_policy_module.core.database.db")
68 def test_evaluate_policy_not_enabled(self, database, get_alarm, list_alarms):
69 mock_alarm = mock.Mock()
70 mock_alarm.scaling_criteria.scaling_policy.enabled = False
71 get_alarm.return_value = mock_alarm
72
73 service = AutoscalingService(self.config)
74 asyncio.run(service.evaluate_policy("test_uuid"))
75 list_alarms.assert_not_called()
76
77 @mock.patch.object(ScalingAlarmRepository, "list")
78 @mock.patch.object(ScalingAlarmRepository, "get")
79 @mock.patch.object(LcmClient, "scale")
80 @mock.patch("osm_policy_module.core.database.db")
81 def test_evaluate_policy_scale_in_and_equal(
82 self, database, scale, get_alarm, list_alarms
83 ):
84 """
85 Tests scale in with AND operation, both alarms triggered
86 """
87 future = asyncio.Future(loop=asyncio.new_event_loop())
88 future.set_result("mock")
89 scale.return_value = future
90
91 mock_alarm = self._build_mock_alarm(
92 action="scale_in", last_status="alarm", enabled=True, scale_in_op="AND"
93 )
94 get_alarm.return_value = mock_alarm
95
96 mock_alarm_2 = self._build_mock_alarm(
97 action="scale_in", last_status="alarm", enabled=True, scale_in_op="AND"
98 )
99
100 list_alarms.return_value = [mock_alarm, mock_alarm_2]
101
102 service = AutoscalingService(self.config)
103 asyncio.run(service.evaluate_policy("test_uuid"))
104 scale.assert_called_with("test_nsr_id", "test_group", "1", "scale_in")
105
106 @mock.patch.object(ScalingAlarmRepository, "list")
107 @mock.patch.object(ScalingAlarmRepository, "get")
108 @mock.patch.object(LcmClient, "scale")
109 @mock.patch("osm_policy_module.core.database.db")
110 def test_evaluate_policy_scale_in_and_diff(
111 self, database, scale, get_alarm, list_alarms
112 ):
113 """
114 Tests scale in with AND operation, only one alarm triggered.
115 """
116 future = asyncio.Future(loop=asyncio.new_event_loop())
117 future.set_result("mock")
118 scale.return_value = future
119
120 mock_alarm = self._build_mock_alarm(
121 action="scale_in", last_status="alarm", enabled=True, scale_in_op="AND"
122 )
123 get_alarm.return_value = mock_alarm
124
125 mock_alarm_2 = self._build_mock_alarm(
126 action="scale_in", last_status="ok", enabled=True, scale_in_op="OR"
127 )
128
129 list_alarms.return_value = [mock_alarm, mock_alarm_2]
130
131 service = AutoscalingService(self.config)
132 asyncio.run(service.evaluate_policy("test_uuid"))
133 scale.assert_not_called()
134
135 @mock.patch.object(ScalingAlarmRepository, "list")
136 @mock.patch.object(ScalingAlarmRepository, "get")
137 @mock.patch.object(LcmClient, "scale")
138 @mock.patch("osm_policy_module.core.database.db")
139 def test_evaluate_policy_scale_in_or_equal(
140 self, database, scale, get_alarm, list_alarms
141 ):
142 """
143 Tests scale in with OR operation, both alarms triggered
144 """
145 future = asyncio.Future(loop=asyncio.new_event_loop())
146 future.set_result("mock")
147 scale.return_value = future
148
149 mock_alarm = self._build_mock_alarm(
150 action="scale_in", last_status="alarm", enabled=True, scale_in_op="OR"
151 )
152 get_alarm.return_value = mock_alarm
153
154 mock_alarm_2 = self._build_mock_alarm(
155 action="scale_in", last_status="alarm", enabled=True, scale_in_op="OR"
156 )
157
158 list_alarms.return_value = [mock_alarm, mock_alarm_2]
159
160 service = AutoscalingService(self.config)
161 asyncio.run(service.evaluate_policy("test_uuid"))
162 scale.assert_called_with("test_nsr_id", "test_group", "1", "scale_in")
163
164 @mock.patch.object(ScalingAlarmRepository, "list")
165 @mock.patch.object(ScalingAlarmRepository, "get")
166 @mock.patch.object(LcmClient, "scale")
167 @mock.patch("osm_policy_module.core.database.db")
168 def test_evaluate_policy_scale_in_or_diff(
169 self, database, scale, get_alarm, list_alarms
170 ):
171 """
172 Tests scale in with OR operation, only one alarm triggered
173 """
174 future = asyncio.Future(loop=asyncio.new_event_loop())
175 future.set_result("mock")
176 scale.return_value = future
177
178 mock_alarm = self._build_mock_alarm(
179 action="scale_in", last_status="alarm", enabled=True, scale_in_op="OR"
180 )
181 get_alarm.return_value = mock_alarm
182
183 mock_alarm_2 = self._build_mock_alarm(
184 action="scale_in", last_status="ok", enabled=True, scale_in_op="OR"
185 )
186
187 list_alarms.return_value = [mock_alarm, mock_alarm_2]
188
189 service = AutoscalingService(self.config)
190 asyncio.run(service.evaluate_policy("test_uuid"))
191 scale.assert_called_with("test_nsr_id", "test_group", "1", "scale_in")
192
193 @mock.patch.object(ScalingAlarmRepository, "list")
194 @mock.patch.object(ScalingAlarmRepository, "get")
195 @mock.patch.object(LcmClient, "scale")
196 @mock.patch("osm_policy_module.core.database.db")
197 def test_evaluate_policy_scale_out_and_equal(
198 self, database, scale, get_alarm, list_alarms
199 ):
200 """
201 Tests scale out with AND operation, both alarms triggered
202 """
203 future = asyncio.Future(loop=asyncio.new_event_loop())
204 future.set_result("mock")
205 scale.return_value = future
206
207 mock_alarm = self._build_mock_alarm(
208 action="scale_out", last_status="alarm", enabled=True, scale_out_op="AND"
209 )
210 get_alarm.return_value = mock_alarm
211
212 mock_alarm_2 = self._build_mock_alarm(
213 action="scale_out", last_status="alarm", enabled=True, scale_out_op="AND"
214 )
215
216 list_alarms.return_value = [mock_alarm, mock_alarm_2]
217
218 service = AutoscalingService(self.config)
219 asyncio.run(service.evaluate_policy("test_uuid"))
220 scale.assert_called_with("test_nsr_id", "test_group", "1", "scale_out")
221
222 @mock.patch.object(ScalingAlarmRepository, "list")
223 @mock.patch.object(ScalingAlarmRepository, "get")
224 @mock.patch.object(LcmClient, "scale")
225 @mock.patch("osm_policy_module.core.database.db")
226 def test_evaluate_policy_scale_out_and_diff(
227 self, database, scale, get_alarm, list_alarms
228 ):
229 """
230 Tests scale out with AND operation, only one alarm triggered.
231 """
232 future = asyncio.Future(loop=asyncio.new_event_loop())
233 future.set_result("mock")
234 scale.return_value = future
235
236 mock_alarm = self._build_mock_alarm(
237 action="scale_out", last_status="alarm", enabled=True, scale_out_op="AND"
238 )
239 get_alarm.return_value = mock_alarm
240
241 mock_alarm_2 = self._build_mock_alarm(
242 action="scale_out", last_status="ok", enabled=True, scale_out_op="OR"
243 )
244
245 list_alarms.return_value = [mock_alarm, mock_alarm_2]
246
247 service = AutoscalingService(self.config)
248 asyncio.run(service.evaluate_policy("test_uuid"))
249 scale.assert_not_called()
250
251 @mock.patch.object(ScalingAlarmRepository, "list")
252 @mock.patch.object(ScalingAlarmRepository, "get")
253 @mock.patch.object(LcmClient, "scale")
254 @mock.patch("osm_policy_module.core.database.db")
255 def test_evaluate_policy_scale_out_or_equal(
256 self, database, scale, get_alarm, list_alarms
257 ):
258 """
259 Tests scale out with OR operation, both alarms triggered
260 """
261 future = asyncio.Future(loop=asyncio.new_event_loop())
262 future.set_result("mock")
263 scale.return_value = future
264
265 mock_alarm = self._build_mock_alarm(
266 action="scale_out", last_status="alarm", enabled=True, scale_out_op="OR"
267 )
268 get_alarm.return_value = mock_alarm
269
270 mock_alarm_2 = self._build_mock_alarm(
271 action="scale_out", last_status="alarm", enabled=True, scale_out_op="OR"
272 )
273
274 list_alarms.return_value = [mock_alarm, mock_alarm_2]
275
276 service = AutoscalingService(self.config)
277 asyncio.run(service.evaluate_policy("test_uuid"))
278 scale.assert_called_with("test_nsr_id", "test_group", "1", "scale_out")
279
280 @mock.patch.object(ScalingAlarmRepository, "list")
281 @mock.patch.object(ScalingAlarmRepository, "get")
282 @mock.patch.object(LcmClient, "scale")
283 @mock.patch("osm_policy_module.core.database.db")
284 def test_evaluate_policy_scale_out_or_diff(
285 self, database, scale, get_alarm, list_alarms
286 ):
287 """
288 Tests scale out with OR operation, only one alarm triggered
289 """
290 future = asyncio.Future(loop=asyncio.new_event_loop())
291 future.set_result("mock")
292 scale.return_value = future
293
294 mock_alarm = self._build_mock_alarm(
295 action="scale_out", last_status="alarm", enabled=True, scale_out_op="OR"
296 )
297 get_alarm.return_value = mock_alarm
298
299 mock_alarm_2 = self._build_mock_alarm(
300 action="scale_out", last_status="ok", enabled=True, scale_out_op="OR"
301 )
302
303 list_alarms.return_value = [mock_alarm, mock_alarm_2]
304
305 service = AutoscalingService(self.config)
306 asyncio.run(service.evaluate_policy("test_uuid"))
307 scale.assert_called_with("test_nsr_id", "test_group", "1", "scale_out")
308
309 def _build_mock_alarm(
310 self,
311 action="scale_in",
312 last_status="alarm",
313 last_scale=datetime.datetime.min,
314 cooldown_time=10,
315 enabled=True,
316 scale_in_op="AND",
317 scale_out_op="AND",
318 ):
319 mock_alarm = mock.Mock()
320 mock_alarm.action = action
321 mock_alarm.last_status = last_status
322 mock_alarm.vnf_member_index = "1"
323 mock_alarm.scaling_criteria.scaling_policy.last_scale = last_scale
324 mock_alarm.scaling_criteria.scaling_policy.cooldown_time = cooldown_time
325 mock_alarm.scaling_criteria.scaling_policy.enabled = enabled
326 mock_alarm.scaling_criteria.scaling_policy.scale_in_operation = scale_in_op
327 mock_alarm.scaling_criteria.scaling_policy.scale_out_operation = scale_out_op
328 mock_alarm.scaling_criteria.scaling_policy.scaling_group.nsr_id = "test_nsr_id"
329 mock_alarm.scaling_criteria.scaling_policy.scaling_group.name = "test_group"
330 return mock_alarm