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