--- /dev/null
+#!/usr/bin/env python3
+
+#
+# Copyright 2016 RIFT.IO Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import argparse
+import asyncio
+import logging
+import os
+import sys
+import time
+import unittest
+import uuid
+
+import xmlrunner
+
+import gi.repository.RwDts as rwdts
+import gi.repository.RwNsmYang as rwnsmyang
+import gi.repository.RwResourceMgrYang as RwResourceMgrYang
+import gi.repository.RwLaunchpadYang as launchpadyang
+import rift.tasklets
+import rift.test.dts
+
+import mano_ut
+
+
+if sys.version_info < (3, 4, 4):
+ asyncio.ensure_future = asyncio.async
+
+
+class OutOfResourceError(Exception):
+ pass
+
+
+class ComputeResourceRequestMockEventHandler(object):
+ def __init__(self):
+ self._pool_name = "vm_pool"
+ self._vdu_id = str(uuid.uuid4())
+ self._vdu_info = {
+ "vdu_id": self._vdu_id,
+ "state": "active",
+ "management_ip": "1.1.1.1",
+ "public_ip": "1.1.1.1",
+ "connection_points": [],
+ }
+
+ self._resource_state = "active"
+
+ self._event_id = None
+ self._request_info = None
+
+ def allocate(self, event_id, request_info):
+ self._event_id = event_id
+ self._request_info = request_info
+
+ self._vdu_info.update({
+ "name": self._request_info.name,
+ "flavor_id": self._request_info.flavor_id,
+ "image_id": self._request_info.image_id,
+ })
+
+ for cp in request_info.connection_points:
+ info_cp = dict(
+ name=cp.name,
+ virtual_link_id=cp.virtual_link_id,
+ vdu_id=self._vdu_id,
+ state="active",
+ ip_address="1.2.3.4",
+ )
+ info_cp = self._vdu_info["connection_points"].append(info_cp)
+
+ @property
+ def event_id(self):
+ return self._event_id
+
+ @property
+ def resource_state(self):
+ return self._resource_state
+
+ def set_active(self):
+ self._resource_state = "active"
+
+ def set_failed(self):
+ self._resource_state = "failed"
+
+ def set_pending(self):
+ self._resource_state = "pending"
+
+ @property
+ def response_msg(self):
+ resource_info = dict(
+ pool_name=self._pool_name,
+ resource_state=self.resource_state,
+ )
+ resource_info.update(self._vdu_info)
+
+ response = RwResourceMgrYang.VDUEventData.from_dict(dict(
+ event_id=self._event_id,
+ request_info=self._request_info.as_dict(),
+ resource_info=resource_info,
+ ))
+
+ return response.resource_info
+
+
+class NetworkResourceRequestMockEventHandler(object):
+ def __init__(self):
+ self._pool_name = "network_pool"
+ self._link_id = str(uuid.uuid4())
+ self._link_info = {
+ "virtual_link_id": self._link_id,
+ "state": "active",
+ }
+
+ self._resource_state = "active"
+
+ self._event_id = None
+ self._request_info = None
+
+ def allocate(self, event_id, request_info):
+ self._event_id = event_id
+ self._request_info = request_info
+
+ self._link_info.update({
+ "name": self._request_info.name,
+ "subnet": self._request_info.subnet,
+ })
+
+ @property
+ def event_id(self):
+ return self._event_id
+
+ @property
+ def resource_state(self):
+ return self._resource_state
+
+ def set_active(self):
+ self._resource_state = "active"
+
+ def set_failed(self):
+ self._resource_state = "failed"
+
+ def set_pending(self):
+ self._resource_state = "pending"
+
+ @property
+ def response_msg(self):
+ resource_info = dict(
+ pool_name=self._pool_name,
+ resource_state=self.resource_state,
+ )
+ resource_info.update(self._link_info)
+
+ response = RwResourceMgrYang.VirtualLinkEventData.from_dict(dict(
+ event_id=self._event_id,
+ request_info=self._request_info.as_dict(),
+ resource_info=resource_info,
+ ))
+
+ return response.resource_info
+
+
+class ResourceMgrMock(object):
+ VDU_REQUEST_XPATH = "D,/rw-resource-mgr:resource-mgmt/vdu-event/vdu-event-data"
+ VLINK_REQUEST_XPATH = "D,/rw-resource-mgr:resource-mgmt/vlink-event/vlink-event-data"
+
+ def __init__(self, dts, log, loop):
+ self._log = log
+ self._dts = dts
+ self._loop = loop
+ self._vdu_reg = None
+ self._link_reg = None
+
+ self._vdu_reg_event = asyncio.Event(loop=self._loop)
+ self._link_reg_event = asyncio.Event(loop=self._loop)
+
+ self._available_compute_handlers = []
+ self._available_network_handlers = []
+
+ self._used_compute_handlers = {}
+ self._used_network_handlers = {}
+
+ self._compute_allocate_requests = 0
+ self._network_allocate_requests = 0
+
+ self._registered = False
+
+ def _allocate_virtual_compute(self, event_id, request_info):
+ self._compute_allocate_requests += 1
+
+ if not self._available_compute_handlers:
+ raise OutOfResourceError("No more compute handlers")
+
+ handler = self._available_compute_handlers.pop()
+ handler.allocate(event_id, request_info)
+ self._used_compute_handlers[event_id] = handler
+
+ return handler.response_msg
+
+ def _allocate_virtual_network(self, event_id, request_info):
+ self._network_allocate_requests += 1
+
+ if not self._available_network_handlers:
+ raise OutOfResourceError("No more network handlers")
+
+ handler = self._available_network_handlers.pop()
+ handler.allocate(event_id, request_info)
+ self._used_network_handlers[event_id] = handler
+
+ return handler.response_msg
+
+ def _release_virtual_network(self, event_id):
+ del self._used_network_handlers[event_id]
+
+ def _release_virtual_compute(self, event_id):
+ del self._used_compute_handlers[event_id]
+
+ def _read_virtual_network(self, event_id):
+ return self._used_network_handlers[event_id].response_msg
+
+ def _read_virtual_compute(self, event_id):
+ return self._used_compute_handlers[event_id].response_msg
+
+ @asyncio.coroutine
+ def on_link_request_prepare(self, xact_info, action, ks_path, request_msg):
+ if not self._registered:
+ self._log.error("Got a prepare callback when not registered!")
+ xact_info.respond_xpath(rwdts.XactRspCode.NA)
+ return
+
+ self._log.debug("Received virtual-link on_prepare callback (self: %s, xact_info: %s, action: %s): %s",
+ self, xact_info, action, request_msg)
+
+ response_info = None
+ response_xpath = ks_path.to_xpath(RwResourceMgrYang.get_schema()) + "/resource-info"
+
+ schema = RwResourceMgrYang.VirtualLinkEventData().schema()
+ pathentry = schema.keyspec_to_entry(ks_path)
+
+ if action == rwdts.QueryAction.CREATE:
+ response_info = self._allocate_virtual_network(
+ pathentry.key00.event_id,
+ request_msg.request_info,
+ )
+
+ elif action == rwdts.QueryAction.DELETE:
+ self._release_virtual_network(pathentry.key00.event_id)
+
+ elif action == rwdts.QueryAction.READ:
+ response_info = self._read_virtual_network(
+ pathentry.key00.event_id
+ )
+ else:
+ raise ValueError("Only read/create/delete actions available. Received action: %s" %(action))
+
+ self._log.debug("Responding with VirtualLinkInfo at xpath %s: %s.",
+ response_xpath, response_info)
+
+ xact_info.respond_xpath(rwdts.XactRspCode.ACK, response_xpath, response_info)
+
+ @asyncio.coroutine
+ def on_vdu_request_prepare(self, xact_info, action, ks_path, request_msg):
+ if not self._registered:
+ self._log.error("Got a prepare callback when not registered!")
+ xact_info.respond_xpath(rwdts.XactRspCode.NA)
+ return
+
+ @asyncio.coroutine
+ def monitor_vdu_state(response_xpath, pathentry):
+ self._log.info("Initiating VDU state monitoring for xpath: %s ", response_xpath)
+ loop_cnt = 120
+ while loop_cnt > 0:
+ self._log.debug("VDU state monitoring: Sleeping for 1 second ")
+ yield from asyncio.sleep(1, loop = self._loop)
+ try:
+ response_info = self._read_virtual_compute(
+ pathentry.key00.event_id
+ )
+ except Exception as e:
+ self._log.error(
+ "VDU state monitoring: Received exception %s "
+ "in VDU state monitoring for %s. Aborting monitoring",
+ str(e), response_xpath
+ )
+ raise
+
+ if response_info.resource_state == 'active' or response_info.resource_state == 'failed':
+ self._log.info(
+ "VDU state monitoring: VDU reached terminal state."
+ "Publishing VDU info: %s at path: %s",
+ response_info, response_xpath
+ )
+ yield from self._dts.query_update(response_xpath,
+ rwdts.XactFlag.ADVISE,
+ response_info)
+ return
+ else:
+ loop_cnt -= 1
+
+ ### End of while loop. This is only possible if VDU did not reach active state
+ self._log.info("VDU state monitoring: VDU at xpath :%s did not reached active state in 120 seconds. Aborting monitoring",
+ response_xpath)
+ response_info = RwResourceMgrYang.VDUEventData_ResourceInfo()
+ response_info.resource_state = 'failed'
+ yield from self._dts.query_update(response_xpath,
+ rwdts.XactFlag.ADVISE,
+ response_info)
+ return
+
+ self._log.debug("Received vdu on_prepare callback (xact_info: %s, action: %s): %s",
+ xact_info, action, request_msg)
+
+ response_info = None
+ response_xpath = ks_path.to_xpath(RwResourceMgrYang.get_schema()) + "/resource-info"
+
+ schema = RwResourceMgrYang.VDUEventData().schema()
+ pathentry = schema.keyspec_to_entry(ks_path)
+
+ if action == rwdts.QueryAction.CREATE:
+ response_info = self._allocate_virtual_compute(
+ pathentry.key00.event_id,
+ request_msg.request_info,
+ )
+ if response_info.resource_state == 'pending':
+ asyncio.ensure_future(monitor_vdu_state(response_xpath, pathentry),
+ loop = self._loop)
+
+ elif action == rwdts.QueryAction.DELETE:
+ self._release_virtual_compute(
+ pathentry.key00.event_id
+ )
+
+ elif action == rwdts.QueryAction.READ:
+ response_info = self._read_virtual_compute(
+ pathentry.key00.event_id
+ )
+ else:
+ raise ValueError("Only create/delete actions available. Received action: %s" %(action))
+
+ self._log.debug("Responding with VDUInfo at xpath %s: %s",
+ response_xpath, response_info)
+
+ xact_info.respond_xpath(rwdts.XactRspCode.ACK, response_xpath, response_info)
+
+ @asyncio.coroutine
+ def register(self):
+ @asyncio.coroutine
+ def on_request_ready(registration, status):
+ self._log.debug("Got request ready event (registration: %s) (status: %s)",
+ registration, status)
+
+ if registration == self._link_reg:
+ self._link_reg_event.set()
+ elif registration == self._vdu_reg:
+ self._vdu_reg_event.set()
+ else:
+ self._log.error("Unknown registration ready event: %s", registration)
+
+
+ with self._dts.group_create() as group:
+ self._log.debug("Registering for Link Resource Request using xpath: %s",
+ ResourceMgrMock.VLINK_REQUEST_XPATH)
+
+ self._link_reg = group.register(
+ xpath=ResourceMgrMock.VLINK_REQUEST_XPATH,
+ handler=rift.tasklets.DTS.RegistrationHandler(on_ready=on_request_ready,
+ on_prepare=self.on_link_request_prepare),
+ flags=rwdts.Flag.PUBLISHER)
+
+ self._log.debug("Registering for VDU Resource Request using xpath: %s",
+ ResourceMgrMock.VDU_REQUEST_XPATH)
+
+ self._vdu_reg = group.register(
+ xpath=ResourceMgrMock.VDU_REQUEST_XPATH,
+ handler=rift.tasklets.DTS.RegistrationHandler(on_ready=on_request_ready,
+ on_prepare=self.on_vdu_request_prepare),
+ flags=rwdts.Flag.PUBLISHER)
+
+ self._registered = True
+
+ def unregister(self):
+ self._link_reg.deregister()
+ self._vdu_reg.deregister()
+ self._registered = False
+
+ @asyncio.coroutine
+ def wait_ready(self, timeout=5):
+ self._log.debug("Waiting for all request registrations to become ready.")
+ yield from asyncio.wait([self._link_reg_event.wait(), self._vdu_reg_event.wait()],
+ timeout=timeout, loop=self._loop)
+
+ def create_compute_mock_event_handler(self):
+ handler = ComputeResourceRequestMockEventHandler()
+ self._available_compute_handlers.append(handler)
+
+ return handler
+
+ def create_network_mock_event_handler(self):
+ handler = NetworkResourceRequestMockEventHandler()
+ self._available_network_handlers.append(handler)
+
+ return handler
+
+ @property
+ def num_compute_requests(self):
+ return self._compute_allocate_requests
+
+ @property
+ def num_network_requests(self):
+ return self._network_allocate_requests
+
+ @property
+ def num_allocated_compute_resources(self):
+ return len(self._used_compute_handlers)
+
+ @property
+ def num_allocated_network_resources(self):
+ return len(self._used_network_handlers)
+
+
+@unittest.skip('failing and needs rework')
+class ManoErrorTestCase(rift.test.dts.AbstractDTSTest):
+ """
+ DTS GI interface unittests
+
+ Note: Each tests uses a list of asyncio.Events for staging through the
+ test. These are required here because we are bring up each coroutine
+ ("tasklet") at the same time and are not implementing any re-try
+ mechanisms. For instance, this is used in numerous tests to make sure that
+ a publisher is up and ready before the subscriber sends queries. Such
+ event lists should not be used in production software.
+ """
+
+ @classmethod
+ def configure_suite(cls, rwmain):
+ plugin_dir = os.path.join(os.environ["RIFT_INSTALL"], "usr/lib/rift/plugins")
+ rwmain.add_tasklet(
+ os.path.join(plugin_dir, 'rwvns'),
+ 'rwvnstasklet'
+ )
+
+ rwmain.add_tasklet(
+ os.path.join(plugin_dir, 'rwvnfm'),
+ 'rwvnfmtasklet'
+ )
+
+ rwmain.add_tasklet(
+ os.path.join(plugin_dir, 'rwnsm'),
+ 'rwnsmtasklet'
+ )
+
+ cls.waited_for_tasklets = False
+
+ @asyncio.coroutine
+ def register_mock_res_mgr(self):
+ self.res_mgr = ResourceMgrMock(
+ self.dts,
+ self.log,
+ self.loop,
+ )
+ yield from self.res_mgr.register()
+
+ self.log.info("Waiting for resource manager to be ready")
+ yield from self.res_mgr.wait_ready()
+
+ def unregister_mock_res_mgr(self):
+ self.res_mgr.unregister()
+
+ @classmethod
+ def configure_schema(cls):
+ return rwnsmyang.get_schema()
+
+ @classmethod
+ def configure_timeout(cls):
+ return 240
+
+ @asyncio.coroutine
+ def wait_tasklets(self):
+ if not ManoErrorTestCase.waited_for_tasklets:
+ yield from asyncio.sleep(5, loop=self.loop)
+ ManoErrorTestCase.waited_for_tasklets = True
+
+ @asyncio.coroutine
+ def publish_desciptors(self, num_external_vlrs=1, num_internal_vlrs=1, num_ping_vms=1):
+ yield from self.ping_pong.publish_desciptors(
+ num_external_vlrs,
+ num_internal_vlrs,
+ num_ping_vms
+ )
+
+ def unpublish_descriptors(self):
+ self.ping_pong.unpublish_descriptors()
+
+ @asyncio.coroutine
+ def wait_until_nsr_active_or_failed(self, nsr_id, timeout_secs=20):
+ start_time = time.time()
+ while (time.time() - start_time) < timeout_secs:
+ nsrs = yield from self.querier.get_nsr_opdatas(nsr_id)
+ self.assertEqual(1, len(nsrs))
+ if nsrs[0].operational_status in ['running', 'failed']:
+ return
+
+ self.log.debug("Rcvd NSR with %s status", nsrs[0].operational_status)
+ yield from asyncio.sleep(2, loop=self.loop)
+
+ self.assertIn(nsrs[0].operational_status, ['running', 'failed'])
+
+ def verify_number_compute_requests(self, num_requests):
+ self.assertEqual(num_requests, self.res_mgr.num_compute_requests)
+
+ def verify_number_network_requests(self, num_requests):
+ self.assertEqual(num_requests, self.res_mgr.num_network_requests)
+
+ def verify_number_allocated_compute(self, num_allocated):
+ self.assertEqual(num_allocated, self.res_mgr.num_allocated_compute_resources)
+
+ def verify_number_allocated_network(self, num_allocated):
+ self.assertEqual(num_allocated, self.res_mgr.num_allocated_network_resources)
+
+ def allocate_network_handlers(self, num_networks):
+ return [self.res_mgr.create_network_mock_event_handler() for _ in range(num_networks)]
+
+ def allocate_compute_handlers(self, num_computes):
+ return [self.res_mgr.create_compute_mock_event_handler() for _ in range(num_computes)]
+
+ @asyncio.coroutine
+ def create_mock_launchpad_tasklet(self):
+ yield from mano_ut.create_mock_launchpad_tasklet(self.log, self.dts)
+
+ def configure_test(self, loop, test_id):
+ self.log.debug("STARTING - %s", self.id())
+ self.tinfo = self.new_tinfo(self.id())
+ self.dts = rift.tasklets.DTS(self.tinfo, self.schema, self.loop)
+ self.ping_pong = mano_ut.PingPongDescriptorPublisher(self.log, self.loop, self.dts)
+ self.querier = mano_ut.ManoQuerier(self.log, self.dts)
+
+ # Add a task to wait for tasklets to come up
+ asyncio.ensure_future(self.wait_tasklets(), loop=self.loop)
+
+ @rift.test.dts.async_test
+ def test_fail_first_nsm_vlr(self):
+ yield from self.publish_desciptors(num_external_vlrs=2)
+ yield from self.register_mock_res_mgr()
+
+ nsr_id = yield from self.ping_pong.create_nsr()
+ yield from self.wait_until_nsr_active_or_failed(nsr_id)
+
+ yield from self.verify_nsd_ref_count(self.ping_pong.nsd_id, 1)
+ yield from self.verify_nsr_state(nsr_id, "failed")
+ yield from self.verify_num_vlrs(1)
+ yield from self.verify_num_nsr_vlrs(nsr_id, 2)
+ yield from self.verify_num_vnfrs(0)
+
+ nsr_vlrs = yield from self.get_nsr_vlrs(nsr_id)
+ yield from self.verify_vlr_state(nsr_vlrs[0], "failed")
+
+ self.verify_number_network_requests(1)
+ self.verify_number_compute_requests(0)
+ self.verify_number_allocated_network(0)
+ self.verify_number_allocated_compute(0)
+
+ yield from self.terminate_nsr(nsr_id)
+
+ yield from self.verify_nsr_deleted(nsr_id)
+ yield from self.verify_nsd_ref_count(self.ping_pong.nsd_id, 0)
+ yield from self.verify_num_vlrs(0)
+
+ self.verify_number_allocated_network(0)
+ self.verify_number_allocated_compute(0)
+
+ self.unregister_mock_res_mgr()
+ self.unpublish_descriptors()
+
+ @rift.test.dts.async_test
+ def test_fail_second_nsm_vlr(self):
+ yield from self.publish_desciptors(num_external_vlrs=2)
+ yield from self.register_mock_res_mgr()
+ self.allocate_network_handlers(1)
+
+ nsr_id = yield from self.ping_pong.create_nsr()
+ yield from self.wait_until_nsr_active_or_failed(nsr_id)
+
+ yield from self.verify_nsd_ref_count(self.ping_pong.nsd_id, 1)
+ yield from self.verify_nsr_state(nsr_id, "failed")
+ yield from self.verify_num_vlrs(2)
+ yield from self.verify_num_nsr_vlrs(nsr_id, 2)
+
+ nsr_vlrs = yield from self.get_nsr_vlrs(nsr_id)
+ yield from self.verify_vlr_state(nsr_vlrs[0], "running")
+ yield from self.verify_vlr_state(nsr_vlrs[1], "failed")
+
+ self.verify_number_network_requests(2)
+ self.verify_number_compute_requests(0)
+ self.verify_number_allocated_network(1)
+ self.verify_number_allocated_compute(0)
+
+ yield from self.terminate_nsr(nsr_id)
+
+ yield from self.verify_nsr_deleted(nsr_id)
+ yield from self.verify_nsd_ref_count(self.ping_pong.nsd_id, 0)
+ yield from self.verify_num_vlrs(0)
+
+ self.verify_number_allocated_network(0)
+ self.verify_number_allocated_compute(0)
+
+ self.unregister_mock_res_mgr()
+ self.unpublish_descriptors()
+
+ @rift.test.dts.async_test
+ def test_fail_first_vnf_first_vlr(self):
+ yield from self.publish_desciptors(num_internal_vlrs=2)
+ yield from self.register_mock_res_mgr()
+ self.allocate_network_handlers(1)
+
+ nsr_id = yield from self.ping_pong.create_nsr()
+ yield from self.wait_until_nsr_active_or_failed(nsr_id)
+
+ yield from self.verify_nsd_ref_count(self.ping_pong.nsd_id, 1)
+ yield from self.verify_nsr_state(nsr_id, "failed")
+ yield from self.verify_num_vlrs(2)
+ yield from self.verify_num_nsr_vlrs(nsr_id, 1)
+
+ nsr_vlrs = yield from self.get_nsr_vlrs(nsr_id)
+ yield from self.verify_vlr_state(nsr_vlrs[0], "running")
+
+ yield from self.verify_num_nsr_vnfrs(nsr_id, 2)
+
+ # Verify only a single vnfr was instantiated and is failed
+ yield from self.verify_num_vnfrs(1)
+ nsr_vnfs = yield from self.get_nsr_vnfs(nsr_id)
+ yield from self.verify_vnf_state(nsr_vnfs[0], "failed")
+
+ yield from self.verify_num_vnfr_vlrs(nsr_vnfs[0], 2)
+ vnf_vlrs = yield from self.get_vnf_vlrs(nsr_vnfs[0])
+ yield from self.verify_vlr_state(vnf_vlrs[0], "failed")
+
+ self.verify_number_network_requests(2)
+ self.verify_number_compute_requests(0)
+ self.verify_number_allocated_network(1)
+ self.verify_number_allocated_compute(0)
+
+ yield from self.terminate_nsr(nsr_id)
+
+ yield from self.verify_nsr_deleted(nsr_id)
+ yield from self.verify_nsd_ref_count(self.ping_pong.nsd_id, 0)
+ yield from self.verify_num_vlrs(0)
+
+ self.verify_number_allocated_network(0)
+ self.verify_number_allocated_compute(0)
+
+ self.unregister_mock_res_mgr()
+ self.unpublish_descriptors()
+
+ @rift.test.dts.async_test
+ def test_fail_first_vnf_second_vlr(self):
+ yield from self.publish_desciptors(num_internal_vlrs=2)
+ yield from self.register_mock_res_mgr()
+ self.allocate_network_handlers(2)
+
+ nsr_id = yield from self.ping_pong.create_nsr()
+ yield from self.wait_until_nsr_active_or_failed(nsr_id)
+
+ yield from self.verify_nsd_ref_count(self.ping_pong.nsd_id, 1)
+ yield from self.verify_nsr_state(nsr_id, "failed")
+ yield from self.verify_num_vlrs(3)
+ yield from self.verify_num_nsr_vlrs(nsr_id, 1)
+
+ nsr_vlrs = yield from self.get_nsr_vlrs(nsr_id)
+ yield from self.verify_vlr_state(nsr_vlrs[0], "running")
+
+ yield from self.verify_num_nsr_vnfrs(nsr_id, 2)
+
+ # Verify only a single vnfr was instantiated and is failed
+ yield from self.verify_num_vnfrs(1)
+ nsr_vnfs = yield from self.get_nsr_vnfs(nsr_id)
+ yield from self.verify_vnf_state(nsr_vnfs[0], "failed")
+
+ yield from self.verify_num_vnfr_vlrs(nsr_vnfs[0], 2)
+ vnf_vlrs = yield from self.get_vnf_vlrs(nsr_vnfs[0])
+ yield from self.verify_vlr_state(vnf_vlrs[0], "running")
+ yield from self.verify_vlr_state(vnf_vlrs[1], "failed")
+
+ self.verify_number_network_requests(3)
+ self.verify_number_compute_requests(0)
+ self.verify_number_allocated_network(2)
+ self.verify_number_allocated_compute(0)
+
+ yield from self.terminate_nsr(nsr_id)
+
+ yield from self.verify_nsr_deleted(nsr_id)
+ yield from self.verify_nsd_ref_count(self.ping_pong.nsd_id, 0)
+ yield from self.verify_num_vlrs(0)
+
+ self.verify_number_allocated_network(0)
+ self.verify_number_allocated_compute(0)
+
+ self.unregister_mock_res_mgr()
+ self.unpublish_descriptors()
+
+ @rift.test.dts.async_test
+ def test_fail_first_vnf_first_vdu(self):
+ yield from self.publish_desciptors(num_internal_vlrs=2, num_ping_vms=2)
+ yield from self.register_mock_res_mgr()
+ yield from self.create_mock_launchpad_tasklet()
+ self.allocate_network_handlers(3)
+
+ nsr_id = yield from self.ping_pong.create_nsr()
+ yield from self.wait_until_nsr_active_or_failed(nsr_id)
+
+ yield from self.verify_nsd_ref_count(self.ping_pong.nsd_id, 1)
+ yield from self.verify_nsr_state(nsr_id, "failed")
+ yield from self.verify_num_vlrs(3)
+ yield from self.verify_num_nsr_vlrs(nsr_id, 1)
+
+ nsr_vlrs = yield from self.get_nsr_vlrs(nsr_id)
+ yield from self.verify_vlr_state(nsr_vlrs[0], "running")
+
+ yield from self.verify_num_nsr_vnfrs(nsr_id, 2)
+
+ # Verify only a single vnfr was instantiated and is failed
+ yield from self.verify_num_vnfrs(1)
+ nsr_vnfs = yield from self.get_nsr_vnfs(nsr_id)
+ yield from self.verify_vnf_state(nsr_vnfs[0], "failed")
+
+ yield from self.verify_num_vnfr_vlrs(nsr_vnfs[0], 2)
+ vnf_vlrs = yield from self.get_vnf_vlrs(nsr_vnfs[0])
+ yield from self.verify_vlr_state(vnf_vlrs[0], "running")
+ yield from self.verify_vlr_state(vnf_vlrs[1], "running")
+
+ yield from self.verify_num_vnfr_vdus(nsr_vnfs[0], 2)
+ vdus = yield from self.get_vnf_vdus(nsr_vnfs[0])
+ self.verify_vdu_state(vdus[0], "failed")
+
+ self.verify_number_network_requests(3)
+ self.verify_number_compute_requests(1)
+ self.verify_number_allocated_network(3)
+ self.verify_number_allocated_compute(0)
+
+ yield from self.terminate_nsr(nsr_id)
+
+ yield from self.verify_nsr_deleted(nsr_id)
+ yield from self.verify_nsd_ref_count(self.ping_pong.nsd_id, 0)
+ yield from self.verify_num_vlrs(0)
+
+ self.verify_number_allocated_network(0)
+ self.verify_number_allocated_compute(0)
+
+ self.unregister_mock_res_mgr()
+ self.unpublish_descriptors()
+
+ @rift.test.dts.async_test
+ def test_fail_first_vnf_second_vdu(self):
+ yield from self.publish_desciptors(num_internal_vlrs=2, num_ping_vms=2)
+ yield from self.register_mock_res_mgr()
+ yield from self.create_mock_launchpad_tasklet()
+ self.allocate_network_handlers(3)
+ self.allocate_compute_handlers(1)
+
+ nsr_id = yield from self.ping_pong.create_nsr()
+ yield from self.wait_until_nsr_active_or_failed(nsr_id)
+
+ yield from self.verify_nsd_ref_count(self.ping_pong.nsd_id, 1)
+ yield from self.verify_nsr_state(nsr_id, "failed")
+ yield from self.verify_num_vlrs(3)
+ yield from self.verify_num_nsr_vlrs(nsr_id, 1)
+
+ nsr_vlrs = yield from self.get_nsr_vlrs(nsr_id)
+ yield from self.verify_vlr_state(nsr_vlrs[0], "running")
+
+ yield from self.verify_num_nsr_vnfrs(nsr_id, 2)
+
+ # Verify only a single vnfr was instantiated and is failed
+ yield from self.verify_num_vnfrs(1)
+ nsr_vnfs = yield from self.get_nsr_vnfs(nsr_id)
+ yield from self.verify_vnf_state(nsr_vnfs[0], "failed")
+
+ yield from self.verify_num_vnfr_vlrs(nsr_vnfs[0], 2)
+ vnf_vlrs = yield from self.get_vnf_vlrs(nsr_vnfs[0])
+ yield from self.verify_vlr_state(vnf_vlrs[0], "running")
+ yield from self.verify_vlr_state(vnf_vlrs[1], "running")
+
+ yield from self.verify_num_vnfr_vdus(nsr_vnfs[0], 2)
+
+ vdus = yield from self.get_vnf_vdus(nsr_vnfs[0])
+ self.verify_vdu_state(vdus[0], "running")
+ self.verify_vdu_state(vdus[1], "failed")
+
+ self.verify_number_network_requests(3)
+ self.verify_number_compute_requests(2)
+ self.verify_number_allocated_network(3)
+ self.verify_number_allocated_compute(1)
+
+ yield from self.terminate_nsr(nsr_id)
+
+ yield from self.verify_nsr_deleted(nsr_id)
+ yield from self.verify_nsd_ref_count(self.ping_pong.nsd_id, 0)
+ yield from self.verify_num_vlrs(0)
+
+ self.verify_number_allocated_network(0)
+ self.verify_number_allocated_compute(0)
+
+ self.unregister_mock_res_mgr()
+ self.unpublish_descriptors()
+
+ @rift.test.dts.async_test
+ def test_fail_second_vnf_second_vdu(self):
+ yield from self.publish_desciptors(num_internal_vlrs=2, num_ping_vms=2)
+ yield from self.register_mock_res_mgr()
+ yield from self.create_mock_launchpad_tasklet()
+ self.allocate_network_handlers(5)
+ self.allocate_compute_handlers(3)
+
+ nsr_id = yield from self.ping_pong.create_nsr()
+ yield from self.wait_until_nsr_active_or_failed(nsr_id)
+
+ yield from self.verify_nsd_ref_count(self.ping_pong.nsd_id, 1)
+ yield from self.verify_nsr_state(nsr_id, "failed")
+ yield from self.verify_num_vlrs(5)
+ yield from self.verify_num_nsr_vlrs(nsr_id, 1)
+
+ nsr_vlrs = yield from self.get_nsr_vlrs(nsr_id)
+ yield from self.verify_vlr_state(nsr_vlrs[0], "running")
+
+ yield from self.verify_num_nsr_vnfrs(nsr_id, 2)
+
+ # Verify only a single vnfr was instantiated and is failed
+ yield from self.verify_num_vnfrs(2)
+ nsr_vnfs = yield from self.get_nsr_vnfs(nsr_id)
+ yield from self.verify_vnf_state(nsr_vnfs[0], "running")
+ yield from self.verify_vnf_state(nsr_vnfs[1], "failed")
+
+ yield from self.verify_num_vnfr_vlrs(nsr_vnfs[0], 2)
+
+ vnf_vlrs = yield from self.get_vnf_vlrs(nsr_vnfs[0])
+ yield from self.verify_vlr_state(vnf_vlrs[0], "running")
+ yield from self.verify_vlr_state(vnf_vlrs[1], "running")
+
+ vnf_vlrs = yield from self.get_vnf_vlrs(nsr_vnfs[1])
+ yield from self.verify_vlr_state(vnf_vlrs[0], "running")
+ yield from self.verify_vlr_state(vnf_vlrs[1], "running")
+
+ yield from self.verify_num_vnfr_vdus(nsr_vnfs[0], 2)
+ yield from self.verify_num_vnfr_vdus(nsr_vnfs[1], 2)
+
+ vdus = yield from self.get_vnf_vdus(nsr_vnfs[0])
+ self.verify_vdu_state(vdus[0], "running")
+ self.verify_vdu_state(vdus[1], "running")
+
+ vdus = yield from self.get_vnf_vdus(nsr_vnfs[1])
+ self.verify_vdu_state(vdus[0], "running")
+ self.verify_vdu_state(vdus[1], "failed")
+
+ self.verify_number_network_requests(5)
+ self.verify_number_compute_requests(4)
+ self.verify_number_allocated_network(5)
+ self.verify_number_allocated_compute(3)
+
+ yield from self.terminate_nsr(nsr_id)
+
+ yield from self.verify_nsr_deleted(nsr_id)
+ yield from self.verify_nsd_ref_count(self.ping_pong.nsd_id, 0)
+ yield from self.verify_num_vlrs(0)
+
+ self.verify_number_allocated_network(0)
+ self.verify_number_allocated_compute(0)
+
+ self.unregister_mock_res_mgr()
+ self.unpublish_descriptors()
+
+
+def main():
+ runner = xmlrunner.XMLTestRunner(output=os.environ["RIFT_MODULE_TEST"])
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-v', '--verbose', action='store_true')
+ args, _ = parser.parse_known_args()
+
+ ManoErrorTestCase.log_level = logging.DEBUG if args.verbose else logging.WARN
+
+ unittest.main(testRunner=runner)
+
+if __name__ == '__main__':
+ main()
+
+# vim: sw