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