4 # Copyright 2016 RIFT.IO Inc
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
19 @file test_multi_vm_vnf_slb.py
20 @author Karun Ganesharatnam (karun.ganesharatnam@riftio.com)
22 @brief Scriptable load-balancer test with multi-vm VNFs
35 from gi
.repository
import (
48 logging
.basicConfig(level
=logging
.DEBUG
)
49 logger
= logging
.getLogger(__name__
)
51 @pytest.fixture(scope
='module')
52 def multi_vm_vnf_nsd_package_file(request
, package_gen_script
, mvv_descr_dir
, package_dir
):
53 pkg_cmd
= "{pkg_scr} --outdir {outdir} --infile {infile} --descriptor-type nsd --format xml".format(
54 pkg_scr
=package_gen_script
,
56 infile
=os
.path
.join(mvv_descr_dir
, 'nsd/xml/multivm_tg_slb_ts_config_nsd.xml'),
58 pkg_file
= os
.path
.join(package_dir
, 'multivm_tg_slb_ts_config_nsd.tar.gz')
59 logger
.debug("Generating NSD package: %s", pkg_file
)
60 subprocess
.check_call(shlex
.split(pkg_cmd
))
63 def create_nsr(nsd_id
, input_param_list
, cloud_account_name
):
65 Create the NSR record object
69 input_param_list - list of input-parameter objects
74 nsr
= RwNsrYang
.YangData_RwProject_Project_NsInstanceConfig_Nsr()
76 nsr
.id = str(uuid
.uuid4())
77 nsr
.name
= rift
.auto
.mano
.resource_name(nsr
.id)
78 nsr
.short_name
= "nsr_short_name"
79 nsr
.description
= "This is a description"
81 nsr
.admin_status
= "ENABLED"
82 nsr
.input_parameter
.extend(input_param_list
)
83 nsr
.cloud_account
= cloud_account_name
88 def upload_descriptor(logger
, descriptor_file
, host
="127.0.0.1"):
89 curl_cmd
= 'curl --insecure -F "descriptor=@{file}" http://{host}:4567/api/upload'.format(
93 logger
.debug("Uploading descriptor %s using cmd: %s", descriptor_file
, curl_cmd
)
94 stdout
= subprocess
.check_output(shlex
.split(curl_cmd
), universal_newlines
=True)
96 json_out
= json
.loads(stdout
)
97 transaction_id
= json_out
["transaction_id"]
102 class DescriptorOnboardError(Exception):
106 def wait_onboard_transaction_finished(logger
, transaction_id
, timeout
=10, host
="127.0.0.1"):
107 logger
.info("Waiting for onboard trans_id %s to complete", transaction_id
)
108 def check_status_onboard_status():
109 uri
= 'http://%s:4567/api/upload/%s/state' % (host
, transaction_id
)
110 curl_cmd
= 'curl --insecure {uri}'.format(
113 return subprocess
.check_output(shlex
.split(curl_cmd
), universal_newlines
=True)
117 while elapsed
< timeout
:
118 reply
= check_status_onboard_status()
119 state
= json
.loads(reply
)
120 if state
["status"] == "success":
123 if state
["status"] != "pending":
124 raise DescriptorOnboardError(state
)
127 elapsed
= time
.time() - start
129 if state
["status"] != "success":
130 raise DescriptorOnboardError(state
)
132 logger
.info("Descriptor onboard was successful")
135 @pytest.mark
.setup('multivmvnf')
136 @pytest.mark
.depends('launchpad')
137 @pytest.mark
.incremental
138 class TestMultiVmVnfSlb(object):
141 def teardown_class(cls
):
142 """ remove the temporary directory contains the descriptor packages
144 logger
.debug("Removing the temporary package directory: %s", cls
.pkg_dir
)
145 # if not cls.pkg_dir is None:
146 # shutil.rmtree(cls.pkg_dir)
148 def test_onboard_trafgen_vnfd(self
, logger
, launchpad_host
, vnfd_proxy
, trafgen_vnfd_package_file
):
149 TestMultiVmVnfSlb
.pkg_dir
= os
.path
.dirname(trafgen_vnfd_package_file
)
150 logger
.info("Onboarding trafgen vnfd package: %s", trafgen_vnfd_package_file
)
151 trans_id
= upload_descriptor(logger
, trafgen_vnfd_package_file
, launchpad_host
)
152 wait_onboard_transaction_finished(logger
, trans_id
, host
=launchpad_host
)
154 catalog
= vnfd_proxy
.get_config('/vnfd-catalog')
156 assert len(vnfds
) == 1, "There should only be a single vnfd"
158 assert vnfd
.name
== "multivm_trafgen_vnfd"
160 def test_onboard_trafsink_vnfd(self
, logger
, launchpad_host
, vnfd_proxy
, trafsink_vnfd_package_file
):
161 TestMultiVmVnfSlb
.pkg_dir
= os
.path
.dirname(trafsink_vnfd_package_file
)
162 logger
.info("Onboarding trafsink vnfd package: %s", trafsink_vnfd_package_file
)
163 trans_id
= upload_descriptor(logger
, trafsink_vnfd_package_file
, launchpad_host
)
164 wait_onboard_transaction_finished(logger
, trans_id
, host
=launchpad_host
)
166 catalog
= vnfd_proxy
.get_config('/vnfd-catalog')
168 assert len(vnfds
) == 2, "There should be two vnfds"
169 assert "multivm_trafsink_vnfd" in [vnfds
[0].name
, vnfds
[1].name
]
171 def test_onboard_slb_vnfd(self
, logger
, launchpad_host
, vnfd_proxy
, slb_vnfd_package_file
):
172 TestMultiVmVnfSlb
.pkg_dir
= os
.path
.dirname(slb_vnfd_package_file
)
173 logger
.info("Onboarding slb vnfd package: %s", slb_vnfd_package_file
)
174 trans_id
= upload_descriptor(logger
, slb_vnfd_package_file
, launchpad_host
)
175 wait_onboard_transaction_finished(logger
, trans_id
, host
=launchpad_host
)
177 catalog
= vnfd_proxy
.get_config('/vnfd-catalog')
179 assert len(vnfds
) == 3, "There should be two vnfds"
180 assert "multivm_slb_vnfd" in [vnfds
[0].name
, vnfds
[1].name
]
182 def test_onboard_multi_vm_vnf_nsd(self
, logger
, launchpad_host
, nsd_proxy
, multi_vm_vnf_nsd_package_file
):
183 logger
.info("Onboarding tg_slb_ts nsd package: %s", multi_vm_vnf_nsd_package_file
)
184 trans_id
= upload_descriptor(logger
, multi_vm_vnf_nsd_package_file
, launchpad_host
)
185 wait_onboard_transaction_finished(logger
, trans_id
, host
=launchpad_host
)
187 catalog
= nsd_proxy
.get_config('/nsd-catalog')
189 assert len(nsds
) == 1, "There should only be a single nsd"
191 assert nsd
.name
== "multivm_tg_slb_ts_config_nsd"
193 def test_instantiate_multi_vm_vnf_nsr(self
, logger
, nsd_proxy
, nsr_proxy
, rwnsr_proxy
, base_proxy
, cloud_account_name
):
195 def verify_input_parameters (running_config
, config_param
):
197 Verify the configured parameter set against the running configuration
199 for run_input_param
in running_config
.input_parameter
:
200 if (input_param
.xpath
== config_param
.xpath
and
201 input_param
.value
== config_param
.value
):
204 assert False, ("Verification of configured input parameters: { xpath:%s, value:%s} "
205 "is unsuccessful.\nRunning configuration: %s" % (config_param
.xpath
,
207 running_nsr_config
.input_parameter
))
209 catalog
= nsd_proxy
.get_config('/nsd-catalog')
212 input_parameters
= []
213 descr_xpath
= "/rw-project:project/nsd:nsd-catalog/nsd:nsd[nsd:id='%s']/nsd:description" % nsd
.id
214 descr_value
= "New NSD Description"
215 in_param_id
= str(uuid
.uuid4())
217 input_param_1
= NsrYang
.YangData_RwProject_Project_NsInstanceConfig_Nsr_InputParameter(
221 input_parameters
.append(input_param_1
)
223 nsr
= create_nsr(nsd
.id, input_parameters
, cloud_account_name
)
225 logger
.info("Instantiating the Network Service")
226 rwnsr_proxy
.create_config('/ns-instance-config/nsr', nsr
)
228 nsr_opdata
= rwnsr_proxy
.get('/ns-instance-opdata')
229 nsrs
= nsr_opdata
.nsr
231 # Verify the input parameter configuration
232 running_config
= rwnsr_proxy
.get_config("/ns-instance-config/nsr[id='%s']" % nsr
.id)
233 for input_param
in input_parameters
:
234 verify_input_parameters(running_config
, input_param
)
236 assert len(nsrs
) == 1
237 assert nsrs
[0].ns_instance_config_ref
== nsr
.id
239 xpath
= "/ns-instance-opdata/nsr[ns-instance-config-ref='{}']/operational-status".format(nsr
.id)
240 rwnsr_proxy
.wait_for(xpath
, "running", fail_on
=['failed'], timeout
=360)
243 @pytest.mark
.teardown('multivmvnf')
244 @pytest.mark
.depends('launchpad')
245 @pytest.mark
.incremental
246 class TestMultiVmVnfSlbTeardown(object):
247 def test_terminate_nsr(self
, nsr_proxy
, vnfr_proxy
, rwnsr_proxy
, logger
):
249 Terminate the instance and check if the record is deleted.
252 1. NSR record is deleted from instance-config.
255 logger
.debug("Terminating Multi VM VNF's NSR")
257 nsr_path
= "/ns-instance-config"
258 nsr
= rwnsr_proxy
.get_config(nsr_path
)
260 ping_pong
= nsr
.nsr
[0]
261 rwnsr_proxy
.delete_config("/ns-instance-config/nsr[id='{}']".format(ping_pong
.id))
265 def test_delete_records(self
, nsd_proxy
, vnfd_proxy
):
266 """Delete the NSD & VNFD records
269 The records are deleted.
271 nsds
= nsd_proxy
.get("/nsd-catalog/nsd", list_obj
=True)
273 xpath
= "/nsd-catalog/nsd[id='{}']".format(nsd
.id)
274 nsd_proxy
.delete_config(xpath
)
276 vnfds
= vnfd_proxy
.get("/vnfd-catalog/vnfd", list_obj
=True)
277 for vnfd_record
in vnfds
.vnfd
:
278 xpath
= "/vnfd-catalog/vnfd[id='{}']".format(vnfd_record
.id)
279 vnfd_proxy
.delete_config(xpath
)
282 nsds
= nsd_proxy
.get("/nsd-catalog/nsd", list_obj
=True)
283 assert nsds
is None or len(nsds
.nsd
) == 0
285 vnfds
= vnfd_proxy
.get("/vnfd-catalog/vnfd", list_obj
=True)
286 assert vnfds
is None or len(vnfds
.vnfd
) == 0