Fix pylint issues appeared with version 3.2.0 of pylint
[osm/POL.git] / osm_policy_module / tests / integration / test_policy_agent.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 logging
26 import os
27 import sys
28 import unittest
29 import uuid
30 from unittest.mock import patch, Mock
31
32 from kafka import KafkaProducer
33 from osm_common.dbmongo import DbMongo
34 from playhouse.db_url import connect
35
36 from osm_policy_module.common.common_db_client import CommonDbClient
37 from osm_policy_module.common.mon_client import MonClient
38 from osm_policy_module.core import database
39 from osm_policy_module.core.agent import PolicyModuleAgent
40 from osm_policy_module.core.config import Config
41 from osm_policy_module.core.database import (
42 ScalingGroup,
43 ScalingAlarm,
44 ScalingPolicy,
45 ScalingCriteria,
46 VnfAlarm,
47 AlarmAction,
48 HealingAction,
49 )
50
51 log = logging.getLogger()
52 log.level = logging.INFO
53 stream_handler = logging.StreamHandler(sys.stdout)
54 log.addHandler(stream_handler)
55
56 nsr_record_mock = {
57 "_id": "87776f33-b67c-417a-8119-cb08e4098951",
58 "crete-time": 1535392482.0044956,
59 "operational-status": "running",
60 "ssh-authorized-key": None,
61 "name-ref": "cirros_ns",
62 "nsd": {
63 "_id": "d7c8bd3c-eb39-4514-8847-19f01345524f",
64 "_admin": {
65 "created": 1535392246.499733,
66 "userDefinedData": {},
67 "usageSate": "NOT_IN_USE",
68 "storage": {
69 "zipfile": "package.tar.gz",
70 "fs": "local",
71 "path": "/app/storage/",
72 "folder": "d7c8bd3c-eb39-4514-8847-19f01345524f",
73 "pkg-dir": "cirros_nsd",
74 "descriptor": "cirros_nsd/cirros_vdu_scaling_nsd.yaml",
75 },
76 "onboardingState": "ONBOARDED",
77 "modified": 1535392246.499733,
78 "projects_read": ["admin"],
79 "operationalState": "ENABLED",
80 "projects_write": ["admin"],
81 },
82 "id": "cirros_vdu_scaling_ns",
83 "name": "cirros_vdu_scaling_ns",
84 "description": "Simple NS example with a cirros_vdu_scaling_vnf",
85 "designer": "OSM",
86 "version": "1.0",
87 "vnfd-id": ["cirros_vdu_scaling_vnf"],
88 "df": [
89 {
90 "id": "default-df",
91 "vnf-profile": [
92 {
93 "id": "1",
94 "vnfd-id": "cirros_vdu_scaling_vnf",
95 "virtual-link-connectivity": [
96 {
97 "virtual-link-profile-id": "cirros_nsd_vld1",
98 "constituent-cpd-id": [
99 {
100 "constituent-base-element-id": "1",
101 "constituent-cpd-id": "eth0-ext",
102 }
103 ],
104 }
105 ],
106 },
107 {
108 "id": "2",
109 "vnfd-id": "cirros_vdu_scaling_vnf",
110 "virtual-link-connectivity": [
111 {
112 "virtual-link-profile-id": "cirros_nsd_vld1",
113 "constituent-cpd-id": [
114 {
115 "constituent-base-element-id": "2",
116 "constituent-cpd-id": "eth0-ext",
117 }
118 ],
119 }
120 ],
121 },
122 ],
123 }
124 ],
125 "virtual-link-desc": [{"id": "cirros_nsd_vld1", "mgmt-network": "true"}],
126 },
127 "id": "87776f33-b67c-417a-8119-cb08e4098951",
128 "config-status": "configured",
129 "operational-events": [],
130 "_admin": {
131 "created": 1535392482.0084584,
132 "projects_read": ["admin"],
133 "nsState": "INSTANTIATED",
134 "modified": 1535392482.0084584,
135 "projects_write": ["admin"],
136 "deployed": {
137 "RO": {
138 "vnfd_id": {
139 "cirros_vdu_scaling_vnf": "7445e347-fe2f-431a-abc2-8b9be3d093c6"
140 },
141 "nsd_id": "92c56cf0-f8fa-488c-9afb-9f3d78ae6bbb",
142 "nsr_id": "637e12cd-c201-4c44-8ebd-70fb57a4dcee",
143 "nsr_status": "BUILD",
144 }
145 },
146 },
147 "nsd-ref": "cirros_vdu_scaling_ns",
148 "name": "cirros_ns",
149 "resource-orchestrator": "osmopenmano",
150 "instantiate_params": {
151 "nsDescription": "default description",
152 "nsdId": "d7c8bd3c-eb39-4514-8847-19f01345524f",
153 "nsr_id": "87776f33-b67c-417a-8119-cb08e4098951",
154 "nsName": "cirros_ns",
155 "vimAccountId": "be48ae31-1d46-4892-a4b4-d69abd55714b",
156 },
157 "description": "default description",
158 "constituent-vnfr-ref": [
159 "0d9d06ad-3fc2-418c-9934-465e815fafe2",
160 "3336eb44-77df-4c4f-9881-d2828d259864",
161 ],
162 "admin-status": "ENABLED",
163 "detailed-status": "done",
164 "datacenter": "be48ae31-1d46-4892-a4b4-d69abd55714b",
165 "orchestration-progress": {},
166 "short-name": "cirros_ns",
167 "ns-instance-config-ref": "87776f33-b67c-417a-8119-cb08e4098951",
168 "nsd-name-ref": "cirros_vdu_scaling_ns",
169 "admin": {"deployed": {"RO": {"nsr_status": "ACTIVE"}}},
170 }
171
172 vnfr_record_mocks = [
173 {
174 "_id": "0d9d06ad-3fc2-418c-9934-465e815fafe2",
175 "ip-address": "192.168.160.2",
176 "created-time": 1535392482.0044956,
177 "vim-account-id": "be48ae31-1d46-4892-a4b4-d69abd55714b",
178 "vdur": [
179 {
180 "interfaces": [
181 {
182 "mac-address": "fa:16:3e:71:fd:b8",
183 "name": "eth0",
184 "ip-address": "192.168.160.2",
185 }
186 ],
187 "count-index": 0,
188 "status": "ACTIVE",
189 "vim-id": "63a65636-9fc8-4022-b070-980823e6266a",
190 "name": "cirros_ns-1-cirros_vnfd-VM-1",
191 "status-detailed": None,
192 "ip-address": "192.168.160.2",
193 "vdu-id-ref": "cirros_vnfd-VM",
194 }
195 ],
196 "id": "0d9d06ad-3fc2-418c-9934-465e815fafe2",
197 "vnfd-ref": "cirros_vdu_scaling_vnf",
198 "vnfd-id": "63f44c41-45ee-456b-b10d-5f08fb1796e0",
199 "_admin": {
200 "created": 1535392482.0067868,
201 "projects_read": ["admin"],
202 "modified": 1535392482.0067868,
203 "projects_write": ["admin"],
204 },
205 "nsr-id-ref": "87776f33-b67c-417a-8119-cb08e4098951",
206 "member-vnf-index-ref": "1",
207 "connection-point": [{"name": "eth0", "id": None, "connection-point-id": None}],
208 },
209 {
210 "_id": "3336eb44-77df-4c4f-9881-d2828d259864",
211 "ip-address": "192.168.160.10",
212 "created-time": 1535392482.0044956,
213 "vim-account-id": "be48ae31-1d46-4892-a4b4-d69abd55714b",
214 "vdur": [
215 {
216 "interfaces": [
217 {
218 "mac-address": "fa:16:3e:1e:76:e8",
219 "name": "eth0",
220 "ip-address": "192.168.160.10",
221 }
222 ],
223 "count-index": 0,
224 "status": "ACTIVE",
225 "vim-id": "a154b8d3-2b10-421a-a51d-4b391d9bd366",
226 "name": "cirros_ns-2-cirros_vnfd-VM-1",
227 "status-detailed": None,
228 "ip-address": "192.168.160.10",
229 "vdu-id-ref": "cirros_vnfd-VM",
230 }
231 ],
232 "id": "3336eb44-77df-4c4f-9881-d2828d259864",
233 "vnfd-ref": "cirros_vdu_scaling_vnf",
234 "vnfd-id": "63f44c41-45ee-456b-b10d-5f08fb1796e0",
235 "_admin": {
236 "created": 1535392482.0076294,
237 "projects_read": ["admin"],
238 "modified": 1535392482.0076294,
239 "projects_write": ["admin"],
240 },
241 "nsr-id-ref": "87776f33-b67c-417a-8119-cb08e4098951",
242 "member-vnf-index-ref": "2",
243 "connection-point": [{"name": "eth0", "id": None, "connection-point-id": None}],
244 },
245 ]
246
247 nsd_record_mock = {
248 "id": "cirros_vdu_scaling_ns",
249 "name": "cirros_vdu_scaling_ns",
250 "description": "Simple NS example with a cirros_vdu_scaling_vnf",
251 "designer": "OSM",
252 "version": "1.0",
253 "vnfd-id": ["cirros_vdu_scaling_vnf"],
254 "df": [
255 {
256 "id": "default-df",
257 "vnf-profile": [
258 {
259 "id": "1",
260 "vnfd-id": "cirros_vdu_scaling_vnf",
261 "virtual-link-connectivity": [
262 {
263 "virtual-link-profile-id": "cirros_nsd_vld1",
264 "constituent-cpd-id": [
265 {
266 "constituent-base-element-id": "1",
267 "constituent-cpd-id": "eth0-ext",
268 }
269 ],
270 }
271 ],
272 },
273 {
274 "id": "2",
275 "vnfd-id": "cirros_vdu_scaling_vnf",
276 "virtual-link-connectivity": [
277 {
278 "virtual-link-profile-id": "cirros_nsd_vld1",
279 "constituent-cpd-id": [
280 {
281 "constituent-base-element-id": "2",
282 "constituent-cpd-id": "eth0-ext",
283 }
284 ],
285 }
286 ],
287 },
288 ],
289 }
290 ],
291 "virtual-link-desc": [{"id": "cirros_nsd_vld1", "mgmt-network": "true"}],
292 }
293
294
295 vnfd_record_mock = {
296 "id": "cirros_vdu_scaling_vnf",
297 "_id": "63f44c41-45ee-456b-b10d-5f08fb1796e0",
298 "product-name": "cirros_vdu_scaling_vnf",
299 "description": "Simple VNF example with a cirros and a scaling group descriptor",
300 "provider": "OSM",
301 "version": "1.0",
302 "mgmt-cp": "eth0-ext",
303 "virtual-storage-desc": [{"id": "cirros_vnfd-VM-storage", "size-of-storage": 2}],
304 "virtual-compute-desc": [
305 {
306 "id": "cirros_vnfd-VM-compute",
307 "virtual-cpu": {"num-virtual-cpu": 1},
308 "virtual-memory": {"size": 0.25},
309 }
310 ],
311 "sw-image-desc": [{"id": "cirros034", "name": "cirros034", "image": "cirros034"}],
312 "vdu": [
313 {
314 "id": "cirros_vnfd-VM",
315 "description": "cirros_vnfd-VM",
316 "name": "cirros_vnfd-VM",
317 "alarm": [
318 {
319 "value": 20.0,
320 "actions": {
321 "insufficient-data": [{"url": "localhost:9090"}],
322 "ok": [{"url": "localhost:9090"}],
323 "alarm": [{"url": "localhost:9090"}],
324 },
325 "alarm-id": "alarm-1",
326 "operation": "LT",
327 "vnf-monitoring-param-ref": "cirros_vnf_memory_util",
328 }
329 ],
330 "sw-image-desc": "cirros034",
331 "virtual-compute-desc": "cirros_vnfd-VM-compute",
332 "virtual-storage-desc": ["cirros_vnfd-VM-storage"],
333 "int-cpd": [
334 {
335 "id": "eth0-int",
336 "virtual-network-interface-requirement": [
337 {
338 "name": "eth0",
339 "virtual-interface": {
340 "bandwidth": "0",
341 "type": "VIRTIO",
342 "vpci": "0000:00:0a.0",
343 },
344 }
345 ],
346 }
347 ],
348 "monitoring-parameter": [
349 {
350 "id": "cirros_vnf_memory_util",
351 "name": "cirros_vnf_memory_util",
352 "performance-metric": "average_memory_utilization",
353 }
354 ],
355 }
356 ],
357 "df": [
358 {
359 "id": "default-df",
360 "vdu-profile": [
361 {
362 "id": "cirros_vnfd-VM",
363 "min-number-of-instances": 1,
364 "max-number-of-instances": 10,
365 "vdu-configuration-id": "cirros_vnfd-VM-vdu-configuration",
366 }
367 ],
368 "healing-aspect": [
369 {
370 "id": "cirros_vnfd-VM-autoheal",
371 "healing-policy": [
372 {
373 "vdu-id": "cirros_vnfd-VM",
374 "event-name": "heal-alarm",
375 "recovery-type": "automatic",
376 "action-on-recovery": "REDEPLOY_ONLY",
377 "cooldown-time": 180,
378 "day1": False,
379 }
380 ],
381 }
382 ],
383 "instantiation-level": [
384 {
385 "id": "default-instantiation-level",
386 "vdu-level": [
387 {"vdu-id": "cirros_vnfd-VM", "number-of-instances": 1}
388 ],
389 }
390 ],
391 "scaling-aspect": [
392 {
393 "id": "scale_cirros_vnfd-VM",
394 "name": "scale_cirros_vnfd-VM",
395 "max-scale-level": 10,
396 "scaling-policy": [
397 {
398 "name": "auto_memory_util_above_threshold",
399 "scaling-type": "automatic",
400 "cooldown-time": 60,
401 "threshold-time": 10,
402 "scaling-criteria": [
403 {
404 "name": "group1_memory_util_above_threshold",
405 "vnf-monitoring-param-ref": "cirros_vnf_memory_util",
406 "scale-out-threshold": 80,
407 "scale-out-relational-operation": "GT",
408 "scale-in-relational-operation": "LT",
409 "scale-in-threshold": 20,
410 }
411 ],
412 }
413 ],
414 "aspect-delta-details": {
415 "deltas": [
416 {
417 "id": "scale_cirros_vnfd-VM-delta",
418 "vdu-delta": [
419 {"number-of-instances": 1, "id": "cirros_vnfd-VM"}
420 ],
421 }
422 ]
423 },
424 }
425 ],
426 }
427 ],
428 "ext-cpd": [
429 {"id": "eth0-ext", "int-cpd": {"vdu-id": "cirros_vnfd-VM", "cpd": "eth0-int"}}
430 ],
431 "vdu-configuration": [
432 {
433 "juju": {"charm": "testmetrics", "proxy": True},
434 "metrics": [{"name": "users"}],
435 "id": "cirros_vnfd-VM-vdu-configuration",
436 }
437 ],
438 "_admin": {
439 "created": 1535392242.6281035,
440 "modified": 1535392242.6281035,
441 "storage": {
442 "zipfile": "package.tar.gz",
443 "pkg-dir": "cirros_vnf",
444 "path": "/app/storage/",
445 "folder": "63f44c41-45ee-456b-b10d-5f08fb1796e0",
446 "fs": "local",
447 "descriptor": "cirros_vnf/cirros_vdu_scaling_vnfd.yaml",
448 },
449 "usageSate": "NOT_IN_USE",
450 "onboardingState": "ONBOARDED",
451 "userDefinedData": {},
452 "projects_read": ["admin"],
453 "operationalState": "ENABLED",
454 "projects_write": ["admin"],
455 },
456 }
457
458 MODELS = [
459 ScalingGroup,
460 ScalingPolicy,
461 ScalingCriteria,
462 ScalingAlarm,
463 VnfAlarm,
464 AlarmAction,
465 HealingAction,
466 ]
467
468
469 class PolicyModuleAgentTest(unittest.TestCase):
470 def setUp(self):
471 super()
472 database.db.initialize(connect("sqlite:///test_db.sqlite"))
473 database.db.bind(MODELS)
474 database.db.connect()
475 database.db.drop_tables(MODELS)
476 database.db.create_tables(MODELS)
477 database.db.close()
478 self.loop = asyncio.new_event_loop()
479
480 def tearDown(self):
481 super()
482 os.remove("test_db.sqlite")
483
484 @patch.object(DbMongo, "db_connect", Mock())
485 @patch.object(KafkaProducer, "__init__")
486 @patch.object(MonClient, "create_alarm")
487 @patch.object(CommonDbClient, "get_vnfd")
488 @patch.object(CommonDbClient, "get_nsr")
489 @patch.object(CommonDbClient, "get_vnfr")
490 def test_configure_scaling_groups(
491 self, get_vnfr, get_nsr, get_vnfd, create_alarm, kafka_producer_init
492 ):
493 def _test_configure_scaling_groups_get_vnfr(*args, **kwargs):
494 if "1" in args[1]:
495 return vnfr_record_mocks[0]
496 if "2" in args[1]:
497 return vnfr_record_mocks[1]
498
499 def assert_not_called_with(*args, **kwargs):
500 try:
501 create_alarm.assert_called_with(*args, **kwargs)
502 except AssertionError:
503 return
504 raise AssertionError("Expected to not have been called.")
505
506 async def _test_configure_scaling_groups_create_alarm(*args, **kwargs):
507 return uuid.uuid4()
508
509 kafka_producer_init.return_value = None
510 get_vnfr.side_effect = _test_configure_scaling_groups_get_vnfr
511 get_nsr.return_value = nsr_record_mock
512 get_vnfd.return_value = vnfd_record_mock
513 create_alarm.side_effect = _test_configure_scaling_groups_create_alarm
514 create_alarm.assert_not_called_with = assert_not_called_with
515 config = Config()
516 agent = PolicyModuleAgent(config)
517 self.loop.run_until_complete(
518 agent.autoscaling_service.configure_scaling_groups("test_nsr_id")
519 )
520 create_alarm.assert_any_call(
521 metric_name="average_memory_utilization",
522 ns_id="test_nsr_id",
523 operation="GT",
524 threshold=80,
525 vdu_name="cirros_ns-1-cirros_vnfd-VM-1",
526 vnf_member_index="1",
527 action="scale_out",
528 vnfr=vnfr_record_mocks[0],
529 vnfd=vnfd_record_mock,
530 )
531 create_alarm.assert_not_called_with(
532 metric_name="average_memory_utilization",
533 ns_id="test_nsr_id",
534 operation="LT",
535 threshold=20,
536 vdu_name="cirros_ns-1-cirros_vnfd-VM-1",
537 vnf_member_index="1",
538 action="scale_out",
539 vnfr=vnfr_record_mocks[0],
540 vnfd=vnfd_record_mock,
541 )
542 create_alarm.assert_any_call(
543 metric_name="average_memory_utilization",
544 ns_id="test_nsr_id",
545 operation="GT",
546 threshold=80,
547 vdu_name="cirros_ns-2-cirros_vnfd-VM-1",
548 vnf_member_index="2",
549 action="scale_out",
550 vnfr=vnfr_record_mocks[1],
551 vnfd=vnfd_record_mock,
552 )
553 create_alarm.assert_not_called_with(
554 metric_name="average_memory_utilization",
555 ns_id="test_nsr_id",
556 operation="LT",
557 threshold=20,
558 vdu_name="cirros_ns-2-cirros_vnfd-VM-1",
559 vnf_member_index="2",
560 action="scale_out",
561 vnfr=vnfr_record_mocks[1],
562 vnfd=vnfd_record_mock,
563 )
564 scaling_record = ScalingGroup.get()
565 self.assertEqual(scaling_record.name, "scale_cirros_vnfd-VM")
566 self.assertEqual(scaling_record.nsr_id, "test_nsr_id")
567
568 @patch.object(DbMongo, "db_connect", Mock())
569 @patch.object(KafkaProducer, "__init__")
570 @patch.object(MonClient, "create_alarm")
571 @patch.object(CommonDbClient, "get_vnfd")
572 @patch.object(CommonDbClient, "get_nsr")
573 @patch.object(CommonDbClient, "get_vnfr")
574 def test_configure_vnf_alarms(
575 self, get_vnfr, get_nsr, get_vnfd, create_alarm, kafka_producer_init
576 ):
577 def _test_configure_scaling_groups_get_vnfr(*args, **kwargs):
578 if "1" in args[1]:
579 return vnfr_record_mocks[0]
580 if "2" in args[1]:
581 return vnfr_record_mocks[1]
582
583 async def _test_configure_vnf_alarms_create_alarm(*args, **kwargs):
584 return uuid.uuid4()
585
586 kafka_producer_init.return_value = None
587 get_vnfr.side_effect = _test_configure_scaling_groups_get_vnfr
588 get_nsr.return_value = nsr_record_mock
589 get_vnfd.return_value = vnfd_record_mock
590 create_alarm.side_effect = _test_configure_vnf_alarms_create_alarm
591 config = Config()
592 agent = PolicyModuleAgent(config)
593 self.loop.run_until_complete(
594 agent.alarming_service.configure_vnf_alarms("test_nsr_id")
595 )
596 create_alarm.assert_any_call(
597 metric_name="average_memory_utilization",
598 ns_id="test_nsr_id",
599 vdu_name="cirros_ns-1-cirros_vnfd-VM-1",
600 vnf_member_index="1",
601 threshold=20.0,
602 operation="LT",
603 action="{'webhook': ['localhost:9090', 'localhost:9090', 'localhost:9090']}",
604 vnfr=vnfr_record_mocks[0],
605 vnfd=vnfd_record_mock,
606 )
607 create_alarm.assert_any_call(
608 metric_name="average_memory_utilization",
609 ns_id="test_nsr_id",
610 vdu_name="cirros_ns-2-cirros_vnfd-VM-1",
611 vnf_member_index="2",
612 threshold=20.0,
613 operation="LT",
614 action="{'webhook': ['localhost:9090', 'localhost:9090', 'localhost:9090']}",
615 vnfr=vnfr_record_mocks[1],
616 vnfd=vnfd_record_mock,
617 )
618
619 @patch.object(DbMongo, "db_connect", Mock())
620 @patch.object(KafkaProducer, "__init__")
621 @patch.object(MonClient, "create_alarm")
622 @patch.object(CommonDbClient, "get_vnfd")
623 @patch.object(CommonDbClient, "get_nsr")
624 @patch.object(CommonDbClient, "get_vnfr")
625 def test_configure_healing_alarms(
626 self, get_vnfr, get_nsr, get_vnfd, create_alarm, kafka_producer_init
627 ):
628 def _test_configure_scaling_groups_get_vnfr(*args, **kwargs):
629 if "1" in args[1]:
630 return vnfr_record_mocks[0]
631 if "2" in args[1]:
632 return vnfr_record_mocks[1]
633
634 async def _test_configure_healing_alarms_create_alarm(*args, **kwargs):
635 return uuid.uuid4()
636
637 kafka_producer_init.return_value = None
638 get_vnfr.side_effect = _test_configure_scaling_groups_get_vnfr
639 get_nsr.return_value = nsr_record_mock
640 get_vnfd.return_value = vnfd_record_mock
641 create_alarm.side_effect = _test_configure_healing_alarms_create_alarm
642 config = Config()
643 agent = PolicyModuleAgent(config)
644 self.loop.run_until_complete(
645 agent.healing_service.configure_healing_alarms("test_nsr_id")
646 )
647 create_alarm.assert_any_call(
648 metric_name="vm_status",
649 ns_id="test_nsr_id",
650 vdu_name="cirros_ns-1-cirros_vnfd-VM-1",
651 vnf_member_index="1",
652 threshold=1,
653 operation="LT",
654 statistic="AVERAGE",
655 )
656 create_alarm.assert_any_call(
657 metric_name="vm_status",
658 ns_id="test_nsr_id",
659 vdu_name="cirros_ns-2-cirros_vnfd-VM-1",
660 vnf_member_index="2",
661 threshold=1,
662 operation="LT",
663 statistic="AVERAGE",
664 )
665
666
667 if __name__ == "__main__":
668 unittest.main()