blob: d85088b536c509e8b05b42e62f31bf8ee59a255b [file] [log] [blame]
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -04001#!/usr/bin/env python3
2
Philip Josephf4937572017-03-03 01:55:37 +05303#
Philip Joseph0f5e8c02017-03-03 01:54:51 +05304# Copyright 2016-2017 RIFT.IO Inc
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -04005#
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
20import asyncio
21import os
22import sys
23import unittest
24import uuid
25import xmlrunner
26import argparse
27import logging
28import time
29import types
30
31import gi
32gi.require_version('RwCloudYang', '1.0')
33gi.require_version('RwDts', '1.0')
34gi.require_version('RwNsmYang', '1.0')
35gi.require_version('RwLaunchpadYang', '1.0')
36gi.require_version('RwResourceMgrYang', '1.0')
37gi.require_version('RwcalYang', '1.0')
38gi.require_version('RwNsrYang', '1.0')
39gi.require_version('NsrYang', '1.0')
40gi.require_version('RwlogMgmtYang', '1.0')
41
42from gi.repository import (
43 RwCloudYang as rwcloudyang,
44 RwDts as rwdts,
45 RwLaunchpadYang as launchpadyang,
46 RwNsmYang as rwnsmyang,
47 RwNsrYang as rwnsryang,
48 NsrYang as nsryang,
49 RwResourceMgrYang as rmgryang,
50 RwcalYang as rwcalyang,
51 RwConfigAgentYang as rwcfg_agent,
52 RwlogMgmtYang
53)
54
55from gi.repository.RwTypes import RwStatus
56import rift.mano.examples.ping_pong_nsd as ping_pong_nsd
57import rift.tasklets
58import rift.test.dts
59import rw_peas
Philip Josephf4937572017-03-03 01:55:37 +053060from rift.mano.utils.project import (
61 ManoProject,
62 DEFAULT_PROJECT,
63)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040064
65
Philip Josephf4937572017-03-03 01:55:37 +053066PROJECT = 'default'
67
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040068openstack_info = {
69 'username': 'pluto',
70 'password': 'mypasswd',
71 'auth_url': 'http://10.66.4.27:5000/v3/',
72 'project_name': 'demo',
73 'mgmt_network': 'private',
74 }
75
76
77if sys.version_info < (3, 4, 4):
78 asyncio.ensure_future = asyncio.async
79
80
81class XPaths(object):
82 @staticmethod
83 def nsd(k=None):
Philip Joseph4f810f22017-03-07 23:09:10 +053084 return ("C,/project-nsd:nsd-catalog/project-nsd:nsd" +
85 ("[project-nsd:id='{}']".format(k) if k is not None else ""))
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040086
87 @staticmethod
88 def vld(k=None):
89 return ("C,/vld:vld-catalog/vld:vld" +
90 ("[vld:id='{}']".format(k) if k is not None else ""))
91
92 @staticmethod
93 def vnfd(k=None):
Philip Joseph4f810f22017-03-07 23:09:10 +053094 return ("C,/project-vnfd:vnfd-catalog/project-vnfd:vnfd" +
95 ("[project-vnfd:id='{}']".format(k) if k is not None else ""))
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040096
97 @staticmethod
98 def vnfr(k=None):
99 return ("D,/vnfr:vnfr-catalog/vnfr:vnfr" +
100 ("[vnfr:id='{}']".format(k) if k is not None else ""))
101
102 @staticmethod
103 def vlr(k=None):
104 return ("D,/vlr:vlr-catalog/vlr:vlr" +
105 ("[vlr:id='{}']".format(k) if k is not None else ""))
106
107 @staticmethod
108 def nsd_ref_count(k=None):
109 return ("D,/nsr:ns-instance-opdata/rw-nsr:nsd-ref-count" +
110 ("[rw-nsr:nsd-id-ref='{}']".format(k) if k is not None else ""))
111
112 @staticmethod
113 def vnfd_ref_count(k=None):
114 return ("D,/vnfr:vnfr-catalog/rw-vnfr:vnfd-ref-count" +
115 ("[rw-nsr:nsd-id-ref='{}']".format(k) if k is not None else ""))
116
117 @staticmethod
118 def nsr_config(k=None):
119 return ("C,/nsr:ns-instance-config/nsr:nsr" +
120 ("[nsr:id='{}']".format(k) if k is not None else ""))
121
122 @staticmethod
123 def nsr_opdata(k=None):
124 return ("D,/nsr:ns-instance-opdata/nsr:nsr" +
125 ("[nsr:ns-instance-config-ref='{}']".format(k) if k is not None else ""))
126
127 @staticmethod
128 def nsr_config_status(k=None):
129 return ("D,/nsr:ns-instance-opdata/nsr:nsr" +
130 ("[nsr:ns-instance-config-ref='{}']/config_status".format(k) if k is not None else ""))
131
132 @staticmethod
133 def cm_state(k=None):
Philip Josephf4937572017-03-03 01:55:37 +0530134 return ("D,/rw-conman:cm-state/rw-conman:cm-nsr" +
135 ("[rw-conman:id='{}']".format(k) if k is not None else ""))
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400136
137 @staticmethod
138 def nsr_scale_group_instance(nsr_id=None, group_name=None, index=None):
139 return (("D,/nsr:ns-instance-opdata/nsr:nsr") +
140 ("[nsr:ns-instance-config-ref='{}']".format(nsr_id) if nsr_id is not None else "") +
141 ("/nsr:scaling-group-record") +
142 ("[nsr:scaling-group-name-ref='{}']".format(group_name) if group_name is not None else "") +
143 ("/nsr:instance") +
144 ("[nsr:scaling-group-index-ref='{}']".format(index) if index is not None else ""))
145
146 @staticmethod
147 def nsr_scale_group_instance_config(nsr_id=None, group_name=None, index=None):
148 return (("C,/nsr:ns-instance-config/nsr:nsr") +
149 ("[nsr:id='{}']".format(nsr_id) if nsr_id is not None else "") +
150 ("/nsr:scaling-group") +
151 ("[nsr:scaling-group-name-ref='{}']".format(group_name) if group_name is not None else "") +
152 ("/nsr:instance") +
153 ("[nsr:index='{}']".format(index) if index is not None else ""))
154
Philip Josephf4937572017-03-03 01:55:37 +0530155 @staticmethod
156 def cloud_account(k=None):
157 return ("C,/rw-cloud:cloud/rw-cloud:account" +
158 ("[rw-cloud:name='{}']".format(k) if k is not None else ""))
159
160 @staticmethod
161 def project(k=None):
162 return ("C,/rw-project:project" +
163 ("[rw-project:name='{}']".format(k) if k is not None else ""))
164
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400165
166class ManoQuerier(object):
Philip Josephf4937572017-03-03 01:55:37 +0530167 def __init__(self, log, dts, project):
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400168 self.log = log
169 self.dts = dts
Philip Josephf4937572017-03-03 01:55:37 +0530170 self.project = project
171
172 def add_project(self, xpath):
173 return self.project.add_project(xpath)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400174
175 @asyncio.coroutine
Philip Josephf4937572017-03-03 01:55:37 +0530176 def _read_query(self, xpath, do_trace=False, project=True):
177 if project:
178 xp = self.add_project(xpath)
179 else:
180 xp = xpath
181 self.log.debug("Running XPATH read query: %s (trace: %s)", xp, do_trace)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400182 flags = rwdts.XactFlag.MERGE
183 flags += rwdts.XactFlag.TRACE if do_trace else 0
184 res_iter = yield from self.dts.query_read(
Philip Josephf4937572017-03-03 01:55:37 +0530185 xp, flags=flags
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400186 )
187
188 results = []
189 for i in res_iter:
190 result = yield from i
191 if result is not None:
192 results.append(result.result)
193
194 return results
195
196 @asyncio.coroutine
Philip Josephf4937572017-03-03 01:55:37 +0530197 def _delete_query(self, xpath, flags=0):
198 xp = self.add_project(xpath)
199 self.log.debug("Running XPATH delete query: %s (flags: %d)", xp, flags)
200 with self.dts.transaction() as xact:
201 yield from self.dts.query_delete(
202 xp,
203 flags
204 )
205
206 @asyncio.coroutine
207 def _update_query(self, xpath, msg, flags=0):
208 xp = self.add_project(xpath)
209 self.log.debug("Running XPATH update query: %s (flags: %d)", xp, flags)
210 with self.dts.transaction() as xact:
211 yield from self.dts.query_update(
212 xp,
213 flags,
214 msg
215 )
216
217 @asyncio.coroutine
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400218 def get_cm_state(self, nsr_id=None):
219 return (yield from self._read_query(XPaths.cm_state(nsr_id), False))
220
221 @asyncio.coroutine
222 def get_nsr_opdatas(self, nsr_id=None):
223 return (yield from self._read_query(XPaths.nsr_opdata(nsr_id), False))
224
225 @asyncio.coroutine
226 def get_nsr_scale_group_instance_opdata(self, nsr_id=None, group_name=None, index=None):
227 return (yield from self._read_query(XPaths.nsr_scale_group_instance(nsr_id, group_name, index), False))
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400228
229 @asyncio.coroutine
230 def get_nsr_configs(self, nsr_id=None):
231 return (yield from self._read_query(XPaths.nsr_config(nsr_id)))
232
233 @asyncio.coroutine
234 def get_nsr_config_status(self, nsr_id=None):
235 return (yield from self._read_query(XPaths.nsr_config_status(nsr_id)))
236
237 @asyncio.coroutine
238 def get_vnfrs(self, vnfr_id=None):
239 return (yield from self._read_query(XPaths.vnfr(vnfr_id)))
240
241 @asyncio.coroutine
242 def get_vlrs(self, vlr_id=None):
243 return (yield from self._read_query(XPaths.vlr(vlr_id)))
244
245 @asyncio.coroutine
246 def get_nsd_ref_counts(self, nsd_id=None):
247 return (yield from self._read_query(XPaths.nsd_ref_count(nsd_id)))
248
249 @asyncio.coroutine
250 def get_vnfd_ref_counts(self, vnfd_id=None):
251 return (yield from self._read_query(XPaths.vnfd_ref_count(vnfd_id)))
252
253 @asyncio.coroutine
254 def delete_nsr(self, nsr_id):
Philip Josephf4937572017-03-03 01:55:37 +0530255 return (yield from self._delete_query(XPaths.nsr_config(nsr_id)))
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400256
257 @asyncio.coroutine
258 def delete_nsd(self, nsd_id):
Philip Josephf4937572017-03-03 01:55:37 +0530259 return (yield from self._delete_query(XPaths.nsd(nsd_id),
260 rwdts.XactFlag.ADVISE))
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400261
262 @asyncio.coroutine
263 def delete_vnfd(self, vnfd_id):
Philip Josephf4937572017-03-03 01:55:37 +0530264 return (yield from self._delete_query(XPaths.vnfd(vnfd_id),
265 rwdts.XactFlag.ADVISE))
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400266
267 @asyncio.coroutine
268 def update_nsd(self, nsd_id, nsd_msg):
Philip Josephf4937572017-03-03 01:55:37 +0530269 return (yield from self._update_query(XPaths.nsd(nsd_id), nsd_msg,
270 rwdts.XactFlag.ADVISE))
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400271
272 @asyncio.coroutine
273 def update_vnfd(self, vnfd_id, vnfd_msg):
Philip Josephf4937572017-03-03 01:55:37 +0530274 return (yield from self._update_query(XPaths.vnfd(vnfd_id), vnfd_msg,
275 rwdts.XactFlag.ADVISE))
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400276
277 @asyncio.coroutine
278 def update_nsr_config(self, nsr_id, nsr_msg):
Philip Josephf4937572017-03-03 01:55:37 +0530279 return (yield from self._update_query(
280 XPaths.nsr_config(nsr_id),
281 nsr_msg,
282 rwdts.XactFlag.ADVISE|rwdts.XactFlag.REPLACE))
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400283
284
285class ManoTestCase(rift.test.dts.AbstractDTSTest):
286 @asyncio.coroutine
287 def verify_nsr_state(self, nsr_id, state):
288 nsrs = yield from self.querier.get_nsr_opdatas(nsr_id)
289 self.assertEqual(1, len(nsrs))
290 nsr = nsrs[0]
291
292 self.log.debug("Got nsr = %s", nsr)
293 self.assertEqual(state, nsr.operational_status)
294
295 @asyncio.coroutine
296 def verify_vlr_state(self, vlr_id, state):
297 vlrs = yield from self.querier.get_vlrs(vlr_id)
298 self.assertEqual(1, len(vlrs))
299 vlr = vlrs[0]
300
301 self.assertEqual(state, vlr.operational_status)
302
303 def verify_vdu_state(self, vdu, state):
304 self.assertEqual(state, vdu.operational_status)
305
306 @asyncio.coroutine
307 def verify_vnf_state(self, vnfr_id, state):
308 vnfrs = yield from self.querier.get_vnfrs(vnfr_id)
309 self.assertEqual(1, len(vnfrs))
310 vnfr = vnfrs[0]
311
312 self.assertEqual(state, vnfr.operational_status)
313
314 @asyncio.coroutine
315 def terminate_nsr(self, nsr_id):
316 self.log.debug("Terminating nsr id: %s", nsr_id)
317 yield from self.querier.delete_nsr(nsr_id)
318
319 @asyncio.coroutine
320 def verify_nsr_deleted(self, nsr_id):
321 nsr_opdatas = yield from self.querier.get_nsr_opdatas(nsr_id)
322 self.assertEqual(0, len(nsr_opdatas))
323
324 nsr_configs = yield from self.querier.get_nsr_configs(nsr_id)
325 self.assertEqual(0, len(nsr_configs))
326
327 @asyncio.coroutine
328 def verify_num_vlrs(self, num_vlrs):
329 vlrs = yield from self.querier.get_vlrs()
330 self.assertEqual(num_vlrs, len(vlrs))
331
332 @asyncio.coroutine
333 def get_nsr_vlrs(self, nsr_id):
334 nsrs = yield from self.querier.get_nsr_opdatas(nsr_id)
335 return [v.vlr_ref for v in nsrs[0].vlr]
336
337 @asyncio.coroutine
338 def get_nsr_vnfs(self, nsr_id):
339 nsrs = yield from self.querier.get_nsr_opdatas(nsr_id)
340 return nsrs[0].constituent_vnfr_ref
341
342 @asyncio.coroutine
343 def get_vnf_vlrs(self, vnfr_id):
344 vnfrs = yield from self.querier.get_vnfrs(vnfr_id)
345 return [i.vlr_ref for i in vnfrs[0].internal_vlr]
346
347 @asyncio.coroutine
348 def verify_num_nsr_vlrs(self, nsr_id, num_vlrs):
349 vlrs = yield from self.get_nsr_vlrs(nsr_id)
350 self.assertEqual(num_vlrs, len(vlrs))
351
352 @asyncio.coroutine
353 def verify_num_nsr_vnfrs(self, nsr_id, num_vnfs):
354 vnfs = yield from self.get_nsr_vnfs(nsr_id)
355 self.assertEqual(num_vnfs, len(vnfs))
356
357 @asyncio.coroutine
358 def verify_num_vnfr_vlrs(self, vnfr_id, num_vlrs):
359 vlrs = yield from self.get_vnf_vlrs(vnfr_id)
360 self.assertEqual(num_vlrs, len(vlrs))
361
362 @asyncio.coroutine
363 def get_vnf_vdus(self, vnfr_id):
364 vnfrs = yield from self.querier.get_vnfrs(vnfr_id)
365 return [i for i in vnfrs[0].vdur]
366
367 @asyncio.coroutine
368 def verify_num_vnfr_vdus(self, vnfr_id, num_vdus):
369 vdus = yield from self.get_vnf_vdus(vnfr_id)
370 self.assertEqual(num_vdus, len(vdus))
371
372 @asyncio.coroutine
373 def verify_num_vnfrs(self, num_vnfrs):
374 vnfrs = yield from self.querier.get_vnfrs()
375 self.assertEqual(num_vnfrs, len(vnfrs))
376
377 @asyncio.coroutine
378 def verify_nsd_ref_count(self, nsd_id, num_ref):
379 nsd_ref_counts = yield from self.querier.get_nsd_ref_counts(nsd_id)
380 self.assertEqual(num_ref, nsd_ref_counts[0].instance_ref_count)
381
Philip Josephf4937572017-03-03 01:55:37 +0530382
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400383class DescriptorPublisher(object):
Philip Josephf4937572017-03-03 01:55:37 +0530384 def __init__(self, log, loop, dts, project):
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400385 self.log = log
386 self.loop = loop
387 self.dts = dts
Philip Josephf4937572017-03-03 01:55:37 +0530388 self.project = project
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400389
390 self._registrations = []
391
392 @asyncio.coroutine
393 def publish(self, w_path, path, desc):
394 ready_event = asyncio.Event(loop=self.loop)
Philip Josephf4937572017-03-03 01:55:37 +0530395 if 'rw-project' in path:
396 w_xp = w_path
397 xp = path
398 else:
399 w_xp = self.project.add_project(w_path)
400 xp = self.project.add_project(path)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400401
402 @asyncio.coroutine
403 def on_ready(regh, status):
404 self.log.debug("Create element: %s, obj-type:%s obj:%s",
Philip Josephf4937572017-03-03 01:55:37 +0530405 xp, type(desc), desc)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400406 with self.dts.transaction() as xact:
Philip Josephf4937572017-03-03 01:55:37 +0530407 regh.create_element(xp, desc, xact.xact)
408 self.log.debug("Created element: %s, obj:%s", xp, desc)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400409 ready_event.set()
410
411 handler = rift.tasklets.DTS.RegistrationHandler(
412 on_ready=on_ready
413 )
414
Philip Josephf4937572017-03-03 01:55:37 +0530415 self.log.debug("Registering path: %s, obj:%s", w_xp, desc)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400416 reg = yield from self.dts.register(
Philip Josephf4937572017-03-03 01:55:37 +0530417 w_xp,
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400418 handler,
419 flags=rwdts.Flag.PUBLISHER | rwdts.Flag.NO_PREP_READ
420 )
421 self._registrations.append(reg)
Philip Josephf4937572017-03-03 01:55:37 +0530422 self.log.debug("Registered path : %s", w_xp)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400423 yield from ready_event.wait()
424
425 return reg
426
427 def unpublish_all(self):
428 self.log.debug("Deregistering all published descriptors")
429 for reg in self._registrations:
430 reg.deregister()
431
432
Philip Josephf4937572017-03-03 01:55:37 +0530433class ProjectPublisher(object):
434 XPATH = "C,/rw-project:project"
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400435
Philip Josephf4937572017-03-03 01:55:37 +0530436 def __init__(self, log, loop, dts, project):
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400437 self.dts = dts
438 self.log = log
439 self.loop = loop
Philip Josephf4937572017-03-03 01:55:37 +0530440 self.project = project
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400441 self.ref = None
442
Philip Josephf4937572017-03-03 01:55:37 +0530443 self.querier = ManoQuerier(log, dts, project)
444 self.publisher = DescriptorPublisher(log, loop,
445 dts, project)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400446
Philip Josephf4937572017-03-03 01:55:37 +0530447 self._ready_event = asyncio.Event(loop=self.loop)
448 asyncio.ensure_future(self.register(), loop=loop)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400449
Philip Josephf4937572017-03-03 01:55:37 +0530450 @asyncio.coroutine
451 def register(self):
452 @asyncio.coroutine
453 def on_ready(regh, status):
454 self._ready_event.set()
455
456 self.log.debug("Registering path: %s", ProjectPublisher.XPATH)
457 self.reg = yield from self.dts.register(
458 ProjectPublisher.XPATH,
459 flags=rwdts.Flag.PUBLISHER,
460 handler=rift.tasklets.DTS.RegistrationHandler(
461 on_ready=on_ready,
462 ),
463 )
464
465 def deregister(self):
466 if self.reg is not None:
467 self.reg.deregister()
468
469 @asyncio.coroutine
470 def publish_project(self, config, xpath, xpath_wild):
471 # Publish project
472 self.log.debug("Publishing cloud_account path: %s - %s, type:%s, obj:%s",
473 xpath, xpath_wild, type(config), config)
474 yield from self.publisher.publish(xpath_wild, xpath, config)
475
476
477class CloudAccountPublisher(object):
478 XPATH = "C,/rw-cloud:cloud"
479
480 def __init__(self, log, loop, dts, project):
481 self.dts = dts
482 self.log = log
483 self.loop = loop
484 self.project = project
485 self.ref = None
486
487 self.querier = ManoQuerier(log, dts, project)
488 self.publisher = DescriptorPublisher(log, loop,
489 dts, project)
490
491 self.xpath = self.project.add_project(CloudAccountPublisher.XPATH)
492
493 self._ready_event = asyncio.Event(loop=self.loop)
494 asyncio.ensure_future(self.register(), loop=loop)
495
496 @asyncio.coroutine
497 def register(self):
498 @asyncio.coroutine
499 def on_ready(regh, status):
500 self._ready_event.set()
501
502 self.log.debug("Registering path: %s", self.xpath)
503 self.reg = yield from self.dts.register(
504 self.xpath,
505 flags=rwdts.Flag.PUBLISHER,
506 handler=rift.tasklets.DTS.RegistrationHandler(
507 on_ready=on_ready,
508 ),
509 )
510
511 def deregister(self):
512 if self.reg is not None:
513 self.reg.deregister()
514
515 @asyncio.coroutine
516 def publish_account(self, account, xpath, xpath_wild):
517 # Publish cloud account
518 self.log.debug("Publishing cloud_account path: %s - %s, type:%s, obj:%s",
519 xpath, xpath_wild, type(account), account)
520 yield from self.publisher.publish(xpath_wild, xpath, account)
521
522
523class PingPongNsrConfigPublisher(object):
524 XPATH = "C,/nsr:ns-instance-config"
525
526 def __init__(self, log, loop, dts, ping_pong, cloud_account_name, project):
527 self.dts = dts
528 self.log = log
529 self.loop = loop
530 self.project = project
531 self.ref = None
532
533 self.querier = ManoQuerier(log, dts, project)
534 self.xpath = self.project.add_project(PingPongNsrConfigPublisher.XPATH)
535 self.nsr_config = rwnsryang.YangData_RwProject_Project_NsInstanceConfig()
536
537 nsr = rwnsryang.YangData_RwProject_Project_NsInstanceConfig_Nsr()
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400538 nsr.id = str(uuid.uuid4())
539 nsr.name = "ns1.{}".format(nsr.id)
Philip Josephf4937572017-03-03 01:55:37 +0530540 nsr.nsd = nsryang.YangData_RwProject_Project_NsInstanceConfig_Nsr_Nsd()
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400541 nsr.nsd.from_dict(ping_pong.ping_pong_nsd.nsd.as_dict())
542 nsr.cloud_account = cloud_account_name
543
544 nsr.vnf_cloud_account_map.add().from_dict({
545 'member_vnf_index_ref': nsr.nsd.constituent_vnfd[0].member_vnf_index,
546 'config_agent_account': 'RiftCA',
547 #'cloud_account':'mock_account1'
548 })
549
Philip Josephf4937572017-03-03 01:55:37 +0530550 inputs = nsryang.YangData_RwProject_Project_NsInstanceConfig_Nsr_InputParameter()
551 inputs.xpath = self.project.add_project(
Philip Joseph4f810f22017-03-07 23:09:10 +0530552 "/project-nsd:nsd-catalog/project-nsd:nsd[project-nsd:id={}]/project-nsd:name".format(ping_pong.nsd_id))
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400553 inputs.value = "inigo montoya"
554
555 fast_cpu = {'metadata_key': 'FASTCPU', 'metadata_value': 'True'}
556 self.create_nsd_placement_group_map(nsr,
557 group_name = 'Orcus',
558 cloud_type = 'openstack',
559 construct_type = 'host_aggregate',
560 construct_value = [fast_cpu])
561
562 fast_storage = {'metadata_key': 'FASTSSD', 'metadata_value': 'True'}
563 self.create_nsd_placement_group_map(nsr,
564 group_name = 'Quaoar',
565 cloud_type = 'openstack',
566 construct_type = 'host_aggregate',
567 construct_value = [fast_storage])
568
569 fast_cpu = {'metadata_key': 'BLUE_HW', 'metadata_value': 'True'}
570 self.create_vnfd_placement_group_map(nsr,
571 group_name = 'Eris',
572 vnfd_id = ping_pong.ping_vnfd_id,
573 cloud_type = 'openstack',
574 construct_type = 'host_aggregate',
575 construct_value = [fast_cpu])
576
577 fast_storage = {'metadata_key': 'YELLOW_HW', 'metadata_value': 'True'}
578 self.create_vnfd_placement_group_map(nsr,
579 group_name = 'Weywot',
580 vnfd_id = ping_pong.pong_vnfd_id,
581 cloud_type = 'openstack',
582 construct_type = 'host_aggregate',
583 construct_value = [fast_storage])
584
585
586 nsr.input_parameter.append(inputs)
587
588 self._nsr = nsr
589 self.nsr_config.nsr.append(nsr)
590
591 self._ready_event = asyncio.Event(loop=self.loop)
592 asyncio.ensure_future(self.register(), loop=loop)
593
594 @asyncio.coroutine
595 def register(self):
596 @asyncio.coroutine
597 def on_ready(regh, status):
598 self._ready_event.set()
599
Philip Josephf4937572017-03-03 01:55:37 +0530600 self.log.debug("Registering path: %s", self.xpath)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400601 self.reg = yield from self.dts.register(
Philip Josephf4937572017-03-03 01:55:37 +0530602 self.xpath,
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400603 flags=rwdts.Flag.PUBLISHER,
604 handler=rift.tasklets.DTS.RegistrationHandler(
605 on_ready=on_ready,
606 ),
607 )
608
609 @asyncio.coroutine
610 def publish(self):
611 self.log.debug("Publishing NSR: {}".format(self.nsr_config))
612 yield from self._ready_event.wait()
613 with self.dts.transaction() as xact:
614 self.reg.create_element(
Philip Josephf4937572017-03-03 01:55:37 +0530615 self.xpath,
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400616 self.nsr_config,
617 xact=xact.xact,
618 )
619
620 return self._nsr.id
621
622 @asyncio.coroutine
623 def create_scale_group_instance(self, group_name, index):
624 index = 1
625 scaling_group = self.nsr_config.nsr[0].scaling_group.add()
626 scaling_group.from_dict({
627 "scaling_group_name_ref": group_name,
628 "instance": [{"index": index}],
629 })
630 with self.dts.transaction() as xact:
631 self.reg.update_element(
Philip Josephf4937572017-03-03 01:55:37 +0530632 self.xpath,
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400633 self.nsr_config,
634 xact=xact.xact,
635 )
636
637 return index
638
639 def create_nsd_placement_group_map(self,
640 nsr,
641 group_name,
642 cloud_type,
643 construct_type,
644 construct_value):
645 placement_group = nsr.nsd_placement_group_maps.add()
646 placement_group.from_dict({
647 "placement_group_ref" : group_name,
648 "cloud_type" : cloud_type,
649 construct_type : construct_value,
650 })
Philip Josephf4937572017-03-03 01:55:37 +0530651
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400652
653 def create_vnfd_placement_group_map(self,
654 nsr,
655 group_name,
656 vnfd_id,
657 cloud_type,
658 construct_type,
659 construct_value):
660 placement_group = nsr.vnfd_placement_group_maps.add()
661 placement_group.from_dict({
662 "placement_group_ref" : group_name,
663 "vnfd_id_ref" : vnfd_id,
664 "cloud_type" : cloud_type,
665 construct_type : construct_value,
666 })
Philip Josephf4937572017-03-03 01:55:37 +0530667
668
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400669 @asyncio.coroutine
670 def delete_scale_group_instance(self, group_name, index):
671 self.log.debug("Deleting scale group %s instance %s", group_name, index)
672 #del self.nsr_config.nsr[0].scaling_group[0].instance[0]
Philip Josephf4937572017-03-03 01:55:37 +0530673 xpath = self.project.add_project(
674 XPaths.nsr_scale_group_instance_config(self.nsr_config.nsr[0].id,
675 group_name, index))
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400676 yield from self.dts.query_delete(xpath, flags=rwdts.XactFlag.ADVISE)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400677
678 def deregister(self):
679 if self.reg is not None:
680 self.reg.deregister()
681
682 def create_nsr_vl(self):
683 vld = self.nsr_config.nsr[0].nsd.vld.add()
684 vld.id = 'ping_pong_vld_2'
685 vld.name = 'ping_pong_vld_2' # hard coded
686 vld.short_name = vld.name
687 vld.vendor = 'RIFT.io'
688 vld.description = 'Toy VL'
689 vld.version = '1.0'
690 vld.type_yang = 'ELAN'
691
692 # cpref = vld.vnfd_connection_point_ref.add()
693 # cpref.member_vnf_index_ref = cp[0]
694 # cpref.vnfd_id_ref = cp[1]
695 # cpref.vnfd_connection_point_ref = cp[2]
696
697 vld = self.nsr_config.nsr[0].vl_cloud_account_map.add()
698 vld.vld_id_ref = 'ping_pong_vld_2'
699 vld.cloud_accounts = ["mock_account"]
700
701 @asyncio.coroutine
702 def add_nsr_vl(self):
703 self.create_nsr_vl()
704 yield from self.querier.update_nsr_config(
705 self.nsr_config.nsr[0].id,
706 self.nsr_config.nsr[0],
707 )
708
709 @asyncio.coroutine
710 def del_nsr_vl(self):
711 for vld in self.nsr_config.nsr[0].nsd.vld:
712 if vld.id == 'ping_pong_vld_2':
713 self.nsr_config.nsr[0].nsd.vld.remove(vld)
714 break
715
716 yield from self.querier.update_nsr_config(
717 self.nsr_config.nsr[0].id,
718 self.nsr_config.nsr[0],
719 )
720
721 def update_vnf_cloud_map(self,vnf_cloud_map):
722 self.log.debug("Modifying NSR to add VNF cloud account map: {}".format(vnf_cloud_map))
723 for vnf_index,cloud_acct in vnf_cloud_map.items():
Philip Josephf4937572017-03-03 01:55:37 +0530724 vnf_maps = [vnf_map for vnf_map in \
725 self.nsr_config.nsr[0].vnf_cloud_account_map \
726 if vnf_index == vnf_map.member_vnf_index_ref]
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400727 if vnf_maps:
728 vnf_maps[0].cloud_account = cloud_acct
Philip Josephf4937572017-03-03 01:55:37 +0530729 else:
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400730 self.nsr_config.nsr[0].vnf_cloud_account_map.add().from_dict({
731 'member_vnf_index_ref':vnf_index,
732 'cloud_account':cloud_acct
733 })
734
735
736class PingPongDescriptorPublisher(object):
Philip Josephf4937572017-03-03 01:55:37 +0530737 def __init__(self, log, loop, dts, project,
738 num_external_vlrs=1, num_internal_vlrs=1, num_ping_vms=1):
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400739 self.log = log
740 self.loop = loop
741 self.dts = dts
Philip Josephf4937572017-03-03 01:55:37 +0530742 self.project = project
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400743
Philip Josephf4937572017-03-03 01:55:37 +0530744 self.querier = ManoQuerier(self.log, self.dts, self.project)
745 self.publisher = DescriptorPublisher(self.log, self.loop,
746 self.dts, self.project)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400747 self.ping_vnfd, self.pong_vnfd, self.ping_pong_nsd = \
748 ping_pong_nsd.generate_ping_pong_descriptors(
749 pingcount=1,
750 external_vlr_count=num_external_vlrs,
751 internal_vlr_count=num_internal_vlrs,
752 num_vnf_vms=2,
753 mano_ut=True,
754 use_scale_group=True,
755 use_mon_params=False,
756 )
757
758 self.config_dir = os.path.join(os.getenv('RIFT_ARTIFACTS'),
759 "launchpad/libs",
760 self.ping_pong_nsd.id,
761 "config")
762
763 @property
764 def nsd_id(self):
765 return self.ping_pong_nsd.id
766
767 @property
768 def ping_vnfd_id(self):
769 return self.ping_vnfd.id
770
771 @property
772 def pong_vnfd_id(self):
773 return self.pong_vnfd.id
774
775 @asyncio.coroutine
776 def publish_desciptors(self):
777 # Publish ping_vnfd
778 xpath = XPaths.vnfd(self.ping_vnfd_id)
779 xpath_wild = XPaths.vnfd()
780 for obj in self.ping_vnfd.descriptor.vnfd:
781 self.log.debug("Publishing ping_vnfd path: %s - %s, type:%s, obj:%s",
782 xpath, xpath_wild, type(obj), obj)
783 yield from self.publisher.publish(xpath_wild, xpath, obj)
784
785 # Publish pong_vnfd
786 xpath = XPaths.vnfd(self.pong_vnfd_id)
787 xpath_wild = XPaths.vnfd()
788 for obj in self.pong_vnfd.descriptor.vnfd:
789 self.log.debug("Publishing pong_vnfd path: %s, wild_path: %s, obj:%s",
790 xpath, xpath_wild, obj)
791 yield from self.publisher.publish(xpath_wild, xpath, obj)
792
793 # Publish ping_pong_nsd
794 xpath = XPaths.nsd(self.nsd_id)
795 xpath_wild = XPaths.nsd()
796 for obj in self.ping_pong_nsd.descriptor.nsd:
797 self.log.debug("Publishing ping_pong nsd path: %s, wild_path: %s, obj:%s",
798 xpath, xpath_wild, obj)
799 yield from self.publisher.publish(xpath_wild, xpath, obj)
800
801 self.log.debug("DONE - publish_desciptors")
802
803 def unpublish_descriptors(self):
804 self.publisher.unpublish_all()
805
806 @asyncio.coroutine
807 def delete_nsd(self):
808 yield from self.querier.delete_nsd(self.ping_pong_nsd.id)
809
810 @asyncio.coroutine
811 def delete_ping_vnfd(self):
812 yield from self.querier.delete_vnfd(self.ping_vnfd.id)
813
814 @asyncio.coroutine
815 def update_nsd(self):
816 yield from self.querier.update_nsd(
817 self.ping_pong_nsd.id,
818 self.ping_pong_nsd.descriptor.nsd[0]
819 )
820
821 @asyncio.coroutine
822 def update_ping_vnfd(self):
823 yield from self.querier.update_vnfd(
824 self.ping_vnfd.id,
825 self.ping_vnfd.descriptor.vnfd[0]
826 )
827
828
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400829class ManoTestCase(rift.test.dts.AbstractDTSTest):
830 """
831 DTS GI interface unittests
832
833 Note: Each tests uses a list of asyncio.Events for staging through the
834 test. These are required here because we are bring up each coroutine
835 ("tasklet") at the same time and are not implementing any re-try
836 mechanisms. For instance, this is used in numerous tests to make sure that
837 a publisher is up and ready before the subscriber sends queries. Such
838 event lists should not be used in production software.
839 """
840
841 @classmethod
842 def configure_suite(cls, rwmain):
843 vns_dir = os.environ.get('VNS_DIR')
844 vnfm_dir = os.environ.get('VNFM_DIR')
845 nsm_dir = os.environ.get('NSM_DIR')
846 rm_dir = os.environ.get('RM_DIR')
847
848 rwmain.add_tasklet(vns_dir, 'rwvnstasklet')
849 rwmain.add_tasklet(vnfm_dir, 'rwvnfmtasklet')
850 rwmain.add_tasklet(nsm_dir, 'rwnsmtasklet')
851 rwmain.add_tasklet(rm_dir, 'rwresmgrtasklet')
852 rwmain.add_tasklet(rm_dir, 'rwconmantasklet')
853
854 @classmethod
855 def configure_schema(cls):
856 return rwnsmyang.get_schema()
857
858 @classmethod
859 def configure_timeout(cls):
860 return 240
861
862 @staticmethod
863 def get_cal_account(account_type, account_name):
864 """
Philip Josephf4937572017-03-03 01:55:37 +0530865 Creates an object for class RwcalYang.Cloud
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400866 """
Philip Josephf4937572017-03-03 01:55:37 +0530867 account = rwcloudyang.CloudAcc()
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400868 if account_type == 'mock':
869 account.name = account_name
870 account.account_type = "mock"
871 account.mock.username = "mock_user"
872 elif ((account_type == 'openstack_static') or (account_type == 'openstack_dynamic')):
873 account.name = account_name
874 account.account_type = 'openstack'
875 account.openstack.key = openstack_info['username']
876 account.openstack.secret = openstack_info['password']
877 account.openstack.auth_url = openstack_info['auth_url']
878 account.openstack.tenant = openstack_info['project_name']
879 account.openstack.mgmt_network = openstack_info['mgmt_network']
880 return account
881
882 @asyncio.coroutine
Philip Josephf4937572017-03-03 01:55:37 +0530883 def configure_project(self, project=None):
884 if project is None:
885 project = self.project
886
887 proj_xpath = "C,{}/project-config".format(project.prefix)
888 self.log.info("Creating project: {} with {}".
889 format(proj_xpath, project.config.as_dict()))
890 xpath_wild = "C,/rw-project:project/project-config"
891 yield from self.project_publisher.publish_project(project.config,
892 proj_xpath,
893 xpath_wild)
894
895 @asyncio.coroutine
896 def configure_cloud_account(self, dts, cloud_type, cloud_name="cloud1", project=None):
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400897 account = self.get_cal_account(cloud_type, cloud_name)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400898 self.log.info("Configuring cloud-account: %s", account)
Philip Josephf4937572017-03-03 01:55:37 +0530899 if project is None:
900 project = self.project
901 xpath = project.add_project(XPaths.cloud_account(account.name))
902 xpath_wild = project.add_project(XPaths.cloud_account())
903
904 # account_xpath = project.add_project(
905 # "C,/rw-cloud:cloud/rw-cloud:account[rw-cloud:name='{}']".format(cloud_name))
906 # yield from dts.query_create(account_xpath,
907 # rwdts.XactFlag.ADVISE,
908 # account)
909 yield from self.cloud_publisher.publish_account(account, xpath, xpath_wild)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400910
911 @asyncio.coroutine
912 def wait_tasklets(self):
913 yield from asyncio.sleep(5, loop=self.loop)
914
915 def configure_test(self, loop, test_id):
916 self.log.debug("STARTING - %s", self.id())
917 self.tinfo = self.new_tinfo(self.id())
918 self.dts = rift.tasklets.DTS(self.tinfo, self.schema, self.loop)
Philip Josephf4937572017-03-03 01:55:37 +0530919 self.project = ManoProject(self.log,
920 name=DEFAULT_PROJECT)
921 self.project1 = ManoProject(self.log,
922 name='test-1')
923 self.ping_pong = PingPongDescriptorPublisher(self.log, self.loop,
924 self.dts, self.project)
925 self.querier = ManoQuerier(self.log, self.dts, self.project)
926 self.project_publisher = ProjectPublisher(
927 self.log,
928 loop,
929 self.dts,
930 self.project
931 )
932 self.cloud_publisher = CloudAccountPublisher(
933 self.log,
934 loop,
935 self.dts,
936 self.project
937 )
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400938 self.nsr_publisher = PingPongNsrConfigPublisher(
939 self.log,
940 loop,
941 self.dts,
942 self.ping_pong,
943 "mock_account",
Philip Josephf4937572017-03-03 01:55:37 +0530944 self.project,
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400945 )
946
947 def test_create_nsr_record(self):
948
949 @asyncio.coroutine
Philip Josephf4937572017-03-03 01:55:37 +0530950 def verify_projects(termination=False):
951 self.log.debug("Verifying projects = %s", XPaths.project())
952
953 accts = yield from self.querier._read_query(XPaths.project(),
954 project=False)
955 projs = []
956 for acc in accts:
957 self.log.debug("Project: {}".format(acc.as_dict()))
958 if acc.name not in projs:
959 projs.append(acc.name)
960 self.log.debug("Merged: {}".format(projs))
961 self.assertEqual(2, len(projs))
962
963 @asyncio.coroutine
964 def verify_cloud_accounts(termination=False):
965 self.log.debug("Verifying cloud accounts = %s", XPaths.cloud_account())
966
967 accts = yield from self.querier._read_query(XPaths.cloud_account())
968 self.assertEqual(2, len(accts))
969
970 accts = yield from self.querier._read_query(
971 self.project1.add_project(XPaths.cloud_account()), project=False)
972 self.assertEqual(1, len(accts))
973
974 accts = yield from self.querier._read_query(
975 "C,/rw-project:project/rw-cloud:cloud/rw-cloud:account",
976 project=False)
977 self.assertEqual(3, len(accts))
978
979 accts = yield from self.querier._read_query(
980 "C,/rw-project:project/rw-cloud:cloud/rw-cloud:account[rw-cloud:name='mock_account']",
981 project=False)
982 self.assertEqual(2, len(accts))
983
984 @asyncio.coroutine
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400985 def verify_cm_state(termination=False, nsrid=None):
986 self.log.debug("Verifying cm_state path = %s", XPaths.cm_state(nsrid))
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400987
988 loop_count = 10
989 loop_sleep = 10
990 while loop_count:
991 yield from asyncio.sleep(loop_sleep, loop=self.loop)
992 loop_count -= 1
993 cm_nsr = None
994 cm_nsr_i = yield from self.querier.get_cm_state(nsr_id=nsrid)
995 if (cm_nsr_i is not None and len(cm_nsr_i) != 0):
996 self.assertEqual(1, len(cm_nsr_i))
997 cm_nsr = cm_nsr_i[0].as_dict()
998 #print("###>>> cm_nsr=", cm_nsr)
999 if termination:
1000 if len(cm_nsr_i) == 0:
1001 print("\n###>>> cm-state NSR deleted OK <<<###\n")
1002 return
1003 elif (cm_nsr is not None and
1004 'state' in cm_nsr and
1005 (cm_nsr['state'] == 'ready')):
1006 self.log.debug("Got cm_nsr record %s", cm_nsr)
1007 print("\n###>>> cm-state NSR 'ready' OK <<<###\n")
1008 return
1009
1010 # if (len(cm_nsr_i) == 1 and cm_nsr_i[0].state == 'ready'):
1011 # self.log.debug("Got cm_nsr record %s", cm_nsr)
1012 # else:
1013 # yield from asyncio.sleep(10, loop=self.loop)
1014
1015 print("###>>> Failed cm-state, termination:", termination)
1016 self.assertEqual(1, loop_count)
1017
1018 @asyncio.coroutine
1019 def verify_nsr_opdata(termination=False):
1020 self.log.debug("Verifying nsr opdata path = %s", XPaths.nsr_opdata())
1021
1022 while True:
1023 nsrs = yield from self.querier.get_nsr_opdatas()
1024 if termination:
1025 if len(nsrs) != 0:
1026 for i in range(10):
1027 nsrs = yield from self.querier.get_nsr_opdatas()
1028 if len(nsrs) == 0:
1029 self.log.debug("No active NSR records found. NSR termination successful")
1030 return
1031 else:
1032 self.assertEqual(0, len(nsrs))
1033 self.log.error("Active NSR records found. NSR termination failed")
1034
1035 else:
1036 self.log.debug("No active NSR records found. NSR termination successful")
1037 self.assertEqual(0, len(nsrs))
1038 return
1039
1040 nsr = nsrs[0]
1041 self.log.debug("Got nsr record %s", nsr)
1042 if nsr.operational_status == 'running':
1043 self.log.debug("!!! Rcvd NSR with running status !!!")
1044 self.assertEqual("configuring", nsr.config_status)
1045 break
1046
1047 self.log.debug("Rcvd NSR with %s status", nsr.operational_status)
1048 self.log.debug("Sleeping for 10 seconds")
1049 yield from asyncio.sleep(10, loop=self.loop)
1050
1051 @asyncio.coroutine
1052 def verify_nsr_config(termination=False):
1053 self.log.debug("Verifying nsr config path = %s", XPaths.nsr_config())
1054
1055 nsr_configs = yield from self.querier.get_nsr_configs()
1056 self.assertEqual(1, len(nsr_configs))
1057
1058 nsr_config = nsr_configs[0]
1059 self.assertEqual(
Philip Joseph4f810f22017-03-07 23:09:10 +05301060 "/rw-project:project/project-nsd:nsd-catalog/project-nsd:nsd[project-nsd:id={}]/project-nsd:name".format(self.ping_pong.nsd_id),
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -04001061 nsr_config.input_parameter[0].xpath,
1062 )
1063
1064 @asyncio.coroutine
1065 def verify_nsr_config_status(termination=False, nsrid=None):
1066 if termination is False and nsrid is not None:
1067 self.log.debug("Verifying nsr config status path = %s", XPaths.nsr_opdata(nsrid))
1068
1069 loop_count = 6
1070 loop_sleep = 10
1071 while loop_count:
1072 loop_count -= 1
1073 yield from asyncio.sleep(loop_sleep, loop=self.loop)
1074 nsr_opdata_l = yield from self.querier.get_nsr_opdatas(nsrid)
1075 self.assertEqual(1, len(nsr_opdata_l))
1076 nsr_opdata = nsr_opdata_l[0].as_dict()
1077 if ("configured" == nsr_opdata['config_status']):
1078 print("\n###>>> NSR Config Status 'configured' OK <<<###\n")
1079 return
1080 self.assertEqual("configured", nsr_opdata['config_status'])
1081
1082 @asyncio.coroutine
1083 def verify_vnfr_record(termination=False):
1084 self.log.debug("Verifying vnfr record path = %s, Termination=%d",
1085 XPaths.vnfr(), termination)
1086 if termination:
1087 for i in range(10):
1088 vnfrs = yield from self.querier.get_vnfrs()
1089 if len(vnfrs) == 0:
1090 return True
1091
1092 for vnfr in vnfrs:
1093 self.log.debug("VNFR still exists = %s", vnfr)
1094
1095 yield from asyncio.sleep(.5, loop=self.loop)
1096
1097
1098 assert len(vnfrs) == 0
1099
1100 while True:
1101 vnfrs = yield from self.querier.get_vnfrs()
1102 if len(vnfrs) != 0 and termination is False:
1103 vnfr = vnfrs[0]
1104 self.log.debug("Rcvd VNFR with %s status", vnfr.operational_status)
1105 if vnfr.operational_status == 'running':
1106 self.log.debug("!!! Rcvd VNFR with running status !!!")
1107 return True
1108
1109 elif vnfr.operational_status == "failed":
1110 self.log.debug("!!! Rcvd VNFR with failed status !!!")
1111 return False
1112
1113 self.log.debug("Sleeping for 10 seconds")
1114 yield from asyncio.sleep(10, loop=self.loop)
1115
1116
1117 @asyncio.coroutine
1118 def verify_vnfr_cloud_account(vnf_index, cloud_account):
1119 self.log.debug("Verifying vnfr record Cloud account for vnf index = %d is %s", vnf_index,cloud_account)
1120 vnfrs = yield from self.querier.get_vnfrs()
1121 cloud_accounts = [vnfr.cloud_account for vnfr in vnfrs if vnfr.member_vnf_index_ref == vnf_index]
1122 self.log.debug("VNFR cloud account for index %d is %s", vnf_index,cloud_accounts[0])
1123 assert cloud_accounts[0] == cloud_account
1124
1125 @asyncio.coroutine
1126 def verify_vlr_record(termination=False):
1127 vlr_xpath = XPaths.vlr()
1128 self.log.debug("Verifying vlr record path = %s, termination: %s",
1129 vlr_xpath, termination)
1130 res_iter = yield from self.dts.query_read(vlr_xpath)
1131
1132 for i in res_iter:
1133 result = yield from i
1134 if termination:
1135 self.assertIsNone(result)
1136
1137 self.log.debug("Got vlr record %s", result)
1138
1139 @asyncio.coroutine
1140 def verify_vlrs(nsr_id, count=0):
1141 while True:
1142 nsrs = yield from self.querier.get_nsr_opdatas()
1143 nsr = nsrs[0]
1144 self.log.debug("Got nsr record %s", nsr)
1145 if nsr.operational_status == 'running':
1146 self.log.debug("!!! Rcvd NSR with running status !!!")
1147 # Check the VLR count
1148 if (len(nsr.vlr)) == count:
1149 self.log.debug("NSR %s has %d VLRs", nsr_id, count)
1150 break
1151
1152 self.log.debug("Rcvd NSR %s with %s status", nsr_id, nsr.operational_status)
1153 self.log.debug("Sleeping for 10 seconds")
1154 yield from asyncio.sleep(10, loop=self.loop)
1155
1156 @asyncio.coroutine
1157 def verify_nsd_ref_count(termination):
1158 self.log.debug("Verifying nsd ref count= %s", XPaths.nsd_ref_count())
1159 res_iter = yield from self.dts.query_read(XPaths.nsd_ref_count())
1160
1161 for i in res_iter:
1162 result = yield from i
1163 self.log.debug("Got nsd ref count record %s", result)
1164
1165 @asyncio.coroutine
1166 def verify_vnfd_ref_count(termination):
1167 self.log.debug("Verifying vnfd ref count= %s", XPaths.vnfd_ref_count())
1168 res_iter = yield from self.dts.query_read(XPaths.vnfd_ref_count())
1169
1170 for i in res_iter:
1171 result = yield from i
1172 self.log.debug("Got vnfd ref count record %s", result)
1173
1174 @asyncio.coroutine
1175 def verify_scale_group_reaches_state(nsr_id, scale_group, index, state, timeout=1000):
1176 start_time = time.time()
1177 instance_state = None
1178 while (time.time() - start_time) < timeout:
1179 results = yield from self.querier.get_nsr_opdatas(nsr_id=nsr_id)
1180 if len(results) == 1:
1181 result = results[0]
1182 if len(result.scaling_group_record) == 0:
1183 continue
1184
1185 if len(result.scaling_group_record[0].instance) == 0:
1186 continue
1187
1188 instance = result.scaling_group_record[0].instance[0]
1189 self.assertEqual(instance.scaling_group_index_ref, index)
1190
1191 instance_state = instance.op_status
1192 if instance_state == state:
1193 self.log.debug("Scale group instance reached %s state", state)
1194 return
1195
1196 yield from asyncio.sleep(1, loop=self.loop)
1197
1198 self.assertEqual(state, instance_state)
1199
1200 @asyncio.coroutine
1201 def verify_results(termination=False, nsrid=None):
1202 yield from verify_vnfr_record(termination)
1203 #yield from verify_vlr_record(termination)
1204 yield from verify_nsr_opdata(termination)
1205 yield from verify_nsr_config(termination)
1206 yield from verify_nsd_ref_count(termination)
1207 yield from verify_vnfd_ref_count(termination)
1208
1209 # Config Manager
1210 yield from verify_cm_state(termination, nsrid)
1211 yield from verify_nsr_config_status(termination, nsrid)
1212
Philip Josephf4937572017-03-03 01:55:37 +05301213 yield from verify_cloud_account(termination)
1214 yield from verify_project_record(termination)
1215
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -04001216 @asyncio.coroutine
1217 def verify_scale_instance(index):
1218 self.log.debug("Verifying scale record path = %s, Termination=%d",
1219 XPaths.vnfr(), termination)
1220 if termination:
1221 for i in range(5):
1222 vnfrs = yield from self.querier.get_vnfrs()
1223 if len(vnfrs) == 0:
1224 return True
1225
1226 for vnfr in vnfrs:
1227 self.log.debug("VNFR still exists = %s", vnfr)
1228
1229
1230 assert len(vnfrs) == 0
1231
1232 while True:
1233 vnfrs = yield from self.querier.get_vnfrs()
1234 if len(vnfrs) != 0 and termination is False:
1235 vnfr = vnfrs[0]
1236 self.log.debug("Rcvd VNFR with %s status", vnfr.operational_status)
1237 if vnfr.operational_status == 'running':
1238 self.log.debug("!!! Rcvd VNFR with running status !!!")
1239 return True
1240
1241 elif vnfr.operational_status == "failed":
1242 self.log.debug("!!! Rcvd VNFR with failed status !!!")
1243 return False
1244
1245 self.log.debug("Sleeping for 10 seconds")
1246 yield from asyncio.sleep(10, loop=self.loop)
1247
1248 @asyncio.coroutine
1249 def terminate_ns(nsr_id):
1250 xpath = XPaths.nsr_config(nsr_id)
1251 self.log.debug("Terminating network service with path %s", xpath)
1252 yield from self.dts.query_delete(xpath, flags=rwdts.XactFlag.ADVISE)
1253 self.log.debug("Terminated network service with path %s", xpath)
1254
1255 @asyncio.coroutine
1256 def run_test():
1257 yield from self.wait_tasklets()
1258
Philip Josephf4937572017-03-03 01:55:37 +05301259 yield from self.configure_project()
1260 yield from self.configure_project(project=self.project1)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -04001261
1262 cloud_type = "mock"
1263 yield from self.configure_cloud_account(self.dts, cloud_type, "mock_account")
1264 yield from self.configure_cloud_account(self.dts, cloud_type, "mock_account1")
Philip Josephf4937572017-03-03 01:55:37 +05301265 yield from self.configure_cloud_account(self.dts, cloud_type, "mock_account",
1266 project=self.project1)
1267
1268 yield from verify_cloud_accounts()
1269 yield from verify_projects()
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -04001270
1271 yield from self.ping_pong.publish_desciptors()
Philip Josephf4937572017-03-03 01:55:37 +05301272 return
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -04001273
1274 # Attempt deleting VNFD not in use
1275 yield from self.ping_pong.update_ping_vnfd()
1276
1277 # Attempt updating NSD not in use
1278 yield from self.ping_pong.update_nsd()
1279
1280 # Attempt deleting VNFD not in use
1281 yield from self.ping_pong.delete_ping_vnfd()
1282
1283 # Attempt deleting NSD not in use
1284 yield from self.ping_pong.delete_nsd()
1285
1286 yield from self.ping_pong.publish_desciptors()
1287
1288 nsr_id = yield from self.nsr_publisher.publish()
1289
1290 yield from verify_results(nsrid=nsr_id)
1291
1292 # yield from self.nsr_publisher.create_scale_group_instance("ping_group", 1)
1293
1294 # yield from verify_scale_group_reaches_state(nsr_id, "ping_group", 1, "running")
1295
1296 # yield from self.nsr_publisher.delete_scale_group_instance("ping_group", 1)
1297
1298 yield from asyncio.sleep(10, loop=self.loop)
1299
1300 # Attempt deleting VNFD in use
1301 yield from self.ping_pong.delete_ping_vnfd()
1302
1303 # Attempt updating NSD in use
1304 yield from self.ping_pong.update_nsd()
1305
1306 # Update NSD in use with new VL
1307 yield from self.nsr_publisher.add_nsr_vl()
1308
1309 # Verify the new VL has been added
1310 yield from verify_vlrs(nsr_id, count=2)
1311
1312 # Delete the added VL
1313 yield from self.nsr_publisher.del_nsr_vl()
1314
1315 # Verify the new VL has been added
1316 yield from verify_vlrs(nsr_id, count=1)
1317
1318 # Attempt deleting NSD in use
1319 yield from self.ping_pong.delete_nsd()
1320
1321 yield from terminate_ns(nsr_id)
1322
1323 yield from asyncio.sleep(25, loop=self.loop)
1324 self.log.debug("Verifying termination results")
1325 yield from verify_results(termination=True, nsrid=nsr_id)
1326 self.log.debug("Verified termination results")
1327
1328 # Multi site NS case
1329 self.log.debug("Testing multi site NS")
1330 self.nsr_publisher.update_vnf_cloud_map({1:"mock_account1",2:"mock_account"})
1331 nsr_id = yield from self.nsr_publisher.publish()
1332
1333 yield from verify_results(nsrid=nsr_id)
1334 yield from verify_vnfr_cloud_account(1,"mock_account1")
1335 yield from verify_vnfr_cloud_account(2,"mock_account")
1336 yield from verify_vlrs(nsr_id, count=2)
1337
1338 yield from terminate_ns(nsr_id)
1339
1340 yield from asyncio.sleep(25, loop=self.loop)
1341 self.log.debug("Verifying termination results for multi site NS")
1342 yield from verify_results(termination=True, nsrid=nsr_id)
1343 self.log.debug("Verified termination results for multi site NS")
1344
1345 self.log.debug("Attempting to delete VNFD for real")
1346 yield from self.ping_pong.delete_ping_vnfd()
1347
1348 self.log.debug("Attempting to delete NSD for real")
1349 yield from self.ping_pong.delete_nsd()
1350
1351 future = asyncio.ensure_future(run_test(), loop=self.loop)
1352 self.run_until(future.done)
1353 if future.exception() is not None:
1354 self.log.error("Caught exception during test")
1355 raise future.exception()
1356
1357
1358def main():
1359 plugin_dir = os.path.join(os.environ["RIFT_INSTALL"], "usr/lib/rift/plugins")
1360 if 'VNS_DIR' not in os.environ:
1361 os.environ['VNS_DIR'] = os.path.join(plugin_dir, 'rwvns')
1362
1363 if 'VNFM_DIR' not in os.environ:
1364 os.environ['VNFM_DIR'] = os.path.join(plugin_dir, 'rwvnfm')
1365
1366 if 'NSM_DIR' not in os.environ:
1367 os.environ['NSM_DIR'] = os.path.join(plugin_dir, 'rwnsm')
1368
1369 if 'RM_DIR' not in os.environ:
1370 os.environ['RM_DIR'] = os.path.join(plugin_dir, 'rwresmgrtasklet')
1371
1372 runner = xmlrunner.XMLTestRunner(output=os.environ["RIFT_MODULE_TEST"])
1373
1374 parser = argparse.ArgumentParser()
1375 parser.add_argument('-v', '--verbose', action='store_true')
1376 parser.add_argument('-n', '--no-runner', action='store_true')
1377 args, unittest_args = parser.parse_known_args()
1378 if args.no_runner:
1379 runner = None
1380
1381 ManoTestCase.log_level = logging.DEBUG if args.verbose else logging.WARN
1382
1383 unittest.main(testRunner=runner, argv=[sys.argv[0]] + unittest_args)
1384
1385if __name__ == '__main__':
1386 main()
1387
1388# vim: sw=4