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 asyncio
.run(service
.evaluate_policy("test_uuid"))
104 scale
.assert_called_with("test_nsr_id", "test_group", "1", "scale_in")
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
114 Tests scale in with AND operation, only one alarm triggered.
116 future
= asyncio
.Future(loop
=asyncio
.new_event_loop())
117 future
.set_result("mock")
118 scale
.return_value
= future
120 mock_alarm
= self
._build
_mock
_alarm
(
121 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="AND"
123 get_alarm
.return_value
= mock_alarm
125 mock_alarm_2
= self
._build
_mock
_alarm
(
126 action
="scale_in", last_status
="ok", enabled
=True, scale_in_op
="OR"
129 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
131 service
= AutoscalingService(self
.config
)
132 asyncio
.run(service
.evaluate_policy("test_uuid"))
133 scale
.assert_not_called()
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
143 Tests scale in with OR operation, both alarms triggered
145 future
= asyncio
.Future(loop
=asyncio
.new_event_loop())
146 future
.set_result("mock")
147 scale
.return_value
= future
149 mock_alarm
= self
._build
_mock
_alarm
(
150 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="OR"
152 get_alarm
.return_value
= mock_alarm
154 mock_alarm_2
= self
._build
_mock
_alarm
(
155 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="OR"
158 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
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")
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
172 Tests scale in with OR operation, only one alarm triggered
174 future
= asyncio
.Future(loop
=asyncio
.new_event_loop())
175 future
.set_result("mock")
176 scale
.return_value
= future
178 mock_alarm
= self
._build
_mock
_alarm
(
179 action
="scale_in", last_status
="alarm", enabled
=True, scale_in_op
="OR"
181 get_alarm
.return_value
= mock_alarm
183 mock_alarm_2
= self
._build
_mock
_alarm
(
184 action
="scale_in", last_status
="ok", enabled
=True, scale_in_op
="OR"
187 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
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")
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
201 Tests scale out with AND operation, both alarms triggered
203 future
= asyncio
.Future(loop
=asyncio
.new_event_loop())
204 future
.set_result("mock")
205 scale
.return_value
= future
207 mock_alarm
= self
._build
_mock
_alarm
(
208 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="AND"
210 get_alarm
.return_value
= mock_alarm
212 mock_alarm_2
= self
._build
_mock
_alarm
(
213 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="AND"
216 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
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")
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
230 Tests scale out with AND operation, only one alarm triggered.
232 future
= asyncio
.Future(loop
=asyncio
.new_event_loop())
233 future
.set_result("mock")
234 scale
.return_value
= future
236 mock_alarm
= self
._build
_mock
_alarm
(
237 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="AND"
239 get_alarm
.return_value
= mock_alarm
241 mock_alarm_2
= self
._build
_mock
_alarm
(
242 action
="scale_out", last_status
="ok", enabled
=True, scale_out_op
="OR"
245 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
247 service
= AutoscalingService(self
.config
)
248 asyncio
.run(service
.evaluate_policy("test_uuid"))
249 scale
.assert_not_called()
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
259 Tests scale out with OR operation, both alarms triggered
261 future
= asyncio
.Future(loop
=asyncio
.new_event_loop())
262 future
.set_result("mock")
263 scale
.return_value
= future
265 mock_alarm
= self
._build
_mock
_alarm
(
266 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="OR"
268 get_alarm
.return_value
= mock_alarm
270 mock_alarm_2
= self
._build
_mock
_alarm
(
271 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="OR"
274 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
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")
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
288 Tests scale out with OR operation, only one alarm triggered
290 future
= asyncio
.Future(loop
=asyncio
.new_event_loop())
291 future
.set_result("mock")
292 scale
.return_value
= future
294 mock_alarm
= self
._build
_mock
_alarm
(
295 action
="scale_out", last_status
="alarm", enabled
=True, scale_out_op
="OR"
297 get_alarm
.return_value
= mock_alarm
299 mock_alarm_2
= self
._build
_mock
_alarm
(
300 action
="scale_out", last_status
="ok", enabled
=True, scale_out_op
="OR"
303 list_alarms
.return_value
= [mock_alarm
, mock_alarm_2
]
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")
309 def _build_mock_alarm(
313 last_scale
=datetime
.datetime
.min,
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"