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