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