update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b second try
[osm/SO.git] / rwlaunchpad / ra / pytest / ns / test_multiple_ns_instantiation.py
1 #!/usr/bin/env python
2 #
3 # Copyright 2016-2017 RIFT.io Inc
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #
17 import gi
18 import numpy as np
19 import os
20 import pytest
21 import random
22 import time
23
24 import rift.auto.descriptor
25 from rift.auto.os_utils import get_mem_usage, print_mem_usage
26 gi.require_version('RwNsrYang', '1.0')
27 gi.require_version('RwProjectNsdYang', '1.0')
28 gi.require_version('RwVnfrYang', '1.0')
29 gi.require_version('RwProjectVnfdYang', '1.0')
30 from gi.repository import (
31 RwNsrYang,
32 RwVnfrYang,
33 RwVlrYang,
34 RwProjectNsdYang,
35 RwProjectVnfdYang,
36 )
37 gi.require_version('RwKeyspec', '1.0')
38 from gi.repository.RwKeyspec import quoted_key
39
40
41 @pytest.fixture(scope='module')
42 def rwvnfr_proxy(request, mgmt_session):
43 return mgmt_session.proxy(RwVnfrYang)
44
45
46 @pytest.fixture(scope='module')
47 def rwvlr_proxy(request, mgmt_session):
48 return mgmt_session.proxy(RwVlrYang)
49
50
51 @pytest.fixture(scope='module')
52 def rwnsr_proxy(request, mgmt_session):
53 return mgmt_session.proxy(RwNsrYang)
54
55
56 @pytest.fixture(scope='module')
57 def nsd_proxy(request, mgmt_session):
58 return mgmt_session.proxy(RwProjectNsdYang)
59
60
61 @pytest.fixture(scope='module')
62 def vnfd_proxy(request, mgmt_session):
63 return mgmt_session.proxy(RwProjectVnfdYang)
64
65
66 @pytest.mark.setup('multiple_ns_setup')
67 @pytest.mark.depends('launchpad')
68 @pytest.mark.incremental
69 class TestMultipleNsSetup(object):
70 def test_onboard_descriptors(self, logger, mgmt_session, descriptors, nsd_proxy, vnfd_proxy):
71 """Onboards the VNF, NS packages required for the test"""
72 vnfds, nsds = [], []
73 for descriptor in descriptors:
74 pkg_type = rift.auto.descriptor.get_package_type(descriptor)
75 if pkg_type == 'NSD':
76 nsds.append(descriptor)
77 elif pkg_type == 'VNFD':
78 vnfds.append(descriptor)
79
80 pkgs_in_upload_seq = vnfds + nsds
81 logger.debug('Packages in sequence of upload: {}'.format([os.path.basename(pkg) for pkg in pkgs_in_upload_seq]))
82
83 for pkg in pkgs_in_upload_seq:
84 logger.debug('Uploading package {}'.format(pkg))
85 rift.auto.descriptor.onboard(mgmt_session, pkg) # Raise exception if the upload is not successful
86
87 # Verify if the packages are uploaded
88 assert len(vnfd_proxy.get_config('/rw-project:project[rw-project:name="default"]/vnfd-catalog').vnfd) == len(vnfds)
89 assert len(nsd_proxy.get_config('/rw-project:project[rw-project:name="default"]/nsd-catalog').nsd) == len(nsds)
90
91
92 @pytest.mark.depends('multiple_ns_setup')
93 @pytest.mark.incremental
94 class TestMultipleNsInstantiate(object):
95 def test_instantiate_ns_mem_check(self, logger, rwvnfr_proxy, nsd_proxy,
96 rwnsr_proxy, rwvlr_proxy,
97 cloud_account_name, descriptors):
98 """It runs over a loop. In each loop, it instantiates a NS,
99 terminates the NS, checks memory usage of the system.
100 During memory check, it verifies whether current system
101 mem usage exceeds base memory-usage by a defined threshold.
102 """
103 catalog = nsd_proxy.get_config('/rw-project:project[rw-project:name="default"]/nsd-catalog')
104
105 # Random NSD sequence generation for NS instantiation
106 iteration, no_of_hours = map(float, pytest.config.getoption('--multiple-ns-instantiate').split(','))
107 nsd_count = len([pkg for pkg in descriptors if 'nsd.' in pkg])
108 nsd_instantiate_seq = np.random.choice(list(range(nsd_count)), int(iteration))
109 random.shuffle(nsd_instantiate_seq)
110
111 logger.debug('nsd instantiaion sequence: {}'.format([catalog.nsd[seq].name for seq in nsd_instantiate_seq]))
112
113 # Collect mem-usage of the system
114 base_system_rss = get_mem_usage()
115 print_mem_usage()
116
117 start_time = time.time()
118 total_duration_in_secs = no_of_hours * 60 * 60
119 # Loop through NSD instantiation sequence and instantiate the NS
120 for idx, seq in enumerate(nsd_instantiate_seq, 1):
121 # Instantiating NS
122 nsd = catalog.nsd[seq]
123 logger.debug('Iteration {}: Instantiating NS {}'.format(idx, nsd.name))
124
125 nsr = rift.auto.descriptor.create_nsr(cloud_account_name, nsd.name, nsd)
126 rwnsr_proxy.create_config('/rw-project:project[rw-project:name="default"]/ns-instance-config/nsr', nsr)
127
128 # Verify if NS reaches active state
129 nsr_opdata = rwnsr_proxy.get('/rw-project:project[rw-project:name="default"]/ns-instance-opdata/nsr[ns-instance-config-ref={}]'.format(quoted_key(nsr.id)))
130 assert nsr_opdata is not None
131
132 # Verify NSR instances enter 'running' operational-status
133 for nsr in rwnsr_proxy.get('/rw-project:project[rw-project:name="default"]/ns-instance-opdata').nsr:
134 xpath = "/rw-project:project[rw-project:name='default']/ns-instance-opdata/nsr[ns-instance-config-ref={}]/operational-status".format(
135 quoted_key(nsr.ns_instance_config_ref))
136 rwnsr_proxy.wait_for(xpath, "running", fail_on=['failed'], timeout=400)
137
138 # Verify NSR instances enter 'configured' config-status
139 for nsr in rwnsr_proxy.get('/rw-project:project[rw-project:name="default"]/ns-instance-opdata').nsr:
140 xpath = "/rw-project:project[rw-project:name='default']/ns-instance-opdata/nsr[ns-instance-config-ref={}]/config-status".format(quoted_key(nsr.ns_instance_config_ref))
141 rwnsr_proxy.wait_for(xpath, "configured", fail_on=['failed'], timeout=400)
142
143 time.sleep(30) # Let it run for few secs before terminating it
144
145 # Terminates the NSR
146 rift.auto.descriptor.terminate_nsr(rwvnfr_proxy, rwnsr_proxy,
147 rwvlr_proxy, logger)
148
149 time.sleep(30) # After NS termination, wait for few secs before collecting mem-usage
150
151 # Get the mem-usage and compare it with base mem-usage
152 print_mem_usage()
153 curr_system_rss = get_mem_usage()
154 threshold = 5
155 mem_usage_inc = 100 * (curr_system_rss - base_system_rss) / base_system_rss
156 if mem_usage_inc > threshold:
157 assert False, 'There is an increase of {}%% during sequence {}. Base system-rss- {}; Current system-rss- {}'.format(
158 mem_usage_inc, idx, base_system_rss, curr_system_rss)
159
160 if (time.time() - start_time) > total_duration_in_secs:
161 logger.debug('NS instantiation has been happening for last {} hours (provided limit). Exiting.'.format(
162 no_of_hours))
163 break
164
165
166 @pytest.mark.depends('multiple_ns_setup')
167 @pytest.mark.teardown('multiple_ns_setup')
168 @pytest.mark.incremental
169 class TestMultipleNsTeardown(object):
170 def test_delete_descritors(self, nsd_proxy, vnfd_proxy):
171 """Deletes VNF, NS descriptors"""
172 nsds = nsd_proxy.get("/rw-project:project[rw-project:name='default']/nsd-catalog/nsd", list_obj=True)
173 for nsd in nsds.nsd:
174 xpath = "/rw-project:project[rw-project:name='default']/nsd-catalog/nsd[id={}]".format(quoted_key(nsd.id))
175 nsd_proxy.delete_config(xpath)
176
177 nsds = nsd_proxy.get("/rw-project:project[rw-project:name='default']/nsd-catalog/nsd", list_obj=True)
178 assert nsds is None or len(nsds.nsd) == 0
179
180 vnfds = vnfd_proxy.get("/rw-project:project[rw-project:name='default']/vnfd-catalog/vnfd", list_obj=True)
181 for vnfd_record in vnfds.vnfd:
182 xpath = "/rw-project:project[rw-project:name='default']/vnfd-catalog/vnfd[id={}]".format(quoted_key(vnfd_record.id))
183 vnfd_proxy.delete_config(xpath)
184
185 vnfds = vnfd_proxy.get("/rw-project:project[rw-project:name='default']/vnfd-catalog/vnfd", list_obj=True)
186 assert vnfds is None or len(vnfds.vnfd) == 0