3 # Copyright 2016-2017 RIFT.io Inc
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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.
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 (
37 gi
.require_version('RwKeyspec', '1.0')
38 from gi
.repository
.RwKeyspec
import quoted_key
41 @pytest.fixture(scope
='module')
42 def rwvnfr_proxy(request
, mgmt_session
):
43 return mgmt_session
.proxy(RwVnfrYang
)
46 @pytest.fixture(scope
='module')
47 def rwvlr_proxy(request
, mgmt_session
):
48 return mgmt_session
.proxy(RwVlrYang
)
51 @pytest.fixture(scope
='module')
52 def rwnsr_proxy(request
, mgmt_session
):
53 return mgmt_session
.proxy(RwNsrYang
)
56 @pytest.fixture(scope
='module')
57 def nsd_proxy(request
, mgmt_session
):
58 return mgmt_session
.proxy(RwProjectNsdYang
)
61 @pytest.fixture(scope
='module')
62 def vnfd_proxy(request
, mgmt_session
):
63 return mgmt_session
.proxy(RwProjectVnfdYang
)
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"""
73 for descriptor
in descriptors
:
74 pkg_type
= rift
.auto
.descriptor
.get_package_type(descriptor
)
76 nsds
.append(descriptor
)
77 elif pkg_type
== 'VNFD':
78 vnfds
.append(descriptor
)
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
]))
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
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
)
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.
103 catalog
= nsd_proxy
.get_config('/rw-project:project[rw-project:name="default"]/nsd-catalog')
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
)
111 logger
.debug('nsd instantiaion sequence: {}'.format([catalog
.nsd
[seq
].name
for seq
in nsd_instantiate_seq
]))
113 # Collect mem-usage of the system
114 base_system_rss
= get_mem_usage()
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):
122 nsd
= catalog
.nsd
[seq
]
123 logger
.debug('Iteration {}: Instantiating NS {}'.format(idx
, nsd
.name
))
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
)
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
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)
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)
143 time
.sleep(30) # Let it run for few secs before terminating it
146 rift
.auto
.descriptor
.terminate_nsr(rwvnfr_proxy
, rwnsr_proxy
,
149 time
.sleep(30) # After NS termination, wait for few secs before collecting mem-usage
151 # Get the mem-usage and compare it with base mem-usage
153 curr_system_rss
= get_mem_usage()
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
)
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(
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)
174 xpath
= "/rw-project:project[rw-project:name='default']/nsd-catalog/nsd[id={}]".format(quoted_key(nsd
.id))
175 nsd_proxy
.delete_config(xpath
)
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
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
)
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