45a7832c895c923043931b485f3abd75a221062f
[osm/SO.git] / rwlaunchpad / ra / pytest / ns / pingpong / test_pingpong.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 lp_test.py
20 @author Austin Cormier (Austin.Cormier@riftio.com)
21 @author Paul Laidler (Paul.Laidler@riftio.com)
22 @date 11/03/2015
23 @brief Launchpad System Test
24 """
25
26 import json
27 import logging
28 import os
29 import pytest
30 import shlex
31 import requests
32 import shutil
33 import subprocess
34 import tempfile
35 import time
36 import uuid
37
38 import rift.auto.mano
39 import rift.auto.session
40 import rift.mano.examples.ping_pong_nsd as ping_pong
41
42 import gi
43 gi.require_version('RwNsrYang', '1.0')
44 gi.require_version('RwVnfdYang', '1.0')
45 gi.require_version('RwLaunchpadYang', '1.0')
46 gi.require_version('RwBaseYang', '1.0')
47
48 from gi.repository import (
49 NsdYang,
50 RwNsrYang,
51 RwVnfrYang,
52 NsrYang,
53 VnfrYang,
54 VldYang,
55 RwVnfdYang,
56 RwLaunchpadYang,
57 RwBaseYang
58 )
59
60 logging.basicConfig(level=logging.DEBUG)
61
62 @pytest.fixture(scope='module')
63 def vnfd_proxy(request, mgmt_session):
64 return mgmt_session.proxy(RwVnfdYang)
65
66 @pytest.fixture(scope='module')
67 def rwvnfr_proxy(request, mgmt_session):
68 return mgmt_session.proxy(RwVnfrYang)
69
70 @pytest.fixture(scope='module')
71 def vld_proxy(request, mgmt_session):
72 return mgmt_session.proxy(VldYang)
73
74 @pytest.fixture(scope='module')
75 def nsd_proxy(request, mgmt_session):
76 return mgmt_session.proxy(NsdYang)
77
78 @pytest.fixture(scope='module')
79 def rwnsr_proxy(request, mgmt_session):
80 return mgmt_session.proxy(RwNsrYang)
81
82 @pytest.fixture(scope='module')
83 def base_proxy(request, mgmt_session):
84 return mgmt_session.proxy(RwBaseYang)
85
86 class DescriptorOnboardError(Exception):
87 pass
88
89 def create_nsr(nsd, input_param_list, cloud_account_name):
90 """
91 Create the NSR record object
92
93 Arguments:
94 nsd - NSD
95 input_param_list - list of input-parameter objects
96 cloud_account_name - name of cloud account
97
98 Return:
99 NSR object
100 """
101 nsr = RwNsrYang.YangData_Nsr_NsInstanceConfig_Nsr()
102
103 nsr.id = str(uuid.uuid4())
104 nsr.name = rift.auto.mano.resource_name(nsr.id)
105 nsr.short_name = "nsr_short_name"
106 nsr.description = "This is a description"
107 nsr.nsd.from_dict(nsr.as_dict())
108 nsr.admin_status = "ENABLED"
109 nsr.input_parameter.extend(input_param_list)
110 nsr.cloud_account = cloud_account_name
111
112 return nsr
113
114 def upload_descriptor(logger, descriptor_file, host="127.0.0.1"):
115 curl_cmd = 'curl --insecure -F "descriptor=@{file}" https://{host}:4567/api/upload'.format(
116 file=descriptor_file,
117 host=host,
118 )
119
120 logger.debug("Uploading descriptor %s using cmd: %s", descriptor_file, curl_cmd)
121 stdout = subprocess.check_output(shlex.split(curl_cmd), universal_newlines=True)
122
123 json_out = json.loads(stdout)
124 transaction_id = json_out["transaction_id"]
125
126 return transaction_id
127
128 def wait_onboard_transaction_finished(logger, transaction_id, timeout=30, host="127.0.0.1"):
129
130 def check_status_onboard_status():
131 uri = 'https://%s:4567/api/upload/%s/state' % (host, transaction_id)
132 curl_cmd = 'curl --insecure {uri}'.format(uri=uri)
133 return subprocess.check_output(shlex.split(curl_cmd), universal_newlines=True)
134
135 logger.info("Waiting for onboard transaction [%s] to complete", transaction_id)
136
137 elapsed = 0
138 start = time.time()
139 while elapsed < timeout:
140
141 reply = check_status_onboard_status()
142 state = json.loads(reply)
143 if state["status"] == "success":
144 break
145
146 if state["status"] == "failure":
147 raise DescriptorOnboardError(state["errors"])
148
149 if state["status"] != "pending":
150 raise DescriptorOnboardError(state)
151
152 time.sleep(1)
153 elapsed = time.time() - start
154
155
156 if state["status"] != "success":
157 raise DescriptorOnboardError(state)
158 logger.info("Descriptor onboard was successful")
159
160 def onboard_descriptor(host, file_name, logger, endpoint, scheme, cert):
161 """On-board/update the descriptor.
162
163 Args:
164 host (str): Launchpad IP
165 file_name (str): Full file path.
166 logger: Logger instance
167 endpoint (str): endpoint to be used for the upload operation.
168
169 """
170 logger.info("Onboarding package: %s", file_name)
171 trans_id = upload_descriptor(
172 logger,
173 file_name,
174 host=host)
175 wait_onboard_transaction_finished(
176 logger,
177 trans_id,
178 host=host)
179
180
181 def terminate_nsrs(rwvnfr_proxy, rwnsr_proxy, logger):
182 """
183 Terminate the instance and check if the record is deleted.
184
185 Asserts:
186 1. NSR record is deleted from instance-config.
187
188 """
189 logger.debug("Terminating Ping Pong NSRs")
190
191 nsr_path = "/ns-instance-config"
192 nsr = rwnsr_proxy.get_config(nsr_path)
193 nsrs = nsr.nsr
194
195 xpaths = []
196 for ping_pong in nsrs:
197 xpath = "/ns-instance-config/nsr[id='{}']".format(ping_pong.id)
198 rwnsr_proxy.delete_config(xpath)
199 xpaths.append(xpath)
200
201 time.sleep(60)
202 for xpath in xpaths:
203 nsr = rwnsr_proxy.get_config(xpath)
204 assert nsr is None
205
206 # Get the ns-instance-config
207 ns_instance_config = rwnsr_proxy.get_config("/ns-instance-config")
208
209 # Termination tests
210 vnfr = "/vnfr-catalog/vnfr"
211 vnfrs = rwvnfr_proxy.get(vnfr, list_obj=True)
212 assert vnfrs is None or len(vnfrs.vnfr) == 0
213
214 # nsr = "/ns-instance-opdata/nsr"
215 # nsrs = rwnsr_proxy.get(nsr, list_obj=True)
216 # assert len(nsrs.nsr) == 0
217
218
219 def generate_tar_files(tmpdir, ping_vnfd, pong_vnfd, ping_pong_nsd):
220 """Converts the descriptor to files and package them into zip files
221 that can be uploaded to LP instance.
222
223 Args:
224 tmpdir (string): Full path where the zipped files should be
225 ping_vnfd (VirtualNetworkFunction): Ping VNFD data
226 pong_vnfd (VirtualNetworkFunction): Pong VNFD data
227 ping_pong_nsd (NetworkService): PingPong NSD data
228
229 Returns:
230 Tuple: file path for ping vnfd, pong vnfd and ping_pong_nsd
231 """
232 rift_build = os.environ['RIFT_BUILD']
233 MANO_DIR = os.path.join(
234 rift_build,
235 "modules/core/mano/src/core_mano-build/examples/ping_pong_ns")
236 ping_img = os.path.join(MANO_DIR, "ping_vnfd_with_image/images/Fedora-x86_64-20-20131211.1-sda-ping.qcow2")
237 pong_img = os.path.join(MANO_DIR, "pong_vnfd_with_image/images/Fedora-x86_64-20-20131211.1-sda-pong.qcow2")
238
239 """ grab cached copies of these files if not found. They may not exist
240 because our git submodule dependency mgmt
241 will not populate these because they live in .build, not .install
242 """
243 if not os.path.exists(ping_img):
244 ping_img = os.path.join(
245 os.environ['RIFT_ROOT'],
246 'images/Fedora-x86_64-20-20131211.1-sda-ping.qcow2')
247 pong_img = os.path.join(
248 os.environ['RIFT_ROOT'],
249 'images/Fedora-x86_64-20-20131211.1-sda-pong.qcow2')
250
251 for descriptor in [ping_vnfd, pong_vnfd, ping_pong_nsd]:
252 descriptor.write_to_file(output_format='xml', outdir=tmpdir.name)
253
254 ping_img_path = os.path.join(tmpdir.name, "{}/images/".format(ping_vnfd.name))
255 pong_img_path = os.path.join(tmpdir.name, "{}/images/".format(pong_vnfd.name))
256 os.makedirs(ping_img_path)
257 os.makedirs(pong_img_path)
258
259 shutil.copy(ping_img, ping_img_path)
260 shutil.copy(pong_img, pong_img_path)
261
262 for dir_name in [ping_vnfd.name, pong_vnfd.name, ping_pong_nsd.name]:
263 subprocess.call([
264 "sh",
265 "{rift_install}/usr/rift/toolchain/cmake/bin/generate_descriptor_pkg.sh".format(rift_install=os.environ['RIFT_INSTALL']),
266 tmpdir.name,
267 dir_name])
268
269 return (os.path.join(tmpdir.name, "{}.tar.gz".format(ping_vnfd.name)),
270 os.path.join(tmpdir.name, "{}.tar.gz".format(pong_vnfd.name)),
271 os.path.join(tmpdir.name, "{}.tar.gz".format(ping_pong_nsd.name)))
272
273
274 @pytest.mark.setup('pingpong')
275 @pytest.mark.depends('launchpad')
276 @pytest.mark.usefixtures('cloud_account')
277 @pytest.mark.incremental
278 class TestPingPongStart(object):
279 """A brief overview of the steps performed.
280 1. Generate & on-board new descriptors
281 2. Start & stop the ping pong NSR
282 3. Update the exiting descriptor files.
283 4. Start the ping pong NSR.
284
285 """
286
287
288 def test_onboard_descriptors(
289 self,
290 logger,
291 vnfd_proxy,
292 nsd_proxy,
293 mgmt_session,
294 scheme,
295 cert,
296 ping_pong_records):
297 """Generates & On-boards the descriptors.
298 """
299 temp_dirs = []
300 catalog = vnfd_proxy.get_config('/vnfd-catalog')
301 endpoint = "upload"
302
303 """
304 This upload routine can get called multiples times for upload API,
305 depending on the combinations of 'cloud_account' & 'endpoint'
306 fixtures. Since the records are cached at module level, we might end up
307 uploading the same uuids multiple times, thus causing errors. So a
308 simple work-around will be to skip the records when they are uploaded
309 for the second time.
310 """
311 def onboard_ping_pong_vnfds(ping_vnfd_file, pong_vnfd_file):
312 # On-board VNFDs
313 for file_name in [ping_vnfd_file, pong_vnfd_file]:
314 onboard_descriptor(
315 mgmt_session.host,
316 file_name,
317 logger,
318 endpoint,
319 scheme,
320 cert)
321
322 catalog = vnfd_proxy.get_config('/vnfd-catalog')
323 vnfds = catalog.vnfd
324 assert len(vnfds) == 2, "There should two vnfds"
325 assert "ping_vnfd" in [vnfds[0].name, vnfds[1].name]
326 assert "pong_vnfd" in [vnfds[0].name, vnfds[1].name]
327
328
329 def delete_vnfds():
330 vnfds = vnfd_proxy.get("/vnfd-catalog/vnfd", list_obj=True)
331 for vnfd_record in vnfds.vnfd:
332 xpath = "/vnfd-catalog/vnfd[id='{}']".format(vnfd_record.id)
333 vnfd_proxy.delete_config(xpath)
334
335 time.sleep(5)
336 vnfds = vnfd_proxy.get("/vnfd-catalog/vnfd", list_obj=True)
337 assert vnfds is None or len(vnfds.vnfd) == 0
338
339
340 if catalog is not None and len(catalog.vnfd) == 2 and endpoint == "upload":
341 return
342
343 if endpoint == "update":
344 for vnfd_record in [ping_vnfd, pong_vnfd]:
345 vnfd_record.descriptor.vnfd[0].description += "_update"
346 ping_pong_nsd.descriptor.nsd[0].description += "_update"
347
348 tmpdir2 = tempfile.TemporaryDirectory()
349 temp_dirs.append(tmpdir2)
350 ping_pong.generate_ping_pong_descriptors(pingcount=1,
351 write_to_file=True,
352 out_dir=tmpdir2.name,
353 ping_fmt='json',
354 pong_fmt='xml',
355 )
356
357 # On-board VNFDs without image
358 ping_vnfd_file = os.path.join(tmpdir2.name, 'ping_vnfd/vnfd/ping_vnfd.json')
359 pong_vnfd_file = os.path.join(tmpdir2.name, 'pong_vnfd/vnfd/pong_vnfd.xml')
360 onboard_ping_pong_vnfds(ping_vnfd_file, pong_vnfd_file)
361
362 delete_vnfds()
363
364 tmpdir = tempfile.TemporaryDirectory()
365 temp_dirs.append(tmpdir)
366
367 ping_vnfd, pong_vnfd, ping_pong_nsd = ping_pong_records
368 ping_vnfd_file, pong_vnfd_file, pingpong_nsd_file = \
369 generate_tar_files(tmpdir, ping_vnfd, pong_vnfd, ping_pong_nsd)
370
371 # On-board VNFDs with image
372 onboard_ping_pong_vnfds(ping_vnfd_file, pong_vnfd_file)
373
374 # On-board NSD
375 onboard_descriptor(
376 mgmt_session.host,
377 pingpong_nsd_file,
378 logger,
379 endpoint,
380 scheme,
381 cert)
382
383 catalog = nsd_proxy.get_config('/nsd-catalog')
384 nsds = catalog.nsd
385 assert len(nsds) == 1, "There should only be a single nsd"
386 assert nsds[0].name == "ping_pong_nsd"
387
388 # Temp directory cleanup
389 # for temp_dir in temp_dirs:
390 # temp_dir.cleanup()
391
392 def test_instantiate_ping_pong_nsr(self, logger, nsd_proxy, rwnsr_proxy, base_proxy, cloud_account):
393
394 def verify_input_parameters(running_config, config_param):
395 """
396 Verify the configured parameter set against the running configuration
397 """
398 for run_input_param in running_config.input_parameter:
399 if (run_input_param.xpath == config_param.xpath and
400 run_input_param.value == config_param.value):
401 return True
402
403 assert False, ("Verification of configured input parameters: { xpath:%s, value:%s} "
404 "is unsuccessful.\nRunning configuration: %s" % (config_param.xpath,
405 config_param.value,
406 running_config.input_parameter))
407
408 catalog = nsd_proxy.get_config('/nsd-catalog')
409 nsd = catalog.nsd[0]
410
411 input_parameters = []
412 descr_xpath = "/nsd:nsd-catalog/nsd:nsd[nsd:id='%s']/nsd:vendor" % nsd.id
413 descr_value = "automation"
414 in_param_id = str(uuid.uuid4())
415
416 input_param_1 = NsrYang.YangData_Nsr_NsInstanceConfig_Nsr_InputParameter(
417 xpath=descr_xpath,
418 value=descr_value)
419
420 input_parameters.append(input_param_1)
421
422 nsr = create_nsr(nsd, input_parameters, cloud_account.name)
423
424 logger.info("Instantiating the Network Service")
425 rwnsr_proxy.create_config('/ns-instance-config/nsr', nsr)
426
427 nsr_opdata = rwnsr_proxy.get('/ns-instance-opdata/nsr[ns-instance-config-ref="{}"]'.format(nsr.id))
428 assert nsr_opdata is not None
429
430 # Verify the input parameter configuration
431 running_config = rwnsr_proxy.get_config("/ns-instance-config/nsr[id='%s']" % nsr.id)
432 for input_param in input_parameters:
433 verify_input_parameters(running_config, input_param)
434
435 def test_wait_for_pingpong_started(self, rwnsr_proxy):
436 nsr_opdata = rwnsr_proxy.get('/ns-instance-opdata')
437 nsrs = nsr_opdata.nsr
438
439 for nsr in nsrs:
440 xpath = "/ns-instance-opdata/nsr[ns-instance-config-ref='{}']/operational-status".format(
441 nsr.ns_instance_config_ref)
442 rwnsr_proxy.wait_for(xpath, "running", fail_on=['failed'], timeout=180)
443
444 def test_wait_for_pingpong_configured(self, rwnsr_proxy):
445 nsr_opdata = rwnsr_proxy.get('/ns-instance-opdata')
446 nsrs = nsr_opdata.nsr
447
448 for nsr in nsrs:
449 xpath = "/ns-instance-opdata/nsr[ns-instance-config-ref='{}']/config-status".format(
450 nsr.ns_instance_config_ref)
451 rwnsr_proxy.wait_for(xpath, "configured", fail_on=['failed'], timeout=450)
452
453
454 @pytest.mark.feature("update-api")
455 @pytest.mark.depends('pingpong')
456 @pytest.mark.usefixtures('cloud_account')
457 @pytest.mark.incremental
458 class TestUpdateNsr(object):
459 def test_stop_nsr(self, rwvnfr_proxy, rwnsr_proxy, logger):
460 """Terminate the currently running NSR instance before updating the descriptor files"""
461 terminate_nsrs(rwvnfr_proxy, rwnsr_proxy, logger)
462
463 def test_onboard_descriptors(
464 self,
465 logger,
466 vnfd_proxy,
467 nsd_proxy,
468 mgmt_session,
469 scheme,
470 cert,
471 ping_pong_records):
472 """Generates & On-boards the descriptors.
473 """
474 temp_dirs = []
475 catalog = vnfd_proxy.get_config('/vnfd-catalog')
476 endpoint = "update"
477 ping_vnfd, pong_vnfd, ping_pong_nsd = ping_pong_records
478
479 """
480 This upload routine can get called multiples times for upload API,
481 depending on the combinations of 'cloud_account' & 'endpoint'
482 fixtures. Since the records are cached at module level, we might end up
483 uploading the same uuids multiple times, thus causing errors. So a
484 simple work-around will be to skip the records when they are uploaded
485 for the second time.
486 """
487 def onboard_ping_pong_vnfds(ping_vnfd_file, pong_vnfd_file):
488 # On-board VNFDs
489 for file_name in [ping_vnfd_file, pong_vnfd_file]:
490 onboard_descriptor(
491 mgmt_session.host,
492 file_name,
493 logger,
494 endpoint,
495 scheme,
496 cert)
497
498 catalog = vnfd_proxy.get_config('/vnfd-catalog')
499 vnfds = catalog.vnfd
500
501 assert len(vnfds) == 2, "There should two vnfds"
502 assert "ping_vnfd" in [vnfds[0].name, vnfds[1].name]
503 assert "pong_vnfd" in [vnfds[0].name, vnfds[1].name]
504
505 def delete_nsds():
506 nsds = nsd_proxy.get("/nsd-catalog/nsd", list_obj=True)
507 for nsd_record in nsds.nsd:
508 xpath = "/nsd-catalog/nsd[id='{}']".format(nsd_record.id)
509 nsd_proxy.delete_config(xpath)
510
511 time.sleep(5)
512 nsds = nsd_proxy.get("/nsd-catalog/nsd", list_obj=True)
513 assert nsds is None or len(nsds.nsd) == 0
514 delete_nsds()
515
516 def delete_vnfds():
517 vnfds = vnfd_proxy.get("/vnfd-catalog/vnfd", list_obj=True)
518 for vnfd_record in vnfds.vnfd:
519 xpath = "/vnfd-catalog/vnfd[id='{}']".format(vnfd_record.id)
520 vnfd_proxy.delete_config(xpath)
521
522 time.sleep(5)
523 vnfds = vnfd_proxy.get("/vnfd-catalog/vnfd", list_obj=True)
524 assert vnfds is None or len(vnfds.vnfd) == 0
525
526 delete_vnfds()
527
528 if catalog is not None and len(catalog.vnfd) == 2 and endpoint == "upload":
529 return
530
531 ping_vnfd, pong_vnfd, ping_pong_nsd = ping_pong_records
532
533 if endpoint == "update":
534 for vnfd_record in [ping_vnfd, pong_vnfd]:
535 vnfd_record.descriptor.vnfd[0].description += "_update"
536 ping_pong_nsd.descriptor.nsd[0].description += "_update"
537
538 tmpdir2 = tempfile.TemporaryDirectory()
539 temp_dirs.append(tmpdir2)
540 ping_pong.generate_ping_pong_descriptors(pingcount=1,
541 write_to_file=True,
542 out_dir=tmpdir2.name,
543 ping_fmt='json',
544 pong_fmt='xml',
545 )
546
547 # On-board VNFDs without image
548 ping_vnfd_file = os.path.join(tmpdir2.name, 'ping_vnfd/vnfd/ping_vnfd.json')
549 pong_vnfd_file = os.path.join(tmpdir2.name, 'pong_vnfd/vnfd/pong_vnfd.xml')
550 onboard_ping_pong_vnfds(ping_vnfd_file, pong_vnfd_file)
551 delete_vnfds()
552
553 tmpdir = tempfile.TemporaryDirectory()
554 temp_dirs.append(tmpdir)
555
556 ping_vnfd_file, pong_vnfd_file, pingpong_nsd_file = \
557 generate_tar_files(tmpdir, ping_vnfd, pong_vnfd, ping_pong_nsd)
558
559 # On-board VNFDs with image
560 onboard_ping_pong_vnfds(ping_vnfd_file, pong_vnfd_file)
561
562
563 # On-board NSD
564 onboard_descriptor(
565 mgmt_session.host,
566 pingpong_nsd_file,
567 logger,
568 endpoint,
569 scheme,
570 cert)
571
572 catalog = nsd_proxy.get_config('/nsd-catalog')
573 nsds = catalog.nsd
574 assert len(nsds) == 1, "There should only be a single nsd"
575 assert nsds[0].name == "ping_pong_nsd"
576
577 # Temp directory cleanup
578 # for temp_dir in temp_dirs:
579 # temp_dir.cleanup()
580
581 def test_instantiate_ping_pong_nsr(self, logger, nsd_proxy, rwnsr_proxy, base_proxy, cloud_account):
582 def verify_input_parameters(running_config, config_param):
583 """
584 Verify the configured parameter set against the running configuration
585 """
586 for run_input_param in running_config.input_parameter:
587 if (run_input_param.xpath == config_param.xpath and
588 run_input_param.value == config_param.value):
589 return True
590
591 assert False, ("Verification of configured input parameters: { xpath:%s, value:%s} "
592 "is unsuccessful.\nRunning configuration: %s" % (config_param.xpath,
593 config_param.value,
594 running_config.input_parameter))
595
596 catalog = nsd_proxy.get_config('/nsd-catalog')
597 nsd = catalog.nsd[0]
598
599 input_parameters = []
600 descr_xpath = "/nsd:nsd-catalog/nsd:nsd[nsd:id='%s']/nsd:vendor" % nsd.id
601 descr_value = "automation"
602 in_param_id = str(uuid.uuid4())
603
604 input_param_1 = NsrYang.YangData_Nsr_NsInstanceConfig_Nsr_InputParameter(
605 xpath=descr_xpath,
606 value=descr_value)
607
608 input_parameters.append(input_param_1)
609
610 nsr = create_nsr(nsd, input_parameters, cloud_account.name)
611
612 logger.info("Instantiating the Network Service")
613 rwnsr_proxy.create_config('/ns-instance-config/nsr', nsr)
614
615 nsr_opdata = rwnsr_proxy.get('/ns-instance-opdata/nsr[ns-instance-config-ref="{}"]'.format(nsr.id))
616 assert nsr_opdata is not None
617
618 # Verify the input parameter configuration
619 running_config = rwnsr_proxy.get_config("/ns-instance-config/nsr[id='%s']" % nsr.id)
620 for input_param in input_parameters:
621 verify_input_parameters(running_config, input_param)
622
623 def test_wait_for_pingpong_started(self, rwnsr_proxy):
624 nsr_opdata = rwnsr_proxy.get('/ns-instance-opdata')
625 nsrs = nsr_opdata.nsr
626
627 for nsr in nsrs:
628 xpath = "/ns-instance-opdata/nsr[ns-instance-config-ref='{}']/operational-status".format(
629 nsr.ns_instance_config_ref)
630 rwnsr_proxy.wait_for(xpath, "running", fail_on=['failed'], timeout=180)
631
632 def test_wait_for_pingpong_configured(self, rwnsr_proxy):
633 nsr_opdata = rwnsr_proxy.get('/ns-instance-opdata')
634 nsrs = nsr_opdata.nsr
635
636 for nsr in nsrs:
637 xpath = "/ns-instance-opdata/nsr[ns-instance-config-ref='{}']/config-status".format(
638 nsr.ns_instance_config_ref)
639 rwnsr_proxy.wait_for(xpath, "configured", fail_on=['failed'], timeout=450)
640
641
642 @pytest.mark.teardown('pingpong')
643 @pytest.mark.depends('launchpad')
644 @pytest.mark.incremental
645 class TestPingPongTeardown(object):
646 def test_terminate_nsrs(self, rwvnfr_proxy, rwnsr_proxy, logger):
647 """
648 Terminate the instance and check if the record is deleted.
649
650 Asserts:
651 1. NSR record is deleted from instance-config.
652
653 """
654 logger.debug("Terminating Ping Pong NSR")
655 terminate_nsrs(rwvnfr_proxy, rwnsr_proxy, logger)
656
657 def test_delete_records(self, nsd_proxy, vnfd_proxy):
658 """Delete the NSD & VNFD records
659
660 Asserts:
661 The records are deleted.
662 """
663 nsds = nsd_proxy.get("/nsd-catalog/nsd", list_obj=True)
664 for nsd in nsds.nsd:
665 xpath = "/nsd-catalog/nsd[id='{}']".format(nsd.id)
666 nsd_proxy.delete_config(xpath)
667
668 nsds = nsd_proxy.get("/nsd-catalog/nsd", list_obj=True)
669 assert nsds is None or len(nsds.nsd) == 0
670
671 vnfds = vnfd_proxy.get("/vnfd-catalog/vnfd", list_obj=True)
672 for vnfd_record in vnfds.vnfd:
673 xpath = "/vnfd-catalog/vnfd[id='{}']".format(vnfd_record.id)
674 vnfd_proxy.delete_config(xpath)
675
676 vnfds = vnfd_proxy.get("/vnfd-catalog/vnfd", list_obj=True)
677 assert vnfds is None or len(vnfds.vnfd) == 0