1588486dea493b85c6021933c79425ec676d79ce
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()
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
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()
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()
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()
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
73 service
= AutoscalingService(self
.config
)
74 asyncio
.run(service
.evaluate_policy("test_uuid"))
75 list_alarms
.assert_not_called()
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
85 Tests scale in with AND operation, both alarms triggered
87 future
= asyncio
.Future(loop
=asyncio
.new_event_loop())
88 future
.set_result("mock")
89 scale
.return_value
= future
91 mock_alarm
= self
._build
_mock
_alarm
(
92 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="AND"
94 get_alarm
.return_value
= mock_alarm
96 mock_alarm_2
= self
._build
_mock
_alarm
(
97 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="AND"
100 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
102 service
= AutoscalingService(self
.config
)
103 if self
.config
.get("autoscale", "enabled") == "True":
104 asyncio
.run(service
.evaluate_policy("test_uuid"))
105 scale
.assert_called_with("test_nsr_id", "test_group", "1", "scale_in")
107 @mock.patch
.object(ScalingAlarmRepository
, "list")
108 @mock.patch
.object(ScalingAlarmRepository
, "get")
109 @mock.patch
.object(LcmClient
, "scale")
110 @mock.patch("osm_policy_module.core.database.db")
111 def test_evaluate_policy_scale_in_and_diff(
112 self
, database
, scale
, get_alarm
, list_alarms
115 Tests scale in with AND operation, only one alarm triggered.
117 future
= asyncio
.Future(loop
=asyncio
.new_event_loop())
118 future
.set_result("mock")
119 scale
.return_value
= future
121 mock_alarm
= self
._build
_mock
_alarm
(
122 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="AND"
124 get_alarm
.return_value
= mock_alarm
126 mock_alarm_2
= self
._build
_mock
_alarm
(
127 action
="scale_in", last_status
="ok", enabled
=True, scale_in_op
="OR"
130 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
132 service
= AutoscalingService(self
.config
)
133 if self
.config
.get("autoscale", "enabled") == "True":
134 asyncio
.run(service
.evaluate_policy("test_uuid"))
135 scale
.assert_not_called()
137 @mock.patch
.object(ScalingAlarmRepository
, "list")
138 @mock.patch
.object(ScalingAlarmRepository
, "get")
139 @mock.patch
.object(LcmClient
, "scale")
140 @mock.patch("osm_policy_module.core.database.db")
141 def test_evaluate_policy_scale_in_or_equal(
142 self
, database
, scale
, get_alarm
, list_alarms
145 Tests scale in with OR operation, both alarms triggered
147 future
= asyncio
.Future(loop
=asyncio
.new_event_loop())
148 future
.set_result("mock")
149 scale
.return_value
= future
151 mock_alarm
= self
._build
_mock
_alarm
(
152 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="OR"
154 get_alarm
.return_value
= mock_alarm
156 mock_alarm_2
= self
._build
_mock
_alarm
(
157 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="OR"
160 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
162 service
= AutoscalingService(self
.config
)
163 if self
.config
.get("autoscale", "enabled") == "True":
164 asyncio
.run(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
=asyncio
.new_event_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 if self
.config
.get("autoscale", "enabled") == "True":
194 asyncio
.run(service
.evaluate_policy("test_uuid"))
195 scale
.assert_called_with("test_nsr_id", "test_group", "1", "scale_in")
197 @mock.patch
.object(ScalingAlarmRepository
, "list")
198 @mock.patch
.object(ScalingAlarmRepository
, "get")
199 @mock.patch
.object(LcmClient
, "scale")
200 @mock.patch("osm_policy_module.core.database.db")
201 def test_evaluate_policy_scale_out_and_equal(
202 self
, database
, scale
, get_alarm
, list_alarms
205 Tests scale out with AND operation, both alarms triggered
207 future
= asyncio
.Future(loop
=asyncio
.new_event_loop())
208 future
.set_result("mock")
209 scale
.return_value
= future
211 mock_alarm
= self
._build
_mock
_alarm
(
212 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="AND"
214 get_alarm
.return_value
= mock_alarm
216 mock_alarm_2
= self
._build
_mock
_alarm
(
217 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="AND"
220 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
222 service
= AutoscalingService(self
.config
)
223 if self
.config
.get("autoscale", "enabled") == "True":
224 asyncio
.run(service
.evaluate_policy("test_uuid"))
225 scale
.assert_called_with("test_nsr_id", "test_group", "1", "scale_out")
227 @mock.patch
.object(ScalingAlarmRepository
, "list")
228 @mock.patch
.object(ScalingAlarmRepository
, "get")
229 @mock.patch
.object(LcmClient
, "scale")
230 @mock.patch("osm_policy_module.core.database.db")
231 def test_evaluate_policy_scale_out_and_diff(
232 self
, database
, scale
, get_alarm
, list_alarms
235 Tests scale out with AND operation, only one alarm triggered.
237 future
= asyncio
.Future(loop
=asyncio
.new_event_loop())
238 future
.set_result("mock")
239 scale
.return_value
= future
241 mock_alarm
= self
._build
_mock
_alarm
(
242 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="AND"
244 get_alarm
.return_value
= mock_alarm
246 mock_alarm_2
= self
._build
_mock
_alarm
(
247 action
="scale_out", last_status
="ok", enabled
=True, scale_out_op
="OR"
250 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
252 service
= AutoscalingService(self
.config
)
253 if self
.config
.get("autoscale", "enabled") == "True":
254 asyncio
.run(service
.evaluate_policy("test_uuid"))
255 scale
.assert_not_called()
257 @mock.patch
.object(ScalingAlarmRepository
, "list")
258 @mock.patch
.object(ScalingAlarmRepository
, "get")
259 @mock.patch
.object(LcmClient
, "scale")
260 @mock.patch("osm_policy_module.core.database.db")
261 def test_evaluate_policy_scale_out_or_equal(
262 self
, database
, scale
, get_alarm
, list_alarms
265 Tests scale out with OR operation, both alarms triggered
267 future
= asyncio
.Future(loop
=asyncio
.new_event_loop())
268 future
.set_result("mock")
269 scale
.return_value
= future
271 mock_alarm
= self
._build
_mock
_alarm
(
272 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="OR"
274 get_alarm
.return_value
= mock_alarm
276 mock_alarm_2
= self
._build
_mock
_alarm
(
277 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="OR"
280 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
282 service
= AutoscalingService(self
.config
)
283 asyncio
.run(service
.evaluate_policy("test_uuid"))
284 if self
.config
.get("autoscale", "enabled") == "True":
285 asyncio
.run(service
.evaluate_policy("test_uuid"))
286 scale
.assert_called_with("test_nsr_id", "test_group", "1", "scale_out")
288 @mock.patch
.object(ScalingAlarmRepository
, "list")
289 @mock.patch
.object(ScalingAlarmRepository
, "get")
290 @mock.patch
.object(LcmClient
, "scale")
291 @mock.patch("osm_policy_module.core.database.db")
292 def test_evaluate_policy_scale_out_or_diff(
293 self
, database
, scale
, get_alarm
, list_alarms
296 Tests scale out with OR operation, only one alarm triggered
298 future
= asyncio
.Future(loop
=asyncio
.new_event_loop())
299 future
.set_result("mock")
300 scale
.return_value
= future
302 mock_alarm
= self
._build
_mock
_alarm
(
303 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="OR"
305 get_alarm
.return_value
= mock_alarm
307 mock_alarm_2
= self
._build
_mock
_alarm
(
308 action
="scale_out", last_status
="ok", enabled
=True, scale_out_op
="OR"
311 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
313 service
= AutoscalingService(self
.config
)
314 asyncio
.run(service
.evaluate_policy("test_uuid"))
315 if self
.config
.get("autoscale", "enabled") == "True":
316 asyncio
.run(service
.evaluate_policy("test_uuid"))
317 scale
.assert_called_with("test_nsr_id", "test_group", "1", "scale_out")
319 def _build_mock_alarm(
323 last_scale
=datetime
.datetime
.min,
329 mock_alarm
= mock
.Mock()
330 mock_alarm
.action
= action
331 mock_alarm
.last_status
= last_status
332 mock_alarm
.vnf_member_index
= "1"
333 mock_alarm
.scaling_criteria
.scaling_policy
.last_scale
= last_scale
334 mock_alarm
.scaling_criteria
.scaling_policy
.cooldown_time
= cooldown_time
335 mock_alarm
.scaling_criteria
.scaling_policy
.enabled
= enabled
336 mock_alarm
.scaling_criteria
.scaling_policy
.scale_in_operation
= scale_in_op
337 mock_alarm
.scaling_criteria
.scaling_policy
.scale_out_operation
= scale_out_op
338 mock_alarm
.scaling_criteria
.scaling_policy
.scaling_group
.nsr_id
= "test_nsr_id"
339 mock_alarm
.scaling_criteria
.scaling_policy
.scaling_group
.name
= "test_group"