557518b362c75a821808cb69ac68c34bdd589e76
[osm/SO.git] / rwlaunchpad / ra / pytest / multivm_vnf / test_multi_vm_vnf_slb.py
1 #!/usr/bin/env python
2 """
3 #
4 # Copyright 2016 RIFT.IO Inc
5 #
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
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
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.
17 #
18
19 @file test_multi_vm_vnf_slb.py
20 @author Karun Ganesharatnam (karun.ganesharatnam@riftio.com)
21 @date 03/16/2016
22 @brief Scriptable load-balancer test with multi-vm VNFs
23 """
24
25 import json
26 import logging
27 import os
28 import pytest
29 import shlex
30 import shutil
31 import subprocess
32 import time
33 import uuid
34
35 from gi.repository import (
36 NsdYang,
37 NsrYang,
38 RwNsrYang,
39 VnfrYang,
40 VldYang,
41 RwVnfdYang,
42 RwLaunchpadYang,
43 RwBaseYang
44 )
45
46 import rift.auto.mano
47
48 logging.basicConfig(level=logging.DEBUG)
49 logger = logging.getLogger(__name__)
50
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,
55 outdir=package_dir,
56 infile=os.path.join(mvv_descr_dir, 'nsd/xml/multivm_tg_slb_ts_config_nsd.xml'),
57 )
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))
61 return pkg_file
62
63 def create_nsr(nsd_id, input_param_list, cloud_account_name):
64 """
65 Create the NSR record object
66
67 Arguments:
68 nsd_id - NSD id
69 input_param_list - list of input-parameter objects
70
71 Return:
72 NSR object
73 """
74 nsr = RwNsrYang.YangData_Nsr_NsInstanceConfig_Nsr()
75
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"
80 nsr.nsd_ref = nsd_id
81 nsr.admin_status = "ENABLED"
82 nsr.input_parameter.extend(input_param_list)
83 nsr.cloud_account = cloud_account_name
84
85 return nsr
86
87
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(
90 file=descriptor_file,
91 host=host,
92 )
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)
95
96 json_out = json.loads(stdout)
97 transaction_id = json_out["transaction_id"]
98
99 return transaction_id
100
101
102 class DescriptorOnboardError(Exception):
103 pass
104
105
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(
111 uri=uri
112 )
113 return subprocess.check_output(shlex.split(curl_cmd), universal_newlines=True)
114
115 elapsed = 0
116 start = time.time()
117 while elapsed < timeout:
118 reply = check_status_onboard_status()
119 state = json.loads(reply)
120 if state["status"] == "success":
121 break
122
123 if state["status"] != "pending":
124 raise DescriptorOnboardError(state)
125
126 time.sleep(1)
127 elapsed = time.time() - start
128
129 if state["status"] != "success":
130 raise DescriptorOnboardError(state)
131
132 logger.info("Descriptor onboard was successful")
133
134
135 @pytest.mark.setup('multivmvnf')
136 @pytest.mark.depends('launchpad')
137 @pytest.mark.incremental
138 class TestMultiVmVnfSlb(object):
139 pkg_dir = None
140 @classmethod
141 def teardown_class(cls):
142 """ remove the temporary directory contains the descriptor packages
143 """
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)
147
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)
153
154 catalog = vnfd_proxy.get_config('/vnfd-catalog')
155 vnfds = catalog.vnfd
156 assert len(vnfds) == 1, "There should only be a single vnfd"
157 vnfd = vnfds[0]
158 assert vnfd.name == "multivm_trafgen_vnfd"
159
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)
165
166 catalog = vnfd_proxy.get_config('/vnfd-catalog')
167 vnfds = catalog.vnfd
168 assert len(vnfds) == 2, "There should be two vnfds"
169 assert "multivm_trafsink_vnfd" in [vnfds[0].name, vnfds[1].name]
170
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)
176
177 catalog = vnfd_proxy.get_config('/vnfd-catalog')
178 vnfds = catalog.vnfd
179 assert len(vnfds) == 3, "There should be two vnfds"
180 assert "multivm_slb_vnfd" in [vnfds[0].name, vnfds[1].name]
181
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)
186
187 catalog = nsd_proxy.get_config('/nsd-catalog')
188 nsds = catalog.nsd
189 assert len(nsds) == 1, "There should only be a single nsd"
190 nsd = nsds[0]
191 assert nsd.name == "multivm_tg_slb_ts_config_nsd"
192
193 def test_instantiate_multi_vm_vnf_nsr(self, logger, nsd_proxy, nsr_proxy, rwnsr_proxy, base_proxy, cloud_account_name):
194
195 def verify_input_parameters (running_config, config_param):
196 """
197 Verify the configured parameter set against the running configuration
198 """
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):
202 return True
203
204 assert False, ("Verification of configured input parameters: { xpath:%s, value:%s} "
205 "is unsuccessful.\nRunning configuration: %s" % (config_param.xpath,
206 config_param.value,
207 running_nsr_config.input_parameter))
208
209 catalog = nsd_proxy.get_config('/nsd-catalog')
210 nsd = catalog.nsd[0]
211
212 input_parameters = []
213 descr_xpath = "/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())
216
217 input_param_1= NsrYang.YangData_Nsr_NsInstanceConfig_Nsr_InputParameter(
218 xpath=descr_xpath,
219 value=descr_value)
220
221 input_parameters.append(input_param_1)
222
223 nsr = create_nsr(nsd.id, input_parameters, cloud_account_name)
224
225 logger.info("Instantiating the Network Service")
226 rwnsr_proxy.create_config('/ns-instance-config/nsr', nsr)
227
228 nsr_opdata = rwnsr_proxy.get('/ns-instance-opdata')
229 nsrs = nsr_opdata.nsr
230
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)
235
236 assert len(nsrs) == 1
237 assert nsrs[0].ns_instance_config_ref == nsr.id
238
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)
241
242
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):
248 """
249 Terminate the instance and check if the record is deleted.
250
251 Asserts:
252 1. NSR record is deleted from instance-config.
253
254 """
255 logger.debug("Terminating Multi VM VNF's NSR")
256
257 nsr_path = "/ns-instance-config"
258 nsr = rwnsr_proxy.get_config(nsr_path)
259
260 ping_pong = nsr.nsr[0]
261 rwnsr_proxy.delete_config("/ns-instance-config/nsr[id='{}']".format(ping_pong.id))
262 time.sleep(30)
263
264
265 def test_delete_records(self, nsd_proxy, vnfd_proxy):
266 """Delete the NSD & VNFD records
267
268 Asserts:
269 The records are deleted.
270 """
271 nsds = nsd_proxy.get("/nsd-catalog/nsd", list_obj=True)
272 for nsd in nsds.nsd:
273 xpath = "/nsd-catalog/nsd[id='{}']".format(nsd.id)
274 nsd_proxy.delete_config(xpath)
275
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)
280
281 time.sleep(5)
282 nsds = nsd_proxy.get("/nsd-catalog/nsd", list_obj=True)
283 assert nsds is None or len(nsds.nsd) == 0
284
285 vnfds = vnfd_proxy.get("/vnfd-catalog/vnfd", list_obj=True)
286 assert vnfds is None or len(vnfds.vnfd) == 0