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.
32 gi
.require_version('RwCloudYang', '1.0')
33 gi
.require_version('RwDts', '1.0')
34 gi
.require_version('RwNsmYang', '1.0')
35 gi
.require_version('RwLaunchpadYang', '1.0')
36 gi
.require_version('RwResourceMgrYang', '1.0')
37 gi
.require_version('RwcalYang', '1.0')
38 gi
.require_version('RwNsrYang', '1.0')
39 gi
.require_version('NsrYang', '1.0')
40 gi
.require_version('RwlogMgmtYang', '1.0')
42 from gi
.repository
import (
43 RwCloudYang
as rwcloudyang
,
45 RwLaunchpadYang
as launchpadyang
,
46 RwNsmYang
as rwnsmyang
,
47 RwNsrYang
as rwnsryang
,
49 RwResourceMgrYang
as rmgryang
,
50 RwcalYang
as rwcalyang
,
51 RwConfigAgentYang
as rwcfg_agent
,
55 from gi
.repository
.RwTypes
import RwStatus
56 import rift
.mano
.examples
.ping_pong_nsd
as ping_pong_nsd
64 'password': 'mypasswd',
65 'auth_url': 'http://10.66.4.27:5000/v3/',
66 'project_name': 'demo',
67 'mgmt_network': 'private',
71 if sys
.version_info
< (3, 4, 4):
72 asyncio
.ensure_future
= asyncio
.async
78 return ("C,/nsd:nsd-catalog/nsd:nsd" +
79 ("[nsd:id='{}']".format(k
) if k
is not None else ""))
83 return ("C,/vld:vld-catalog/vld:vld" +
84 ("[vld:id='{}']".format(k
) if k
is not None else ""))
88 return ("C,/vnfd:vnfd-catalog/vnfd:vnfd" +
89 ("[vnfd:id='{}']".format(k
) if k
is not None else ""))
93 return ("D,/vnfr:vnfr-catalog/vnfr:vnfr" +
94 ("[vnfr:id='{}']".format(k
) if k
is not None else ""))
98 return ("D,/vlr:vlr-catalog/vlr:vlr" +
99 ("[vlr:id='{}']".format(k
) if k
is not None else ""))
102 def nsd_ref_count(k
=None):
103 return ("D,/nsr:ns-instance-opdata/rw-nsr:nsd-ref-count" +
104 ("[rw-nsr:nsd-id-ref='{}']".format(k
) if k
is not None else ""))
107 def vnfd_ref_count(k
=None):
108 return ("D,/vnfr:vnfr-catalog/rw-vnfr:vnfd-ref-count" +
109 ("[rw-nsr:nsd-id-ref='{}']".format(k
) if k
is not None else ""))
112 def nsr_config(k
=None):
113 return ("C,/nsr:ns-instance-config/nsr:nsr" +
114 ("[nsr:id='{}']".format(k
) if k
is not None else ""))
117 def nsr_opdata(k
=None):
118 return ("D,/nsr:ns-instance-opdata/nsr:nsr" +
119 ("[nsr:ns-instance-config-ref='{}']".format(k
) if k
is not None else ""))
122 def nsr_config_status(k
=None):
123 return ("D,/nsr:ns-instance-opdata/nsr:nsr" +
124 ("[nsr:ns-instance-config-ref='{}']/config_status".format(k
) if k
is not None else ""))
127 def cm_state(k
=None):
129 return ("D,/rw-conman:cm-state/rw-conman:cm-nsr")
131 return ("D,/rw-conman:cm-state/rw-conman:cm-nsr" +
132 ("[rw-conman:id='{}']".format(k
) if k
is not None else ""))
135 def nsr_scale_group_instance(nsr_id
=None, group_name
=None, index
=None):
136 return (("D,/nsr:ns-instance-opdata/nsr:nsr") +
137 ("[nsr:ns-instance-config-ref='{}']".format(nsr_id
) if nsr_id
is not None else "") +
138 ("/nsr:scaling-group-record") +
139 ("[nsr:scaling-group-name-ref='{}']".format(group_name
) if group_name
is not None else "") +
141 ("[nsr:scaling-group-index-ref='{}']".format(index
) if index
is not None else ""))
144 def nsr_scale_group_instance_config(nsr_id
=None, group_name
=None, index
=None):
145 return (("C,/nsr:ns-instance-config/nsr:nsr") +
146 ("[nsr:id='{}']".format(nsr_id
) if nsr_id
is not None else "") +
147 ("/nsr:scaling-group") +
148 ("[nsr:scaling-group-name-ref='{}']".format(group_name
) if group_name
is not None else "") +
150 ("[nsr:index='{}']".format(index
) if index
is not None else ""))
153 class ManoQuerier(object):
154 def __init__(self
, log
, dts
):
159 def _read_query(self
, xpath
, do_trace
=False):
160 self
.log
.debug("Running XPATH read query: %s (trace: %s)", xpath
, do_trace
)
161 flags
= rwdts
.XactFlag
.MERGE
162 flags
+= rwdts
.XactFlag
.TRACE
if do_trace
else 0
163 res_iter
= yield from self
.dts
.query_read(
169 result
= yield from i
170 if result
is not None:
171 results
.append(result
.result
)
176 def get_cm_state(self
, nsr_id
=None):
177 return (yield from self
._read
_query
(XPaths
.cm_state(nsr_id
), False))
180 def get_nsr_opdatas(self
, nsr_id
=None):
181 return (yield from self
._read
_query
(XPaths
.nsr_opdata(nsr_id
), False))
184 def get_nsr_scale_group_instance_opdata(self
, nsr_id
=None, group_name
=None, index
=None):
185 return (yield from self
._read
_query
(XPaths
.nsr_scale_group_instance(nsr_id
, group_name
, index
), False))
186 #return (yield from self._read_query(XPaths.nsr_scale_group_instance(nsr_id, group_name), True))
189 def get_nsr_configs(self
, nsr_id
=None):
190 return (yield from self
._read
_query
(XPaths
.nsr_config(nsr_id
)))
193 def get_nsr_config_status(self
, nsr_id
=None):
194 return (yield from self
._read
_query
(XPaths
.nsr_config_status(nsr_id
)))
197 def get_vnfrs(self
, vnfr_id
=None):
198 return (yield from self
._read
_query
(XPaths
.vnfr(vnfr_id
)))
201 def get_vlrs(self
, vlr_id
=None):
202 return (yield from self
._read
_query
(XPaths
.vlr(vlr_id
)))
205 def get_nsd_ref_counts(self
, nsd_id
=None):
206 return (yield from self
._read
_query
(XPaths
.nsd_ref_count(nsd_id
)))
209 def get_vnfd_ref_counts(self
, vnfd_id
=None):
210 return (yield from self
._read
_query
(XPaths
.vnfd_ref_count(vnfd_id
)))
213 def delete_nsr(self
, nsr_id
):
214 with self
.dts
.transaction() as xact
:
215 yield from self
.dts
.query_delete(
216 XPaths
.nsr_config(nsr_id
),
218 #rwdts.XactFlag.TRACE,
223 def delete_nsd(self
, nsd_id
):
224 nsd_xpath
= XPaths
.nsd(nsd_id
)
225 self
.log
.debug("Attempting to delete NSD with path = %s", nsd_xpath
)
226 with self
.dts
.transaction() as xact
:
227 yield from self
.dts
.query_delete(
229 rwdts
.XactFlag
.ADVISE
,
233 def delete_vnfd(self
, vnfd_id
):
234 vnfd_xpath
= XPaths
.vnfd(vnfd_id
)
235 self
.log
.debug("Attempting to delete VNFD with path = %s", vnfd_xpath
)
236 with self
.dts
.transaction() as xact
:
237 yield from self
.dts
.query_delete(
239 rwdts
.XactFlag
.ADVISE
,
243 def update_nsd(self
, nsd_id
, nsd_msg
):
244 nsd_xpath
= XPaths
.nsd(nsd_id
)
245 self
.log
.debug("Attempting to update NSD with path = %s", nsd_xpath
)
246 with self
.dts
.transaction() as xact
:
247 yield from self
.dts
.query_update(
249 rwdts
.XactFlag
.ADVISE
,
254 def update_vnfd(self
, vnfd_id
, vnfd_msg
):
255 vnfd_xpath
= XPaths
.vnfd(vnfd_id
)
256 self
.log
.debug("Attempting to delete VNFD with path = %s", vnfd_xpath
)
257 with self
.dts
.transaction() as xact
:
258 yield from self
.dts
.query_update(
260 rwdts
.XactFlag
.ADVISE
,
265 def update_nsr_config(self
, nsr_id
, nsr_msg
):
266 nsr_xpath
= XPaths
.nsr_config(nsr_id
)
267 self
.log
.debug("Attempting to update NSR with path = %s", nsr_xpath
)
268 with self
.dts
.transaction() as xact
:
269 yield from self
.dts
.query_update(
271 rwdts
.XactFlag
.ADVISE|rwdts
.XactFlag
.REPLACE
,
276 class ManoTestCase(rift
.test
.dts
.AbstractDTSTest
):
278 def verify_nsr_state(self
, nsr_id
, state
):
279 nsrs
= yield from self
.querier
.get_nsr_opdatas(nsr_id
)
280 self
.assertEqual(1, len(nsrs
))
283 self
.log
.debug("Got nsr = %s", nsr
)
284 self
.assertEqual(state
, nsr
.operational_status
)
287 def verify_vlr_state(self
, vlr_id
, state
):
288 vlrs
= yield from self
.querier
.get_vlrs(vlr_id
)
289 self
.assertEqual(1, len(vlrs
))
292 self
.assertEqual(state
, vlr
.operational_status
)
294 def verify_vdu_state(self
, vdu
, state
):
295 self
.assertEqual(state
, vdu
.operational_status
)
298 def verify_vnf_state(self
, vnfr_id
, state
):
299 vnfrs
= yield from self
.querier
.get_vnfrs(vnfr_id
)
300 self
.assertEqual(1, len(vnfrs
))
303 self
.assertEqual(state
, vnfr
.operational_status
)
306 def terminate_nsr(self
, nsr_id
):
307 self
.log
.debug("Terminating nsr id: %s", nsr_id
)
308 yield from self
.querier
.delete_nsr(nsr_id
)
311 def verify_nsr_deleted(self
, nsr_id
):
312 nsr_opdatas
= yield from self
.querier
.get_nsr_opdatas(nsr_id
)
313 self
.assertEqual(0, len(nsr_opdatas
))
315 nsr_configs
= yield from self
.querier
.get_nsr_configs(nsr_id
)
316 self
.assertEqual(0, len(nsr_configs
))
319 def verify_num_vlrs(self
, num_vlrs
):
320 vlrs
= yield from self
.querier
.get_vlrs()
321 self
.assertEqual(num_vlrs
, len(vlrs
))
324 def get_nsr_vlrs(self
, nsr_id
):
325 nsrs
= yield from self
.querier
.get_nsr_opdatas(nsr_id
)
326 return [v
.vlr_ref
for v
in nsrs
[0].vlr
]
329 def get_nsr_vnfs(self
, nsr_id
):
330 nsrs
= yield from self
.querier
.get_nsr_opdatas(nsr_id
)
331 return nsrs
[0].constituent_vnfr_ref
334 def get_vnf_vlrs(self
, vnfr_id
):
335 vnfrs
= yield from self
.querier
.get_vnfrs(vnfr_id
)
336 return [i
.vlr_ref
for i
in vnfrs
[0].internal_vlr
]
339 def verify_num_nsr_vlrs(self
, nsr_id
, num_vlrs
):
340 vlrs
= yield from self
.get_nsr_vlrs(nsr_id
)
341 self
.assertEqual(num_vlrs
, len(vlrs
))
344 def verify_num_nsr_vnfrs(self
, nsr_id
, num_vnfs
):
345 vnfs
= yield from self
.get_nsr_vnfs(nsr_id
)
346 self
.assertEqual(num_vnfs
, len(vnfs
))
349 def verify_num_vnfr_vlrs(self
, vnfr_id
, num_vlrs
):
350 vlrs
= yield from self
.get_vnf_vlrs(vnfr_id
)
351 self
.assertEqual(num_vlrs
, len(vlrs
))
354 def get_vnf_vdus(self
, vnfr_id
):
355 vnfrs
= yield from self
.querier
.get_vnfrs(vnfr_id
)
356 return [i
for i
in vnfrs
[0].vdur
]
359 def verify_num_vnfr_vdus(self
, vnfr_id
, num_vdus
):
360 vdus
= yield from self
.get_vnf_vdus(vnfr_id
)
361 self
.assertEqual(num_vdus
, len(vdus
))
364 def verify_num_vnfrs(self
, num_vnfrs
):
365 vnfrs
= yield from self
.querier
.get_vnfrs()
366 self
.assertEqual(num_vnfrs
, len(vnfrs
))
369 def verify_nsd_ref_count(self
, nsd_id
, num_ref
):
370 nsd_ref_counts
= yield from self
.querier
.get_nsd_ref_counts(nsd_id
)
371 self
.assertEqual(num_ref
, nsd_ref_counts
[0].instance_ref_count
)
373 class DescriptorPublisher(object):
374 def __init__(self
, log
, loop
, dts
):
379 self
._registrations
= []
382 def publish(self
, w_path
, path
, desc
):
383 ready_event
= asyncio
.Event(loop
=self
.loop
)
386 def on_ready(regh
, status
):
387 self
.log
.debug("Create element: %s, obj-type:%s obj:%s",
388 path
, type(desc
), desc
)
389 with self
.dts
.transaction() as xact
:
390 regh
.create_element(path
, desc
, xact
.xact
)
391 self
.log
.debug("Created element: %s, obj:%s", path
, desc
)
394 handler
= rift
.tasklets
.DTS
.RegistrationHandler(
398 self
.log
.debug("Registering path: %s, obj:%s", w_path
, desc
)
399 reg
= yield from self
.dts
.register(
402 flags
=rwdts
.Flag
.PUBLISHER | rwdts
.Flag
.NO_PREP_READ
404 self
._registrations
.append(reg
)
405 self
.log
.debug("Registered path : %s", w_path
)
406 yield from ready_event
.wait()
410 def unpublish_all(self
):
411 self
.log
.debug("Deregistering all published descriptors")
412 for reg
in self
._registrations
:
416 class PingPongNsrConfigPublisher(object):
417 XPATH
= "C,/nsr:ns-instance-config"
419 def __init__(self
, log
, loop
, dts
, ping_pong
, cloud_account_name
):
425 self
.querier
= ManoQuerier(log
, dts
)
427 self
.nsr_config
= rwnsryang
.YangData_Nsr_NsInstanceConfig()
429 nsr
= rwnsryang
.YangData_Nsr_NsInstanceConfig_Nsr()
430 nsr
.id = str(uuid
.uuid4())
431 nsr
.name
= "ns1.{}".format(nsr
.id)
432 nsr
.nsd
= nsryang
.YangData_Nsr_NsInstanceConfig_Nsr_Nsd()
433 nsr
.nsd
.from_dict(ping_pong
.ping_pong_nsd
.nsd
.as_dict())
434 nsr
.cloud_account
= cloud_account_name
436 nsr
.vnf_cloud_account_map
.add().from_dict({
437 'member_vnf_index_ref': nsr
.nsd
.constituent_vnfd
[0].member_vnf_index
,
438 'config_agent_account': 'RiftCA',
439 #'cloud_account':'mock_account1'
442 inputs
= nsryang
.YangData_Nsr_NsInstanceConfig_Nsr_InputParameter()
443 inputs
.xpath
= "/nsd:nsd-catalog/nsd:nsd[nsd:id={}]/nsd:name".format(ping_pong
.nsd_id
)
444 inputs
.value
= "inigo montoya"
446 fast_cpu
= {'metadata_key': 'FASTCPU', 'metadata_value': 'True'}
447 self
.create_nsd_placement_group_map(nsr
,
448 group_name
= 'Orcus',
449 cloud_type
= 'openstack',
450 construct_type
= 'host_aggregate',
451 construct_value
= [fast_cpu
])
453 fast_storage
= {'metadata_key': 'FASTSSD', 'metadata_value': 'True'}
454 self
.create_nsd_placement_group_map(nsr
,
455 group_name
= 'Quaoar',
456 cloud_type
= 'openstack',
457 construct_type
= 'host_aggregate',
458 construct_value
= [fast_storage
])
460 fast_cpu
= {'metadata_key': 'BLUE_HW', 'metadata_value': 'True'}
461 self
.create_vnfd_placement_group_map(nsr
,
463 vnfd_id
= ping_pong
.ping_vnfd_id
,
464 cloud_type
= 'openstack',
465 construct_type
= 'host_aggregate',
466 construct_value
= [fast_cpu
])
468 fast_storage
= {'metadata_key': 'YELLOW_HW', 'metadata_value': 'True'}
469 self
.create_vnfd_placement_group_map(nsr
,
470 group_name
= 'Weywot',
471 vnfd_id
= ping_pong
.pong_vnfd_id
,
472 cloud_type
= 'openstack',
473 construct_type
= 'host_aggregate',
474 construct_value
= [fast_storage
])
477 nsr
.input_parameter
.append(inputs
)
480 self
.nsr_config
.nsr
.append(nsr
)
482 self
._ready
_event
= asyncio
.Event(loop
=self
.loop
)
483 asyncio
.ensure_future(self
.register(), loop
=loop
)
488 def on_ready(regh
, status
):
489 self
._ready
_event
.set()
491 self
.log
.debug("Registering path: %s", PingPongNsrConfigPublisher
.XPATH
)
492 self
.reg
= yield from self
.dts
.register(
493 PingPongNsrConfigPublisher
.XPATH
,
494 flags
=rwdts
.Flag
.PUBLISHER
,
495 handler
=rift
.tasklets
.DTS
.RegistrationHandler(
502 self
.log
.debug("Publishing NSR: {}".format(self
.nsr_config
))
503 yield from self
._ready
_event
.wait()
504 with self
.dts
.transaction() as xact
:
505 self
.reg
.create_element(
506 PingPongNsrConfigPublisher
.XPATH
,
514 def create_scale_group_instance(self
, group_name
, index
):
516 scaling_group
= self
.nsr_config
.nsr
[0].scaling_group
.add()
517 scaling_group
.from_dict({
518 "scaling_group_name_ref": group_name
,
519 "instance": [{"index": index
}],
521 with self
.dts
.transaction() as xact
:
522 self
.reg
.update_element(
523 PingPongNsrConfigPublisher
.XPATH
,
530 def create_nsd_placement_group_map(self
,
536 placement_group
= nsr
.nsd_placement_group_maps
.add()
537 placement_group
.from_dict({
538 "placement_group_ref" : group_name
,
539 "cloud_type" : cloud_type
,
540 construct_type
: construct_value
,
544 def create_vnfd_placement_group_map(self
,
551 placement_group
= nsr
.vnfd_placement_group_maps
.add()
552 placement_group
.from_dict({
553 "placement_group_ref" : group_name
,
554 "vnfd_id_ref" : vnfd_id
,
555 "cloud_type" : cloud_type
,
556 construct_type
: construct_value
,
561 def delete_scale_group_instance(self
, group_name
, index
):
562 self
.log
.debug("Deleting scale group %s instance %s", group_name
, index
)
563 #del self.nsr_config.nsr[0].scaling_group[0].instance[0]
564 xpath
= XPaths
.nsr_scale_group_instance_config(self
.nsr_config
.nsr
[0].id, group_name
, index
)
565 yield from self
.dts
.query_delete(xpath
, flags
=rwdts
.XactFlag
.ADVISE
)
566 #with self.dts.transaction() as xact:
567 # self.reg.update_element(
568 # PingPongNsrConfigPublisher.XPATH,
570 # flags=rwdts.XactFlag.REPLACE,
574 def deregister(self
):
575 if self
.reg
is not None:
576 self
.reg
.deregister()
578 def create_nsr_vl(self
):
579 vld
= self
.nsr_config
.nsr
[0].nsd
.vld
.add()
580 vld
.id = 'ping_pong_vld_2'
581 vld
.name
= 'ping_pong_vld_2' # hard coded
582 vld
.short_name
= vld
.name
583 vld
.vendor
= 'RIFT.io'
584 vld
.description
= 'Toy VL'
586 vld
.type_yang
= 'ELAN'
588 # cpref = vld.vnfd_connection_point_ref.add()
589 # cpref.member_vnf_index_ref = cp[0]
590 # cpref.vnfd_id_ref = cp[1]
591 # cpref.vnfd_connection_point_ref = cp[2]
593 vld
= self
.nsr_config
.nsr
[0].vl_cloud_account_map
.add()
594 vld
.vld_id_ref
= 'ping_pong_vld_2'
595 vld
.cloud_accounts
= ["mock_account"]
598 def add_nsr_vl(self
):
600 yield from self
.querier
.update_nsr_config(
601 self
.nsr_config
.nsr
[0].id,
602 self
.nsr_config
.nsr
[0],
606 def del_nsr_vl(self
):
607 for vld
in self
.nsr_config
.nsr
[0].nsd
.vld
:
608 if vld
.id == 'ping_pong_vld_2':
609 self
.nsr_config
.nsr
[0].nsd
.vld
.remove(vld
)
612 yield from self
.querier
.update_nsr_config(
613 self
.nsr_config
.nsr
[0].id,
614 self
.nsr_config
.nsr
[0],
617 def update_vnf_cloud_map(self
,vnf_cloud_map
):
618 self
.log
.debug("Modifying NSR to add VNF cloud account map: {}".format(vnf_cloud_map
))
619 for vnf_index
,cloud_acct
in vnf_cloud_map
.items():
620 vnf_maps
= [vnf_map
for vnf_map
in self
.nsr_config
.nsr
[0].vnf_cloud_account_map
if vnf_index
== vnf_map
.member_vnf_index_ref
]
622 vnf_maps
[0].cloud_account
= cloud_acct
624 self
.nsr_config
.nsr
[0].vnf_cloud_account_map
.add().from_dict({
625 'member_vnf_index_ref':vnf_index
,
626 'cloud_account':cloud_acct
630 class PingPongDescriptorPublisher(object):
631 def __init__(self
, log
, loop
, dts
, num_external_vlrs
=1, num_internal_vlrs
=1, num_ping_vms
=1):
636 self
.querier
= ManoQuerier(self
.log
, self
.dts
)
637 self
.publisher
= DescriptorPublisher(self
.log
, self
.loop
, self
.dts
)
638 self
.ping_vnfd
, self
.pong_vnfd
, self
.ping_pong_nsd
= \
639 ping_pong_nsd
.generate_ping_pong_descriptors(
641 external_vlr_count
=num_external_vlrs
,
642 internal_vlr_count
=num_internal_vlrs
,
645 use_scale_group
=True,
646 use_mon_params
=False,
649 self
.config_dir
= os
.path
.join(os
.getenv('RIFT_ARTIFACTS'),
651 self
.ping_pong_nsd
.id,
656 return self
.ping_pong_nsd
.id
659 def ping_vnfd_id(self
):
660 return self
.ping_vnfd
.id
663 def pong_vnfd_id(self
):
664 return self
.pong_vnfd
.id
667 def publish_desciptors(self
):
669 xpath
= XPaths
.vnfd(self
.ping_vnfd_id
)
670 xpath_wild
= XPaths
.vnfd()
671 for obj
in self
.ping_vnfd
.descriptor
.vnfd
:
672 self
.log
.debug("Publishing ping_vnfd path: %s - %s, type:%s, obj:%s",
673 xpath
, xpath_wild
, type(obj
), obj
)
674 yield from self
.publisher
.publish(xpath_wild
, xpath
, obj
)
677 xpath
= XPaths
.vnfd(self
.pong_vnfd_id
)
678 xpath_wild
= XPaths
.vnfd()
679 for obj
in self
.pong_vnfd
.descriptor
.vnfd
:
680 self
.log
.debug("Publishing pong_vnfd path: %s, wild_path: %s, obj:%s",
681 xpath
, xpath_wild
, obj
)
682 yield from self
.publisher
.publish(xpath_wild
, xpath
, obj
)
684 # Publish ping_pong_nsd
685 xpath
= XPaths
.nsd(self
.nsd_id
)
686 xpath_wild
= XPaths
.nsd()
687 for obj
in self
.ping_pong_nsd
.descriptor
.nsd
:
688 self
.log
.debug("Publishing ping_pong nsd path: %s, wild_path: %s, obj:%s",
689 xpath
, xpath_wild
, obj
)
690 yield from self
.publisher
.publish(xpath_wild
, xpath
, obj
)
692 self
.log
.debug("DONE - publish_desciptors")
694 def unpublish_descriptors(self
):
695 self
.publisher
.unpublish_all()
698 def delete_nsd(self
):
699 yield from self
.querier
.delete_nsd(self
.ping_pong_nsd
.id)
702 def delete_ping_vnfd(self
):
703 yield from self
.querier
.delete_vnfd(self
.ping_vnfd
.id)
706 def update_nsd(self
):
707 yield from self
.querier
.update_nsd(
708 self
.ping_pong_nsd
.id,
709 self
.ping_pong_nsd
.descriptor
.nsd
[0]
713 def update_ping_vnfd(self
):
714 yield from self
.querier
.update_vnfd(
716 self
.ping_vnfd
.descriptor
.vnfd
[0]
722 class ManoTestCase(rift
.test
.dts
.AbstractDTSTest
):
724 DTS GI interface unittests
726 Note: Each tests uses a list of asyncio.Events for staging through the
727 test. These are required here because we are bring up each coroutine
728 ("tasklet") at the same time and are not implementing any re-try
729 mechanisms. For instance, this is used in numerous tests to make sure that
730 a publisher is up and ready before the subscriber sends queries. Such
731 event lists should not be used in production software.
735 def configure_suite(cls
, rwmain
):
736 vns_dir
= os
.environ
.get('VNS_DIR')
737 vnfm_dir
= os
.environ
.get('VNFM_DIR')
738 nsm_dir
= os
.environ
.get('NSM_DIR')
739 rm_dir
= os
.environ
.get('RM_DIR')
741 rwmain
.add_tasklet(vns_dir
, 'rwvnstasklet')
742 rwmain
.add_tasklet(vnfm_dir
, 'rwvnfmtasklet')
743 rwmain
.add_tasklet(nsm_dir
, 'rwnsmtasklet')
744 rwmain
.add_tasklet(rm_dir
, 'rwresmgrtasklet')
745 rwmain
.add_tasklet(rm_dir
, 'rwconmantasklet')
748 def configure_schema(cls
):
749 return rwnsmyang
.get_schema()
752 def configure_timeout(cls
):
756 def get_cal_account(account_type
, account_name
):
758 Creates an object for class RwcalYang.Clo
760 account
= rwcloudyang
.CloudAccount()
761 if account_type
== 'mock':
762 account
.name
= account_name
763 account
.account_type
= "mock"
764 account
.mock
.username
= "mock_user"
765 elif ((account_type
== 'openstack_static') or (account_type
== 'openstack_dynamic')):
766 account
.name
= account_name
767 account
.account_type
= 'openstack'
768 account
.openstack
.key
= openstack_info
['username']
769 account
.openstack
.secret
= openstack_info
['password']
770 account
.openstack
.auth_url
= openstack_info
['auth_url']
771 account
.openstack
.tenant
= openstack_info
['project_name']
772 account
.openstack
.mgmt_network
= openstack_info
['mgmt_network']
776 def configure_cloud_account(self
, dts
, cloud_type
, cloud_name
="cloud1"):
777 account
= self
.get_cal_account(cloud_type
, cloud_name
)
778 account_xpath
= "C,/rw-cloud:cloud/rw-cloud:account[rw-cloud:name='{}']".format(cloud_name
)
779 self
.log
.info("Configuring cloud-account: %s", account
)
780 yield from dts
.query_create(account_xpath
,
781 rwdts
.XactFlag
.ADVISE
,
785 def wait_tasklets(self
):
786 yield from asyncio
.sleep(5, loop
=self
.loop
)
788 def configure_test(self
, loop
, test_id
):
789 self
.log
.debug("STARTING - %s", self
.id())
790 self
.tinfo
= self
.new_tinfo(self
.id())
791 self
.dts
= rift
.tasklets
.DTS(self
.tinfo
, self
.schema
, self
.loop
)
792 self
.ping_pong
= PingPongDescriptorPublisher(self
.log
, self
.loop
, self
.dts
)
793 self
.querier
= ManoQuerier(self
.log
, self
.dts
)
794 self
.nsr_publisher
= PingPongNsrConfigPublisher(
802 def test_create_nsr_record(self
):
805 def verify_cm_state(termination
=False, nsrid
=None):
806 self
.log
.debug("Verifying cm_state path = %s", XPaths
.cm_state(nsrid
))
807 #print("###>>> Verifying cm_state path:", XPaths.cm_state(nsrid))
812 yield from asyncio
.sleep(loop_sleep
, loop
=self
.loop
)
815 cm_nsr_i
= yield from self
.querier
.get_cm_state(nsr_id
=nsrid
)
816 if (cm_nsr_i
is not None and len(cm_nsr_i
) != 0):
817 self
.assertEqual(1, len(cm_nsr_i
))
818 cm_nsr
= cm_nsr_i
[0].as_dict()
819 #print("###>>> cm_nsr=", cm_nsr)
821 if len(cm_nsr_i
) == 0:
822 print("\n###>>> cm-state NSR deleted OK <<<###\n")
824 elif (cm_nsr
is not None and
825 'state' in cm_nsr
and
826 (cm_nsr
['state'] == 'ready')):
827 self
.log
.debug("Got cm_nsr record %s", cm_nsr
)
828 print("\n###>>> cm-state NSR 'ready' OK <<<###\n")
831 # if (len(cm_nsr_i) == 1 and cm_nsr_i[0].state == 'ready'):
832 # self.log.debug("Got cm_nsr record %s", cm_nsr)
834 # yield from asyncio.sleep(10, loop=self.loop)
836 print("###>>> Failed cm-state, termination:", termination
)
837 self
.assertEqual(1, loop_count
)
840 def verify_nsr_opdata(termination
=False):
841 self
.log
.debug("Verifying nsr opdata path = %s", XPaths
.nsr_opdata())
844 nsrs
= yield from self
.querier
.get_nsr_opdatas()
848 nsrs
= yield from self
.querier
.get_nsr_opdatas()
850 self
.log
.debug("No active NSR records found. NSR termination successful")
853 self
.assertEqual(0, len(nsrs
))
854 self
.log
.error("Active NSR records found. NSR termination failed")
857 self
.log
.debug("No active NSR records found. NSR termination successful")
858 self
.assertEqual(0, len(nsrs
))
862 self
.log
.debug("Got nsr record %s", nsr
)
863 if nsr
.operational_status
== 'running':
864 self
.log
.debug("!!! Rcvd NSR with running status !!!")
865 self
.assertEqual("configuring", nsr
.config_status
)
868 self
.log
.debug("Rcvd NSR with %s status", nsr
.operational_status
)
869 self
.log
.debug("Sleeping for 10 seconds")
870 yield from asyncio
.sleep(10, loop
=self
.loop
)
873 def verify_nsr_config(termination
=False):
874 self
.log
.debug("Verifying nsr config path = %s", XPaths
.nsr_config())
876 nsr_configs
= yield from self
.querier
.get_nsr_configs()
877 self
.assertEqual(1, len(nsr_configs
))
879 nsr_config
= nsr_configs
[0]
881 "/nsd:nsd-catalog/nsd:nsd[nsd:id={}]/nsd:name".format(self
.ping_pong
.nsd_id
),
882 nsr_config
.input_parameter
[0].xpath
,
886 def verify_nsr_config_status(termination
=False, nsrid
=None):
887 if termination
is False and nsrid
is not None:
888 self
.log
.debug("Verifying nsr config status path = %s", XPaths
.nsr_opdata(nsrid
))
894 yield from asyncio
.sleep(loop_sleep
, loop
=self
.loop
)
895 nsr_opdata_l
= yield from self
.querier
.get_nsr_opdatas(nsrid
)
896 self
.assertEqual(1, len(nsr_opdata_l
))
897 nsr_opdata
= nsr_opdata_l
[0].as_dict()
898 if ("configured" == nsr_opdata
['config_status']):
899 print("\n###>>> NSR Config Status 'configured' OK <<<###\n")
901 self
.assertEqual("configured", nsr_opdata
['config_status'])
904 def verify_vnfr_record(termination
=False):
905 self
.log
.debug("Verifying vnfr record path = %s, Termination=%d",
906 XPaths
.vnfr(), termination
)
909 vnfrs
= yield from self
.querier
.get_vnfrs()
914 self
.log
.debug("VNFR still exists = %s", vnfr
)
916 yield from asyncio
.sleep(.5, loop
=self
.loop
)
919 assert len(vnfrs
) == 0
922 vnfrs
= yield from self
.querier
.get_vnfrs()
923 if len(vnfrs
) != 0 and termination
is False:
925 self
.log
.debug("Rcvd VNFR with %s status", vnfr
.operational_status
)
926 if vnfr
.operational_status
== 'running':
927 self
.log
.debug("!!! Rcvd VNFR with running status !!!")
930 elif vnfr
.operational_status
== "failed":
931 self
.log
.debug("!!! Rcvd VNFR with failed status !!!")
934 self
.log
.debug("Sleeping for 10 seconds")
935 yield from asyncio
.sleep(10, loop
=self
.loop
)
939 def verify_vnfr_cloud_account(vnf_index
, cloud_account
):
940 self
.log
.debug("Verifying vnfr record Cloud account for vnf index = %d is %s", vnf_index
,cloud_account
)
941 vnfrs
= yield from self
.querier
.get_vnfrs()
942 cloud_accounts
= [vnfr
.cloud_account
for vnfr
in vnfrs
if vnfr
.member_vnf_index_ref
== vnf_index
]
943 self
.log
.debug("VNFR cloud account for index %d is %s", vnf_index
,cloud_accounts
[0])
944 assert cloud_accounts
[0] == cloud_account
947 def verify_vlr_record(termination
=False):
948 vlr_xpath
= XPaths
.vlr()
949 self
.log
.debug("Verifying vlr record path = %s, termination: %s",
950 vlr_xpath
, termination
)
951 res_iter
= yield from self
.dts
.query_read(vlr_xpath
)
954 result
= yield from i
956 self
.assertIsNone(result
)
958 self
.log
.debug("Got vlr record %s", result
)
961 def verify_vlrs(nsr_id
, count
=0):
963 nsrs
= yield from self
.querier
.get_nsr_opdatas()
965 self
.log
.debug("Got nsr record %s", nsr
)
966 if nsr
.operational_status
== 'running':
967 self
.log
.debug("!!! Rcvd NSR with running status !!!")
968 # Check the VLR count
969 if (len(nsr
.vlr
)) == count
:
970 self
.log
.debug("NSR %s has %d VLRs", nsr_id
, count
)
973 self
.log
.debug("Rcvd NSR %s with %s status", nsr_id
, nsr
.operational_status
)
974 self
.log
.debug("Sleeping for 10 seconds")
975 yield from asyncio
.sleep(10, loop
=self
.loop
)
978 def verify_nsd_ref_count(termination
):
979 self
.log
.debug("Verifying nsd ref count= %s", XPaths
.nsd_ref_count())
980 res_iter
= yield from self
.dts
.query_read(XPaths
.nsd_ref_count())
983 result
= yield from i
984 self
.log
.debug("Got nsd ref count record %s", result
)
987 def verify_vnfd_ref_count(termination
):
988 self
.log
.debug("Verifying vnfd ref count= %s", XPaths
.vnfd_ref_count())
989 res_iter
= yield from self
.dts
.query_read(XPaths
.vnfd_ref_count())
992 result
= yield from i
993 self
.log
.debug("Got vnfd ref count record %s", result
)
996 def verify_scale_group_reaches_state(nsr_id
, scale_group
, index
, state
, timeout
=1000):
997 start_time
= time
.time()
998 instance_state
= None
999 while (time
.time() - start_time
) < timeout
:
1000 results
= yield from self
.querier
.get_nsr_opdatas(nsr_id
=nsr_id
)
1001 if len(results
) == 1:
1003 if len(result
.scaling_group_record
) == 0:
1006 if len(result
.scaling_group_record
[0].instance
) == 0:
1009 instance
= result
.scaling_group_record
[0].instance
[0]
1010 self
.assertEqual(instance
.scaling_group_index_ref
, index
)
1012 instance_state
= instance
.op_status
1013 if instance_state
== state
:
1014 self
.log
.debug("Scale group instance reached %s state", state
)
1017 yield from asyncio
.sleep(1, loop
=self
.loop
)
1019 self
.assertEqual(state
, instance_state
)
1022 def verify_results(termination
=False, nsrid
=None):
1023 yield from verify_vnfr_record(termination
)
1024 #yield from verify_vlr_record(termination)
1025 yield from verify_nsr_opdata(termination
)
1026 yield from verify_nsr_config(termination
)
1027 yield from verify_nsd_ref_count(termination
)
1028 yield from verify_vnfd_ref_count(termination
)
1031 yield from verify_cm_state(termination
, nsrid
)
1032 yield from verify_nsr_config_status(termination
, nsrid
)
1035 def verify_scale_instance(index
):
1036 self
.log
.debug("Verifying scale record path = %s, Termination=%d",
1037 XPaths
.vnfr(), termination
)
1040 vnfrs
= yield from self
.querier
.get_vnfrs()
1045 self
.log
.debug("VNFR still exists = %s", vnfr
)
1048 assert len(vnfrs
) == 0
1051 vnfrs
= yield from self
.querier
.get_vnfrs()
1052 if len(vnfrs
) != 0 and termination
is False:
1054 self
.log
.debug("Rcvd VNFR with %s status", vnfr
.operational_status
)
1055 if vnfr
.operational_status
== 'running':
1056 self
.log
.debug("!!! Rcvd VNFR with running status !!!")
1059 elif vnfr
.operational_status
== "failed":
1060 self
.log
.debug("!!! Rcvd VNFR with failed status !!!")
1063 self
.log
.debug("Sleeping for 10 seconds")
1064 yield from asyncio
.sleep(10, loop
=self
.loop
)
1067 def terminate_ns(nsr_id
):
1068 xpath
= XPaths
.nsr_config(nsr_id
)
1069 self
.log
.debug("Terminating network service with path %s", xpath
)
1070 yield from self
.dts
.query_delete(xpath
, flags
=rwdts
.XactFlag
.ADVISE
)
1071 self
.log
.debug("Terminated network service with path %s", xpath
)
1075 yield from self
.wait_tasklets()
1079 yield from self
.configure_cloud_account(self
.dts
, cloud_type
, "mock_account")
1080 yield from self
.configure_cloud_account(self
.dts
, cloud_type
, "mock_account1")
1082 yield from self
.ping_pong
.publish_desciptors()
1084 # Attempt deleting VNFD not in use
1085 yield from self
.ping_pong
.update_ping_vnfd()
1087 # Attempt updating NSD not in use
1088 yield from self
.ping_pong
.update_nsd()
1090 # Attempt deleting VNFD not in use
1091 yield from self
.ping_pong
.delete_ping_vnfd()
1093 # Attempt deleting NSD not in use
1094 yield from self
.ping_pong
.delete_nsd()
1096 yield from self
.ping_pong
.publish_desciptors()
1098 nsr_id
= yield from self
.nsr_publisher
.publish()
1100 yield from verify_results(nsrid
=nsr_id
)
1102 # yield from self.nsr_publisher.create_scale_group_instance("ping_group", 1)
1104 # yield from verify_scale_group_reaches_state(nsr_id, "ping_group", 1, "running")
1106 # yield from self.nsr_publisher.delete_scale_group_instance("ping_group", 1)
1108 yield from asyncio
.sleep(10, loop
=self
.loop
)
1110 # Attempt deleting VNFD in use
1111 yield from self
.ping_pong
.delete_ping_vnfd()
1113 # Attempt updating NSD in use
1114 yield from self
.ping_pong
.update_nsd()
1116 # Update NSD in use with new VL
1117 yield from self
.nsr_publisher
.add_nsr_vl()
1119 # Verify the new VL has been added
1120 yield from verify_vlrs(nsr_id
, count
=2)
1122 # Delete the added VL
1123 yield from self
.nsr_publisher
.del_nsr_vl()
1125 # Verify the new VL has been added
1126 yield from verify_vlrs(nsr_id
, count
=1)
1128 # Attempt deleting NSD in use
1129 yield from self
.ping_pong
.delete_nsd()
1131 yield from terminate_ns(nsr_id
)
1133 yield from asyncio
.sleep(25, loop
=self
.loop
)
1134 self
.log
.debug("Verifying termination results")
1135 yield from verify_results(termination
=True, nsrid
=nsr_id
)
1136 self
.log
.debug("Verified termination results")
1138 # Multi site NS case
1139 self
.log
.debug("Testing multi site NS")
1140 self
.nsr_publisher
.update_vnf_cloud_map({1:"mock_account1",2:"mock_account"})
1141 nsr_id
= yield from self
.nsr_publisher
.publish()
1143 yield from verify_results(nsrid
=nsr_id
)
1144 yield from verify_vnfr_cloud_account(1,"mock_account1")
1145 yield from verify_vnfr_cloud_account(2,"mock_account")
1146 yield from verify_vlrs(nsr_id
, count
=2)
1148 yield from terminate_ns(nsr_id
)
1150 yield from asyncio
.sleep(25, loop
=self
.loop
)
1151 self
.log
.debug("Verifying termination results for multi site NS")
1152 yield from verify_results(termination
=True, nsrid
=nsr_id
)
1153 self
.log
.debug("Verified termination results for multi site NS")
1155 self
.log
.debug("Attempting to delete VNFD for real")
1156 yield from self
.ping_pong
.delete_ping_vnfd()
1158 self
.log
.debug("Attempting to delete NSD for real")
1159 yield from self
.ping_pong
.delete_nsd()
1161 future
= asyncio
.ensure_future(run_test(), loop
=self
.loop
)
1162 self
.run_until(future
.done
)
1163 if future
.exception() is not None:
1164 self
.log
.error("Caught exception during test")
1165 raise future
.exception()
1169 plugin_dir
= os
.path
.join(os
.environ
["RIFT_INSTALL"], "usr/lib/rift/plugins")
1170 if 'VNS_DIR' not in os
.environ
:
1171 os
.environ
['VNS_DIR'] = os
.path
.join(plugin_dir
, 'rwvns')
1173 if 'VNFM_DIR' not in os
.environ
:
1174 os
.environ
['VNFM_DIR'] = os
.path
.join(plugin_dir
, 'rwvnfm')
1176 if 'NSM_DIR' not in os
.environ
:
1177 os
.environ
['NSM_DIR'] = os
.path
.join(plugin_dir
, 'rwnsm')
1179 if 'RM_DIR' not in os
.environ
:
1180 os
.environ
['RM_DIR'] = os
.path
.join(plugin_dir
, 'rwresmgrtasklet')
1182 runner
= xmlrunner
.XMLTestRunner(output
=os
.environ
["RIFT_MODULE_TEST"])
1184 parser
= argparse
.ArgumentParser()
1185 parser
.add_argument('-v', '--verbose', action
='store_true')
1186 parser
.add_argument('-n', '--no-runner', action
='store_true')
1187 args
, unittest_args
= parser
.parse_known_args()
1191 ManoTestCase
.log_level
= logging
.DEBUG
if args
.verbose
else logging
.WARN
1193 unittest
.main(testRunner
=runner
, argv
=[sys
.argv
[0]] + unittest_args
)
1195 if __name__
== '__main__':