1 # -*- coding: utf-8 -*-
3 # Copyright 2018 Whitestack, LLC
4 # *************************************************************
6 # This file is part of OSM Monitoring module
7 # All Rights Reserved to Whitestack, LLC
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
13 # http://www.apache.org/licenses/LICENSE-2.0
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
21 # For those usages not covered by the Apache License, Version 2.0 please
22 # contact: bdiaz@whitestack.com or glavado@whitestack.com
26 from unittest
import TestCase
, mock
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
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
):
41 self
.config
= Config()
42 self
.loop
= asyncio
.new_event_loop()
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
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()
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()
61 service
= AutoscalingService(self
.config
)
62 self
.loop
.run_until_complete(
63 service
.update_alarm_status("test_uuid", "insufficient_data")
65 self
.assertEqual(mock_alarm
.last_status
, "insufficient_data")
66 mock_alarm
.save
.assert_called_with()
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
76 service
= AutoscalingService(self
.config
)
77 self
.loop
.run_until_complete(service
.evaluate_policy("test_uuid"))
78 list_alarms
.assert_not_called()
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
88 Tests scale in with AND operation, both alarms triggered
90 future
= asyncio
.Future(loop
=self
.loop
)
91 future
.set_result("mock")
92 scale
.return_value
= future
94 mock_alarm
= self
._build
_mock
_alarm
(
95 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="AND"
97 get_alarm
.return_value
= mock_alarm
99 mock_alarm_2
= self
._build
_mock
_alarm
(
100 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="AND"
103 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
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")
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
117 Tests scale in with AND operation, only one alarm triggered.
119 future
= asyncio
.Future(loop
=self
.loop
)
120 future
.set_result("mock")
121 scale
.return_value
= future
123 mock_alarm
= self
._build
_mock
_alarm
(
124 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="AND"
126 get_alarm
.return_value
= mock_alarm
128 mock_alarm_2
= self
._build
_mock
_alarm
(
129 action
="scale_in", last_status
="ok", enabled
=True, scale_in_op
="OR"
132 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
134 service
= AutoscalingService(self
.config
)
135 self
.loop
.run_until_complete(service
.evaluate_policy("test_uuid"))
136 scale
.assert_not_called()
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
146 Tests scale in with OR operation, both alarms triggered
148 future
= asyncio
.Future(loop
=self
.loop
)
149 future
.set_result("mock")
150 scale
.return_value
= future
152 mock_alarm
= self
._build
_mock
_alarm
(
153 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="OR"
155 get_alarm
.return_value
= mock_alarm
157 mock_alarm_2
= self
._build
_mock
_alarm
(
158 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="OR"
161 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
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")
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
175 Tests scale in with OR operation, only one alarm triggered
177 future
= asyncio
.Future(loop
=self
.loop
)
178 future
.set_result("mock")
179 scale
.return_value
= future
181 mock_alarm
= self
._build
_mock
_alarm
(
182 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="OR"
184 get_alarm
.return_value
= mock_alarm
186 mock_alarm_2
= self
._build
_mock
_alarm
(
187 action
="scale_in", last_status
="ok", enabled
=True, scale_in_op
="OR"
190 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
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")
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
204 Tests scale out with AND operation, both alarms triggered
206 future
= asyncio
.Future(loop
=self
.loop
)
207 future
.set_result("mock")
208 scale
.return_value
= future
210 mock_alarm
= self
._build
_mock
_alarm
(
211 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="AND"
213 get_alarm
.return_value
= mock_alarm
215 mock_alarm_2
= self
._build
_mock
_alarm
(
216 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="AND"
219 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
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")
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
233 Tests scale out with AND operation, only one alarm triggered.
235 future
= asyncio
.Future(loop
=self
.loop
)
236 future
.set_result("mock")
237 scale
.return_value
= future
239 mock_alarm
= self
._build
_mock
_alarm
(
240 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="AND"
242 get_alarm
.return_value
= mock_alarm
244 mock_alarm_2
= self
._build
_mock
_alarm
(
245 action
="scale_out", last_status
="ok", enabled
=True, scale_out_op
="OR"
248 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
250 service
= AutoscalingService(self
.config
)
251 self
.loop
.run_until_complete(service
.evaluate_policy("test_uuid"))
252 scale
.assert_not_called()
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
262 Tests scale out with OR operation, both alarms triggered
264 future
= asyncio
.Future(loop
=self
.loop
)
265 future
.set_result("mock")
266 scale
.return_value
= future
268 mock_alarm
= self
._build
_mock
_alarm
(
269 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="OR"
271 get_alarm
.return_value
= mock_alarm
273 mock_alarm_2
= self
._build
_mock
_alarm
(
274 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="OR"
277 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
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")
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
291 Tests scale out with OR operation, only one alarm triggered
293 future
= asyncio
.Future(loop
=self
.loop
)
294 future
.set_result("mock")
295 scale
.return_value
= future
297 mock_alarm
= self
._build
_mock
_alarm
(
298 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="OR"
300 get_alarm
.return_value
= mock_alarm
302 mock_alarm_2
= self
._build
_mock
_alarm
(
303 action
="scale_out", last_status
="ok", enabled
=True, scale_out_op
="OR"
306 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
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")
312 def _build_mock_alarm(
316 last_scale
=datetime
.datetime
.min,
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"