summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docker/vnf/Dockerfile11
-rw-r--r--docs/testing/user/userguide/test_details.rst33
-rw-r--r--docs/testing/user/userguide/test_overview.rst11
-rw-r--r--functest/ci/config_aarch64_patch.yaml8
-rw-r--r--functest/ci/download_images.sh4
-rw-r--r--functest/ci/rally_aarch64_patch.conf2
-rw-r--r--functest/opnfv_tests/openstack/rally/rally.py142
-rw-r--r--functest/opnfv_tests/openstack/tempest/tempest.py3
-rw-r--r--functest/opnfv_tests/openstack/vping/vping_base.py5
-rw-r--r--functest/opnfv_tests/sdn/odl/odl.py12
-rw-r--r--functest/opnfv_tests/vnf/epc/juju_epc.py103
-rw-r--r--functest/opnfv_tests/vnf/ims/cloudify_ims.py169
-rw-r--r--functest/opnfv_tests/vnf/ims/cloudify_ims.yaml10
-rw-r--r--functest/opnfv_tests/vnf/ims/cloudify_ims_perf.yaml4
-rw-r--r--functest/opnfv_tests/vnf/router/cloudify_vrouter.py179
-rw-r--r--functest/opnfv_tests/vnf/router/cloudify_vrouter.yaml11
-rw-r--r--functest/tests/unit/odl/test_odl.py148
-rw-r--r--functest/tests/unit/openstack/rally/test_rally.py65
18 files changed, 580 insertions, 340 deletions
diff --git a/docker/vnf/Dockerfile b/docker/vnf/Dockerfile
index afaec2320..54241875e 100644
--- a/docker/vnf/Dockerfile
+++ b/docker/vnf/Dockerfile
@@ -2,7 +2,9 @@ FROM opnfv/functest-core
ARG BRANCH=master
ARG OPENSTACK_TAG=stable/queens
-ARG VIMS_TAG=stable
+ARG VIMS_TEST_TAG=stable
+ARG VIMS_TAG=fraser
+ARG VROUTER_TAG=fraser
ARG JUJU_TAG=tags/juju-2.2.5
ENV GOPATH /src/epc-requirements/go
@@ -17,7 +19,9 @@ RUN apk --no-cache add --update \
wget -q -O- https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=$OPENSTACK_TAG | \
sed -E s/^tempest==+\(.*\)$/-e\ git+https:\\/\\/github.com\\/openstack\\/tempest@\\1#egg=tempest/ | \
> upper-constraints.txt && \
- git clone --depth 1 -b $VIMS_TAG https://github.com/boucherv-orange/clearwater-live-test /src/vims-test && \
+ git clone --depth 1 -b $VIMS_TEST_TAG https://github.com/boucherv-orange/clearwater-live-test.git /src/vims-test && \
+ git clone --depth 1 -b $VIMS_TAG https://github.com/Orange-OpenSource/opnfv-cloudify-clearwater.git /src/vims && \
+ git clone --depth 1 -b $VROUTER_TAG https://github.com/oolorg/opnfv-vnf-vyos-blueprint.git /src/opnfv-vnf-vyos-blueprint && \
git clone https://github.com/RebacaInc/abot_charm.git /src/epc-requirements/abot_charm && \
python3 -m pip install --no-cache-dir --src /src -cupper-constraints.txt \
-chttps://git.opnfv.org/functest/plain/upper-constraints.txt?h=$BRANCH \
@@ -28,7 +32,8 @@ RUN apk --no-cache add --update \
go install -v github.com/juju/juju/... && \
rm -rf $GOPATH/go/src/ $GOPATH/pkg && \
(cd /src/vims-test && bundle config build.nokogiri --use-system-libraries && bundle install --system) && \
- rm -r upper-constraints.txt /src/vims-test/.git /src/epc-requirements/abot_charm/.git && \
+ rm -r upper-constraints.txt /src/vims-test/.git /src/vims/.git /src/opnfv-vnf-vyos-blueprint/.git \
+ /src/epc-requirements/abot_charm/.git && \
apk del .build-deps
COPY testcases.yaml /usr/lib/python2.7/site-packages/xtesting/ci/testcases.yaml
CMD ["run_tests", "-t", "all"]
diff --git a/docs/testing/user/userguide/test_details.rst b/docs/testing/user/userguide/test_details.rst
index 543f66a19..38d35a697 100644
--- a/docs/testing/user/userguide/test_details.rst
+++ b/docs/testing/user/userguide/test_details.rst
@@ -422,13 +422,41 @@ The vyos-vrouter architecture is described in `[14]`_
juju_epc
^^^^^^^^
+The Evolved Packet Core (EPC) is the main component of the System Architecture
+Evolution (SAE) which forms the core of the 3GPP LTE specification.
+vEPC has been integrated in Functest to demonstrate the capability to deploy a
+complex mobility-specific NFV scenario on the OPNFV platform. The OAI EPC
+supports most of the essential functions defined by the 3GPP Technical Specs;
+hence the successful execution of functional tests on the OAI EPC provides a
+good endorsement of the underlying NFV platform.
+
+This integration also includes ABot, a Test Orchestration system that enables
+test scenarios to be defined in high-level DSL. ABot is also deployed as a
+VM on the OPNFV platform; and this provides an example of the automation
+driver and the Test VNF being both deployed as separate VNFs on the underlying
+OPNFV platform.
+
+The Workflow is as follows:
+ * Deploy Orchestrator
+ Deploy Juju controller using Bootstrap command.
+ * Deploy VNF
+ Deploy ABot orchestrator and OAI EPC as Juju charms.
+ Configuration of ABot and OAI EPC components is handled through
+ built-in Juju relations.
+ * Test VNF
+ Execution of ABot feature files triggered by Juju actions.
+ This executes a suite of LTE signalling tests on the OAI EPC.
+ * Reporting
+ ABot test results are parsed accordingly and pushed to Functest Db.
+
+Details of the ABot test orchestration tool may be found in `[15]`_
Kubernetes (K8s)
----------------
Kubernetes testing relies on sets of tests, which are part of the Kubernetes
-source tree, such as the Kubernetes End-to-End (e2e) tests `[15]`_.
+source tree, such as the Kubernetes End-to-End (e2e) tests `[16]`_.
The kubernetes testcases are distributed across various Tiers:
@@ -460,4 +488,5 @@ The kubernetes testcases are distributed across various Tiers:
.. _`[12]`: http://docs.opnfv.org/en/latest/submodules/functest/docs/testing/user/userguide/index.html
.. _`[13]`: https://wiki.opnfv.org/display/PROJ/SNAPS-OO
.. _`[14]`: https://github.com/oolorg/opnfv-functest-vrouter
-.. _`[15]`: https://github.com/kubernetes/community/blob/master/contributors/devel/e2e-tests.md
+.. _`[15]`: https://www.rebaca.com/abot-test-orchestration-tool/
+.. _`[16]`: https://github.com/kubernetes/community/blob/master/contributors/devel/e2e-tests.md
diff --git a/docs/testing/user/userguide/test_overview.rst b/docs/testing/user/userguide/test_overview.rst
index 4644109a5..b88a99caf 100644
--- a/docs/testing/user/userguide/test_overview.rst
+++ b/docs/testing/user/userguide/test_overview.rst
@@ -147,8 +147,15 @@ validate the scenario for the release.
| | | vyos | vRouter testing |
| | | \_vrouter | |
| | +------------+----------------------------------+
-| | | juju_epc | vEPC validation with Juju as VNF |
-| | | | manager and ABoT as test executor|
+| | | juju_epc | Validates deployment of a complex|
+| | | | mobility VNF on OPNFV Platform. |
+| | | | Uses Juju for deploying the OAI |
+| | | | EPC and ABot for defining test |
+| | | | scenarios using high-level DSL. |
+| | | | VNF tests reference 3GPP |
+| | | | Technical Specs and are executed |
+| | | | through protocol drivers provided|
+| | | | by ABot. |
| | +------------+----------------------------------+
| | | cloudify | Based on cloudify_ims test case |
| | | \_ims_perf | cloudify_ims_perf substitutes |
diff --git a/functest/ci/config_aarch64_patch.yaml b/functest/ci/config_aarch64_patch.yaml
index 2f1289c1c..983461d78 100644
--- a/functest/ci/config_aarch64_patch.yaml
+++ b/functest/ci/config_aarch64_patch.yaml
@@ -3,8 +3,10 @@ os:
general:
openstack:
image_name: TestVM
- image_file_name: cirros-d161201-aarch64-disk.img
+ image_file_name: cirros-0.4.0-aarch64-disk.img
image_password: gocubsgo
+ image_url:
+ /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
extra_properties:
hw_firmware_type: 'uefi'
hw_video_model: 'vga'
@@ -15,7 +17,7 @@ os:
images:
glance_tests:
disk_file:
- /home/opnfv/functest/images/cirros-d161201-aarch64-disk.img
+ /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
extra_properties:
hw_firmware_type: 'uefi'
short_id: 'ubuntu16.04'
@@ -24,7 +26,7 @@ os:
hw_scsi_model: 'virtio-scsi'
cirros:
disk_file:
- /home/opnfv/functest/images/cirros-d161201-aarch64-disk.img
+ /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
extra_properties:
hw_firmware_type: 'uefi'
short_id: 'ubuntu16.04'
diff --git a/functest/ci/download_images.sh b/functest/ci/download_images.sh
index c498b9bcc..d3dcee266 100644
--- a/functest/ci/download_images.sh
+++ b/functest/ci/download_images.sh
@@ -11,9 +11,7 @@ https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2
https://cloud-images.ubuntu.com/releases/16.04/release/ubuntu-16.04-server-cloudimg-amd64-disk1.img
http://repository.cloudifysource.org/cloudify/4.0.1/sp-release/cloudify-manager-premium-4.0.1.qcow2
http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-lxc.tar.gz
-http://download.cirros-cloud.net/daily/20161201/cirros-d161201-aarch64-disk.img
-http://download.cirros-cloud.net/daily/20161201/cirros-d161201-aarch64-initramfs
-http://download.cirros-cloud.net/daily/20161201/cirros-d161201-aarch64-kernel
+http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-aarch64-disk.img
https://cloud-images.ubuntu.com/releases/14.04/release/ubuntu-14.04-server-cloudimg-arm64-uefi1.img
http://cloud.centos.org/altarch/7/images/aarch64/CentOS-7-aarch64-GenericCloud.qcow2.xz
https://sourceforge.net/projects/ool-opnfv/files/vyos-1.1.7.img
diff --git a/functest/ci/rally_aarch64_patch.conf b/functest/ci/rally_aarch64_patch.conf
index e5cae8137..baeceac76 100644
--- a/functest/ci/rally_aarch64_patch.conf
+++ b/functest/ci/rally_aarch64_patch.conf
@@ -1,5 +1,5 @@
img_name_regex = ^TestVM$
-img_url = http://download.cirros-cloud.net/daily/20161201/cirros-d161201-aarch64-disk.img
+img_url = http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-aarch64-disk.img
flavor_ref_ram = 256
flavor_ref_alt_ram = 256
heat_instance_type_ram = 256
diff --git a/functest/opnfv_tests/openstack/rally/rally.py b/functest/opnfv_tests/openstack/rally/rally.py
index 8d1bfabb5..cca198853 100644
--- a/functest/opnfv_tests/openstack/rally/rally.py
+++ b/functest/opnfv_tests/openstack/rally/rally.py
@@ -47,7 +47,7 @@ class RallyBase(testcase.TestCase):
config.CONF, 'dir_functest_images'), GLANCE_IMAGE_FILENAME)
GLANCE_IMAGE_FORMAT = getattr(config.CONF, 'openstack_image_disk_format')
GLANCE_IMAGE_EXTRA_PROPERTIES = getattr(
- config.CONF, 'image_properties', {})
+ config.CONF, 'openstack_extra_properties', {})
FLAVOR_NAME = getattr(config.CONF, 'rally_flavor_name')
FLAVOR_ALT_NAME = getattr(config.CONF, 'rally_flavor_alt_name')
FLAVOR_RAM = 512
@@ -181,14 +181,14 @@ class RallyBase(testcase.TestCase):
:return: Bool
"""
rally_report = json.loads(json_raw)
- for report in rally_report:
- if report is None or report.get('result') is None:
- return False
-
- for result in report.get('result'):
- if result is None or result.get('error'):
+ tasks = rally_report.get('tasks')
+ if tasks:
+ for task in tasks:
+ if task.get('status') != 'finished' or \
+ task.get('pass_sla') is not True:
return False
-
+ else:
+ return False
return True
def _migration_supported(self):
@@ -316,6 +316,52 @@ class RallyBase(testcase.TestCase):
return True
+ def _save_results(self, test_name, task_id):
+ """ Generate and save task execution results"""
+ # check for result directory and create it otherwise
+ if not os.path.exists(self.RESULTS_DIR):
+ LOGGER.debug('%s does not exist, we create it.',
+ self.RESULTS_DIR)
+ os.makedirs(self.RESULTS_DIR)
+
+ # put detailed result to log
+ cmd = (["rally", "task", "detailed", "--uuid", task_id])
+ LOGGER.debug('running command: %s', cmd)
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ json_detailed = self.get_cmd_output(proc)
+ LOGGER.info('%s', json_detailed)
+
+ # save report as JSON
+ cmd = (["rally", "task", "report", "--json", "--uuid", task_id])
+ LOGGER.debug('running command: %s', cmd)
+ with open(os.devnull, 'w') as devnull:
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=devnull)
+ json_results = self.get_cmd_output(proc)
+ report_json_name = 'opnfv-{}.json'.format(test_name)
+ report_json_dir = os.path.join(self.RESULTS_DIR, report_json_name)
+ with open(report_json_dir, 'w') as r_file:
+ LOGGER.debug('saving json file')
+ r_file.write(json_results)
+
+ # save report as HTML
+ report_html_name = 'opnfv-{}.html'.format(test_name)
+ report_html_dir = os.path.join(self.RESULTS_DIR, report_html_name)
+ cmd = (["rally", "task", "report", "--html", "--uuid", task_id,
+ "--out", report_html_dir])
+ LOGGER.debug('running command: %s', cmd)
+ with open(os.devnull, 'w') as devnull:
+ subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=devnull)
+
+ self._append_summary(json_results, test_name)
+
+ # parse JSON operation result
+ if self.task_succeed(json_results):
+ LOGGER.info('Test scenario: "{}" OK.'.format(test_name) + "\n")
+ else:
+ LOGGER.info('Test scenario: "{}" Failed.'.format(test_name) + "\n")
+
def _run_task(self, test_name):
"""Run a task."""
LOGGER.info('Starting test scenario "%s" ...', test_name)
@@ -351,47 +397,9 @@ class RallyBase(testcase.TestCase):
stderr=subprocess.STDOUT)
output = self.get_cmd_output(proc)
LOGGER.error("Task validation result:" + "\n" + output)
- return
+ raise Exception("Failed to retrieve task id")
- # check for result directory and create it otherwise
- if not os.path.exists(self.RESULTS_DIR):
- LOGGER.debug('%s does not exist, we create it.',
- self.RESULTS_DIR)
- os.makedirs(self.RESULTS_DIR)
-
- # get and save rally operation JSON result
- cmd = (["rally", "task", "detailed", task_id])
- LOGGER.debug('running command: %s', cmd)
- proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- json_detailed = self.get_cmd_output(proc)
- LOGGER.info('%s', json_detailed)
-
- cmd = (["rally", "task", "results", task_id])
- LOGGER.debug('running command: %s', cmd)
- proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- json_results = self.get_cmd_output(proc)
- self._append_summary(json_results, test_name)
- report_json_name = 'opnfv-{}.json'.format(test_name)
- report_json_dir = os.path.join(self.RESULTS_DIR, report_json_name)
- with open(report_json_dir, 'w') as r_file:
- LOGGER.debug('saving json file')
- r_file.write(json_results)
-
- # write html report file
- report_html_name = 'opnfv-{}.html'.format(test_name)
- report_html_dir = os.path.join(self.RESULTS_DIR, report_html_name)
- cmd = (["rally", "task", "report", task_id, "--out", report_html_dir])
- LOGGER.debug('running command: %s', cmd)
- subprocess.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
-
- # parse JSON operation result
- if self.task_succeed(json_results):
- LOGGER.info('Test scenario: "{}" OK.'.format(test_name) + "\n")
- else:
- LOGGER.info('Test scenario: "{}" Failed.'.format(test_name) + "\n")
+ self._save_results(test_name, task_id)
def _append_summary(self, json_raw, test_name):
"""Update statistics summary info."""
@@ -400,20 +408,24 @@ class RallyBase(testcase.TestCase):
overall_duration = 0.0
rally_report = json.loads(json_raw)
- for report in rally_report:
- if report.get('full_duration'):
- overall_duration += report.get('full_duration')
+ for task in rally_report.get('tasks'):
+ for subtask in task.get('subtasks'):
+ for workload in subtask.get('workloads'):
+ if workload.get('full_duration'):
+ overall_duration += workload.get('full_duration')
- if report.get('result'):
- for result in report.get('result'):
- nb_tests += 1
- if not result.get('error'):
- nb_success += 1
+ if workload.get('data'):
+ nb_tests += len(workload.get('data'))
+
+ for result in workload.get('data'):
+ if not result.get('error'):
+ nb_success += 1
scenario_summary = {'test_name': test_name,
'overall_duration': overall_duration,
'nb_tests': nb_tests,
- 'nb_success': nb_success}
+ 'nb_success': nb_success,
+ 'task_status': self.task_succeed(json_raw)}
self.summary.append(scenario_summary)
def _prepare_env(self):
@@ -508,6 +520,7 @@ class RallyBase(testcase.TestCase):
total_duration = 0.0
total_nb_tests = 0
total_nb_success = 0
+ nb_modules = 0
payload = []
res_table = prettytable.PrettyTable(
@@ -519,6 +532,8 @@ class RallyBase(testcase.TestCase):
# for each scenario we draw a row for the table
for item in self.summary:
+ if item['task_status'] is True:
+ nb_modules += 1
total_duration += item['overall_duration']
total_nb_tests += item['nb_tests']
total_nb_success += item['nb_success']
@@ -549,8 +564,9 @@ class RallyBase(testcase.TestCase):
success_rate_str])
LOGGER.info("Rally Summary Report:\n\n%s\n", res_table.get_string())
- LOGGER.info("Rally '%s' success_rate is %s%%",
- self.case_name, success_rate)
+ LOGGER.info("Rally '%s' success_rate is %s%% in %s/%s modules",
+ self.case_name, success_rate, nb_modules,
+ len(self.summary))
payload.append({'summary': {'duration': total_duration,
'nb tests': total_nb_tests,
'nb success': success_rate}})
@@ -573,6 +589,14 @@ class RallyBase(testcase.TestCase):
if self.image:
self.cloud.delete_image(self.image.id)
+ def is_successful(self):
+ """The overall result of the test."""
+ for item in self.summary:
+ if item['task_status'] is False:
+ return testcase.TestCase.EX_TESTCASE_FAILED
+
+ return super(RallyBase, self).is_successful()
+
@energy.enable_recording
def run(self, **kwargs):
"""Run testcase."""
diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py
index 5ba1ed38a..11de144c9 100644
--- a/functest/opnfv_tests/openstack/tempest/tempest.py
+++ b/functest/opnfv_tests/openstack/tempest/tempest.py
@@ -428,9 +428,10 @@ class TempestResourcesManager(object):
def _create_image(self, name):
"""Create image for tests"""
LOGGER.info("Creating image with name: '%s'", name)
+ meta = getattr(config.CONF, 'openstack_extra_properties', None)
image = self.cloud.create_image(
name, filename=getattr(config.CONF, 'openstack_image_url'),
- is_public=True)
+ is_public=True, meta=meta)
LOGGER.debug("image: %s", image)
return image
diff --git a/functest/opnfv_tests/openstack/vping/vping_base.py b/functest/opnfv_tests/openstack/vping/vping_base.py
index 2d1f856d7..2451c2de4 100644
--- a/functest/opnfv_tests/openstack/vping/vping_base.py
+++ b/functest/opnfv_tests/openstack/vping/vping_base.py
@@ -64,9 +64,12 @@ class VPingBase(testcase.TestCase):
image_base_name = '{}-{}'.format(
getattr(config.CONF, 'vping_image_name'), self.guid)
self.logger.info("Creating image with name: '%s'", image_base_name)
+ meta = getattr(config.CONF, 'openstack_extra_properties', None)
+ self.logger.info("Image metadata: %s", meta)
self.image = self.cloud.create_image(
image_base_name,
- filename=getattr(config.CONF, 'openstack_image_url'))
+ filename=getattr(config.CONF, 'openstack_image_url'),
+ meta=meta)
self.logger.debug("image: %s", self.image)
private_net_name = getattr(
diff --git a/functest/opnfv_tests/sdn/odl/odl.py b/functest/opnfv_tests/sdn/odl/odl.py
index 7c61e88df..cc56c6202 100644
--- a/functest/opnfv_tests/sdn/odl/odl.py
+++ b/functest/opnfv_tests/sdn/odl/odl.py
@@ -25,10 +25,9 @@ import os
import re
import sys
+import os_client_config
from six.moves import urllib
-from snaps.openstack.utils import keystone_utils
-from functest.opnfv_tests.openstack.snaps import snaps_utils
from functest.utils import config
from functest.utils import env
from xtesting.core import robotframework
@@ -157,9 +156,12 @@ class ODLTests(robotframework.RobotFramework):
suites = kwargs["suites"]
except KeyError:
pass
- snaps_creds = snaps_utils.get_credentials()
- kwargs = {'neutronurl': keystone_utils.get_endpoint(
- snaps_creds, 'network')}
+ cloud = os_client_config.make_shade()
+ neutron_id = cloud.search_services('neutron')[0].id
+ endpoint = cloud.search_endpoints(
+ filters={'interface': os.environ.get('OS_INTERFACE', 'public'),
+ 'service_id': neutron_id})[0].url
+ kwargs = {'neutronurl': endpoint}
kwargs['odlip'] = env.get('SDN_CONTROLLER_IP')
kwargs['odlwebport'] = '8080'
kwargs['odlrestconfport'] = '8181'
diff --git a/functest/opnfv_tests/vnf/epc/juju_epc.py b/functest/opnfv_tests/vnf/epc/juju_epc.py
index 50253ccac..224d71114 100644
--- a/functest/opnfv_tests/vnf/epc/juju_epc.py
+++ b/functest/opnfv_tests/vnf/epc/juju_epc.py
@@ -137,7 +137,7 @@ class JujuEpc(vnf.VnfOnBoarding):
name=name,
password=str(uuid.uuid4()),
project_name=self.tenant_name,
- domain=self.snaps_creds.user_domain_name,
+ domain_name=self.snaps_creds.user_domain_name,
roles={'_member_': self.tenant_name}))
user_creator.create()
self.created_object.append(user_creator)
@@ -218,8 +218,12 @@ class JujuEpc(vnf.VnfOnBoarding):
if ex.errno != errno.EEXIST:
self.__logger.exception("Cannot create %s", self.res_dir)
raise vnf.VnfPreparationException
+
+ self.__logger.info("ENV:\n%s", env.string())
+
self.public_auth_url = keystone_utils.get_endpoint(
self.snaps_creds, 'identity')
+
# it enforces a versioned public identity endpoint as juju simply
# adds /auth/tokens wich fails vs an unversioned endpoint.
if not self.public_auth_url.endswith(('v3', 'v3/', 'v2.0', 'v2.0/')):
@@ -236,7 +240,7 @@ class JujuEpc(vnf.VnfOnBoarding):
Bootstrap juju
"""
- self.__logger.info("Deployed Orchestrator")
+ self.__logger.info("Deploying Juju Orchestrator")
private_net_name = getattr(
config.CONF, 'vnf_{}_private_net_name'.format(self.case_name))
private_subnet_name = '{}-{}'.format(
@@ -249,7 +253,8 @@ class JujuEpc(vnf.VnfOnBoarding):
getattr(config.CONF,
'vnf_{}_external_router'.format(self.case_name)),
self.uuid)
- self.__logger.info("Creating full network ...")
+ self.__logger.info("Creating full network with nameserver: %s",
+ env.get('NAMESERVER'))
subnet_settings = SubnetConfig(
name=private_subnet_name,
cidr=private_subnet_cidr,
@@ -277,6 +282,7 @@ class JujuEpc(vnf.VnfOnBoarding):
flavor_creator = OpenStackFlavor(self.snaps_creds, flavor_settings)
flavor_creator.create()
self.created_object.append(flavor_creator)
+
self.__logger.info("Upload some OS images if it doesn't exist")
images = get_config("tenant_images", self.config_file)
self.__logger.info("Images needed for vEPC: %s", images)
@@ -287,8 +293,7 @@ class JujuEpc(vnf.VnfOnBoarding):
name=image_name, image_user='cloud', img_format='qcow2',
image_file=image_file))
image_id = image_creator.create().id
- cmd = ['timeout', '-t', JujuEpc.juju_timeout,
- 'juju', 'metadata', 'generate-image', '-d', '/root',
+ cmd = ['juju', 'metadata', 'generate-image', '-d', '/root',
'-i', image_id, '-s', image_name,
'-r', self.snaps_creds.region_name,
'-u', self.public_auth_url]
@@ -296,18 +301,30 @@ class JujuEpc(vnf.VnfOnBoarding):
self.__logger.info("%s\n%s", " ".join(cmd), output)
self.created_object.append(image_creator)
self.__logger.info("Network ID : %s", net_id)
- cmd = ['timeout', '-t', JujuEpc.juju_timeout,
- 'juju', 'bootstrap', 'abot-epc', 'abot-controller',
- '--metadata-source', '/root',
- '--constraints', 'mem=2G',
- '--bootstrap-series', 'xenial',
- '--config', 'network={}'.format(net_id),
- '--config', 'ssl-hostname-verification=false',
- '--config', 'use-floating-ip=true',
- '--config', 'use-default-secgroup=true',
- '--debug']
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
+
+ self.__logger.info("Starting Juju Bootstrap process...")
+ try:
+ cmd = ['timeout', '-t', JujuEpc.juju_timeout,
+ 'juju', 'bootstrap', 'abot-epc', 'abot-controller',
+ '--metadata-source', '/root',
+ '--constraints', 'mem=2G',
+ '--bootstrap-series', 'xenial',
+ '--config', 'network={}'.format(net_id),
+ '--config', 'ssl-hostname-verification=false',
+ '--config', 'use-floating-ip=true',
+ '--config', 'use-default-secgroup=true',
+ '--debug']
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ self.__logger.info("%s\n%s", " ".join(cmd), output)
+ except subprocess.CalledProcessError as cpe:
+ self.__logger.error(
+ "Exception with Juju Bootstrap: %s\n%s",
+ cpe.cmd, cpe.output)
+ return False
+ except Exception: # pylint: disable=broad-except
+ self.__logger.exception("Some issue with Juju Bootstrap ...")
+ return False
+
return True
def check_app(self, name='abot-epc-basic', status='active'):
@@ -336,15 +353,32 @@ class JujuEpc(vnf.VnfOnBoarding):
flavor_creator.create()
self.created_object.append(flavor_creator)
self.__logger.info("Deploying Abot-epc bundle file ...")
- cmd = ['timeout', '-t', JujuEpc.juju_timeout,
- 'juju', 'deploy', '{}'.format(descriptor.get('file_name'))]
+ cmd = ['juju', 'deploy', '{}'.format(descriptor.get('file_name'))]
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
self.__logger.info("%s\n%s", " ".join(cmd), output)
self.__logger.info("Waiting for instances .....")
- cmd = ['timeout', '-t', JujuEpc.juju_timeout, 'juju-wait']
+ try:
+ cmd = ['timeout', '-t', JujuEpc.juju_timeout, 'juju-wait']
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ self.__logger.info("%s\n%s", " ".join(cmd), output)
+ self.__logger.info("Deployed Abot-epc on Openstack")
+ except subprocess.CalledProcessError as cpe:
+ self.__logger.error(
+ "Exception with Juju VNF Deployment: %s\n%s",
+ cpe.cmd, cpe.output)
+ return False
+ except Exception: # pylint: disable=broad-except
+ self.__logger.exception("Some issue with the VNF Deployment ..")
+ return False
+
+ self.__logger.info("Checking status of ABot and EPC units ...")
+ cmd = ['juju', 'status']
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
- self.__logger.info("Deployed Abot-epc on Openstack")
+ self.__logger.debug("%s\n%s", " ".join(cmd), output)
+ for app in ['abot-epc-basic', 'oai-epc', 'oai-hss']:
+ if not self.check_app(app):
+ return False
+
nova_client = nova_utils.nova_client(self.snaps_creds)
instances = get_instances(nova_client)
self.__logger.info("List of Instance: %s", instances)
@@ -360,22 +394,18 @@ class JujuEpc(vnf.VnfOnBoarding):
# This will add sctp rule to a common Security Group Created
# by juju and shared to all deployed units.
self._add_custom_rule(sec_group)
- cmd = ['juju', 'status']
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.debug("%s\n%s", " ".join(cmd), output)
- for app in ['abot-epc-basic', 'oai-epc', 'oai-hss']:
- if not self.check_app(app):
- return False
- self.__logger.info("Copying the feature files to Abot_node ")
+
+ self.__logger.info("Transferring the feature files to Abot_node ...")
cmd = ['timeout', '-t', JujuEpc.juju_timeout,
'juju', 'scp', '--', '-r', '-v',
'{}/featureFiles'.format(self.case_dir), 'abot-epc-basic/0:~/']
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
self.__logger.info("%s\n%s", " ".join(cmd), output)
- self.__logger.info("Copying the feature files in Abot_node ")
+
+ self.__logger.info("Copying the feature files within Abot_node ")
cmd = ['timeout', '-t', JujuEpc.juju_timeout,
'juju', 'ssh', 'abot-epc-basic/0',
- 'sudo', 'rsync', '-azvv', '~/featureFiles',
+ 'sudo', 'cp', '-vfR', '~/featureFiles/*',
'/etc/rebaca-test-suite/featureFiles']
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
self.__logger.info("%s\n%s", " ".join(cmd), output)
@@ -385,14 +415,15 @@ class JujuEpc(vnf.VnfOnBoarding):
"""Run test on ABoT."""
start_time = time.time()
self.__logger.info("Running VNF Test cases....")
- cmd = ['timeout', '-t', JujuEpc.juju_timeout,
- 'juju', 'run-action', 'abot-epc-basic/0', 'run',
+ cmd = ['juju', 'run-action', 'abot-epc-basic/0', 'run',
'tagnames={}'.format(self.details['test_vnf']['tag_name'])]
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
self.__logger.info("%s\n%s", " ".join(cmd), output)
+
cmd = ['timeout', '-t', JujuEpc.juju_timeout, 'juju-wait']
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
self.__logger.info("%s\n%s", " ".join(cmd), output)
+
duration = time.time() - start_time
self.__logger.info("Getting results from Abot node....")
cmd = ['timeout', '-t', JujuEpc.juju_timeout,
@@ -429,8 +460,12 @@ class JujuEpc(vnf.VnfOnBoarding):
'--destroy-all-models']
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
self.__logger.info("%s\n%s", " ".join(cmd), output)
+ except subprocess.CalledProcessError as cpe:
+ self.__logger.error(
+ "Exception with Juju Cleanup: %s\n%s",
+ cpe.cmd, cpe.output)
except Exception: # pylint: disable=broad-except
- self.__logger.exception("Some issue during the undeployment ..")
+ self.__logger.exception("General issue during the undeployment ..")
if not self.orchestrator['requirements']['preserve_setup']:
self.__logger.info('Remove the Abot_epc OS object ..')
diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.py b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
index 6180e2c8f..b3b0ee4a9 100644
--- a/functest/opnfv_tests/vnf/ims/cloudify_ims.py
+++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
@@ -12,6 +12,7 @@
import logging
import os
import time
+import uuid
from cloudify_rest_client import CloudifyClient
from cloudify_rest_client.executions import Execution
@@ -25,6 +26,7 @@ from snaps.config.network import NetworkConfig, PortConfig, SubnetConfig
from snaps.config.router import RouterConfig
from snaps.config.security_group import (
Direction, Protocol, SecurityGroupConfig, SecurityGroupRuleConfig)
+from snaps.config.user import UserConfig
from snaps.config.vm_inst import FloatingIpConfig, VmInstanceConfig
from snaps.openstack.create_flavor import OpenStackFlavor
from snaps.openstack.create_image import OpenStackImage
@@ -33,6 +35,7 @@ from snaps.openstack.create_keypairs import OpenStackKeypair
from snaps.openstack.create_network import OpenStackNetwork
from snaps.openstack.create_router import OpenStackRouter
from snaps.openstack.create_security_group import OpenStackSecurityGroup
+from snaps.openstack.create_user import OpenStackUser
from snaps.openstack.utils import keystone_utils
from xtesting.energy import energy
@@ -112,19 +115,6 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase):
compute_quotas = self.os_project.update_compute_quotas(compute_quotas)
network_quotas = self.os_project.update_network_quotas(network_quotas)
- # needs some images
- self.__logger.info("Upload some OS images if it doesn't exist")
- for image_name, image_file in self.images.iteritems():
- self.__logger.info("image: %s, file: %s", image_name, image_file)
- if image_file and image_name:
- image_creator = OpenStackImage(
- self.snaps_creds,
- ImageConfig(
- name=image_name, image_user='cloud',
- img_format='qcow2', image_file=image_file))
- image_creator.create()
- self.created_object.append(image_creator)
-
def deploy_orchestrator(self):
# pylint: disable=too-many-locals,too-many-statements
"""
@@ -132,18 +122,59 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase):
network, security group, fip, VM creation
"""
- # network creation
-
start_time = time.time()
+
+ # orchestrator VM flavor
+ self.__logger.info("Get or create flavor for cloudify manager vm ...")
+ flavor_settings = FlavorConfig(
+ name="{}-{}".format(
+ self.orchestrator['requirements']['flavor']['name'],
+ self.uuid),
+ ram=self.orchestrator['requirements']['flavor']['ram_min'],
+ disk=50,
+ vcpus=2)
+ flavor_creator = OpenStackFlavor(self.snaps_creds, flavor_settings)
+ flavor_creator.create()
+ self.created_object.append(flavor_creator)
+
+ self.__logger.info("Creating a second user to bypass issues ...")
+ user_creator = OpenStackUser(
+ self.snaps_creds,
+ UserConfig(
+ name='cloudify_network_bug-{}'.format(self.uuid),
+ password=str(uuid.uuid4()),
+ project_name=self.tenant_name,
+ domain_name=self.snaps_creds.user_domain_name,
+ roles={'_member_': self.tenant_name}))
+ user_creator.create()
+ self.created_object.append(user_creator)
+
+ snaps_creds = user_creator.get_os_creds(self.snaps_creds.project_name)
+ self.__logger.debug("snaps creds: %s", snaps_creds)
+
self.__logger.info("Creating keypair ...")
kp_file = os.path.join(self.data_dir, "cloudify_ims.pem")
keypair_settings = KeypairConfig(
name='cloudify_ims_kp-{}'.format(self.uuid),
private_filepath=kp_file)
- keypair_creator = OpenStackKeypair(self.snaps_creds, keypair_settings)
+ keypair_creator = OpenStackKeypair(snaps_creds, keypair_settings)
keypair_creator.create()
self.created_object.append(keypair_creator)
+ # needs some images
+ self.__logger.info("Upload some OS images if it doesn't exist")
+ for image_name, image_file in self.images.iteritems():
+ self.__logger.info("image: %s, file: %s", image_name, image_file)
+ if image_file and image_name:
+ image_creator = OpenStackImage(
+ snaps_creds,
+ ImageConfig(
+ name=image_name, image_user='cloud',
+ img_format='qcow2', image_file=image_file))
+ image_creator.create()
+ self.created_object.append(image_creator)
+
+ # network creation
self.__logger.info("Creating full network ...")
subnet_settings = SubnetConfig(
name='cloudify_ims_subnet-{}'.format(self.uuid),
@@ -152,12 +183,12 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase):
network_settings = NetworkConfig(
name='cloudify_ims_network-{}'.format(self.uuid),
subnet_settings=[subnet_settings])
- network_creator = OpenStackNetwork(self.snaps_creds, network_settings)
+ network_creator = OpenStackNetwork(snaps_creds, network_settings)
network_creator.create()
self.created_object.append(network_creator)
- ext_net_name = snaps_utils.get_ext_net_name(self.snaps_creds)
+ ext_net_name = snaps_utils.get_ext_net_name(snaps_creds)
router_creator = OpenStackRouter(
- self.snaps_creds,
+ snaps_creds,
RouterConfig(
name='cloudify_ims_router-{}'.format(self.uuid),
external_gateway=ext_net_name,
@@ -178,36 +209,21 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase):
sec_grp_name="sg-cloudify-manager-{}".format(self.uuid),
direction=Direction.ingress, protocol=Protocol.udp,
port_range_min=1, port_range_max=65535))
-
security_group_creator = OpenStackSecurityGroup(
- self.snaps_creds,
+ snaps_creds,
SecurityGroupConfig(
name="sg-cloudify-manager-{}".format(self.uuid),
rule_settings=sg_rules))
-
security_group_creator.create()
self.created_object.append(security_group_creator)
- # orchestrator VM flavor
- self.__logger.info("Get or create flavor for cloudify manager vm ...")
-
- flavor_settings = FlavorConfig(
- name=self.orchestrator['requirements']['flavor']['name'],
- ram=self.orchestrator['requirements']['flavor']['ram_min'],
- disk=50,
- vcpus=2)
- flavor_creator = OpenStackFlavor(self.snaps_creds, flavor_settings)
- flavor_creator.create()
- self.created_object.append(flavor_creator)
image_settings = ImageConfig(
name=self.orchestrator['requirements']['os_image'],
image_user='centos',
exists=True)
-
port_settings = PortConfig(
name='cloudify_manager_port-{}'.format(self.uuid),
network_name=network_settings.name)
-
manager_settings = VmInstanceConfig(
name='cloudify_manager-{}'.format(self.uuid),
flavor=flavor_settings.name,
@@ -218,26 +234,23 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase):
name='cloudify_manager_fip-{}'.format(self.uuid),
port_name=port_settings.name,
router_name=router_creator.router_settings.name)])
-
manager_creator = OpenStackVmInstance(
- self.snaps_creds, manager_settings, image_settings,
+ snaps_creds, manager_settings, image_settings,
keypair_settings)
-
self.__logger.info("Creating cloudify manager VM")
manager_creator.create()
self.created_object.append(manager_creator)
- public_auth_url = keystone_utils.get_endpoint(
- self.snaps_creds, 'identity')
+ public_auth_url = keystone_utils.get_endpoint(snaps_creds, 'identity')
cfy_creds = dict(
- keystone_username=self.snaps_creds.username,
- keystone_password=self.snaps_creds.password,
- keystone_tenant_name=self.snaps_creds.project_name,
+ keystone_username=snaps_creds.username,
+ keystone_password=snaps_creds.password,
+ keystone_tenant_name=snaps_creds.project_name,
keystone_url=public_auth_url,
- region=self.snaps_creds.region_name,
- user_domain_name=self.snaps_creds.user_domain_name,
- project_domain_name=self.snaps_creds.project_domain_name)
+ region=snaps_creds.region_name,
+ user_domain_name=snaps_creds.user_domain_name,
+ project_domain_name=snaps_creds.project_domain_name)
self.__logger.info("Set creds for cloudify manager %s", cfy_creds)
cfy_client = CloudifyClient(
@@ -247,36 +260,35 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase):
self.orchestrator['object'] = cfy_client
self.__logger.info("Attemps running status of the Manager")
- cfy_status = None
- retry = 10
- while str(cfy_status) != 'running' and retry:
+ for loop in range(10):
try:
+ self.__logger.debug(
+ "status %s", cfy_client.manager.get_status())
cfy_status = cfy_client.manager.get_status()['status']
self.__logger.info(
"The current manager status is %s", cfy_status)
+ if str(cfy_status) != 'running':
+ raise Exception("Cloudify Manager isn't up and running")
+ self.__logger.info("Put OpenStack creds in manager")
+ secrets_list = cfy_client.secrets.list()
+ for k, val in cfy_creds.iteritems():
+ if not any(d.get('key', None) == k for d in secrets_list):
+ cfy_client.secrets.create(k, val)
+ else:
+ cfy_client.secrets.update(k, val)
+ break
except Exception: # pylint: disable=broad-except
- self.__logger.info(
- "Cloudify Manager isn't up and running. Retrying ...")
- retry = retry - 1
- time.sleep(30)
-
- if str(cfy_status) == 'running':
- self.__logger.info("Cloudify Manager is up and running")
+ self.logger.info(
+ "try %s: Cloudify Manager isn't up and running", loop + 1)
+ time.sleep(30)
else:
- raise Exception("Cloudify Manager isn't up and running")
-
- self.__logger.info("Put OpenStack creds in manager")
- secrets_list = cfy_client.secrets.list()
- for k, val in cfy_creds.iteritems():
- if not any(d.get('key', None) == k for d in secrets_list):
- cfy_client.secrets.create(k, val)
- else:
- cfy_client.secrets.update(k, val)
+ self.logger.error("Cloudify Manager isn't up and running")
+ return False
duration = time.time() - start_time
- self.__logger.info("Put private keypair in manager")
if manager_creator.vm_ssh_active(block=True):
+ self.__logger.info("Put private keypair in manager")
ssh = manager_creator.ssh_client()
scp = SCPClient(ssh.get_transport(), socket_timeout=15.0)
scp.put(kp_file, '~/')
@@ -287,6 +299,10 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase):
cmd = "sudo yum install -y gcc python-devel"
self.run_blocking_ssh_command(
ssh, cmd, "Unable to install packages on manager")
+ self.run_blocking_ssh_command(ssh, 'cfy status')
+ else:
+ self.__logger.error("Cannot connect to manager")
+ return False
self.details['orchestrator'].update(status='PASS', duration=duration)
@@ -305,22 +321,22 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase):
self.__logger.info("Upload VNFD")
cfy_client = self.orchestrator['object']
descriptor = self.vnf['descriptor']
- cfy_client.blueprints.publish_archive(descriptor.get('url'),
- descriptor.get('name'),
- descriptor.get('file_name'))
-
+ cfy_client.blueprints.upload(
+ descriptor.get('file_name'), descriptor.get('name'))
self.__logger.info("Get or create flavor for all clearwater vm")
flavor_settings = FlavorConfig(
- name=self.vnf['requirements']['flavor']['name'],
+ name="{}-{}".format(
+ self.vnf['requirements']['flavor']['name'],
+ self.uuid),
ram=self.vnf['requirements']['flavor']['ram_min'],
disk=25,
- vcpus=1)
+ vcpus=2)
flavor_creator = OpenStackFlavor(self.snaps_creds, flavor_settings)
flavor_creator.create()
self.created_object.append(flavor_creator)
self.vnf['inputs'].update(dict(
- flavor_id=self.vnf['requirements']['flavor']['name'],
+ flavor_id=flavor_settings.name,
))
self.__logger.info("Create VNF Instance")
@@ -338,7 +354,8 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase):
execution = cfy_client.executions.start(descriptor.get('name'),
'install')
# Show execution log
- execution = wait_for_execution(cfy_client, execution, self.__logger)
+ execution = wait_for_execution(
+ cfy_client, execution, self.__logger, timeout=3600)
duration = time.time() - start_time
@@ -458,7 +475,7 @@ def get_config(parameter, file_path):
return value
-def wait_for_execution(client, execution, logger, timeout=1500, ):
+def wait_for_execution(client, execution, logger, timeout=3600, ):
"""Wait for a workflow execution on Cloudify Manager."""
# if execution already ended - return without waiting
if execution.status in Execution.END_STATES:
@@ -478,7 +495,7 @@ def wait_for_execution(client, execution, logger, timeout=1500, ):
execution_id=execution.id,
_offset=offset,
_size=batch_size,
- include_logs=False,
+ include_logs=True,
sort='@timestamp').items
offset = offset + len(event_list)
diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml b/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml
index 4586dfd33..a40fcc6b3 100644
--- a/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml
+++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml
@@ -9,21 +9,19 @@ orchestrator:
version: '4.0'
requirements:
flavor:
- name: m1.medium
+ name: cloudify.medium
ram_min: 4096
os_image: 'cloudify_manager_4.0'
vnf:
name: clearwater
version: '107'
descriptor:
- file_name: openstack-blueprint.yaml
+ file_name: /src/vims/openstack-blueprint.yaml
name: clearwater-opnfv
- url:
- https://github.com/Orange-OpenSource/opnfv-cloudify-clearwater/archive/master.zip
version: '122'
requirements:
flavor:
- name: m1.small
+ name: cloudify.small
ram_min: 2048
compute_quotas:
cores: 50
@@ -34,7 +32,7 @@ vnf:
port: 50
inputs:
image_id: 'ubuntu_14.04'
- flavor_id: 'm1.small'
+ flavor_id: 'cloudify.small'
agent_user: ubuntu
key_pair_name: cloudify_ims_kp
private_key_path: '/etc/cloudify/cloudify_ims.pem'
diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims_perf.yaml b/functest/opnfv_tests/vnf/ims/cloudify_ims_perf.yaml
index 0e020cbe4..a6633dfc1 100644
--- a/functest/opnfv_tests/vnf/ims/cloudify_ims_perf.yaml
+++ b/functest/opnfv_tests/vnf/ims/cloudify_ims_perf.yaml
@@ -22,10 +22,8 @@ vnf:
name: clearwater
version: '107'
descriptor:
- file_name: openstack-blueprint-with-numbers.yaml
+ file_name: /src/vims/openstack-blueprint-with-numbers.yaml
name: clearwater-opnfv
- url:
- https://github.com/Orange-OpenSource/opnfv-cloudify-clearwater/archive/master.zip
version: '122'
requirements:
flavor:
diff --git a/functest/opnfv_tests/vnf/router/cloudify_vrouter.py b/functest/opnfv_tests/vnf/router/cloudify_vrouter.py
index 9f6327b78..11f30bf4d 100644
--- a/functest/opnfv_tests/vnf/router/cloudify_vrouter.py
+++ b/functest/opnfv_tests/vnf/router/cloudify_vrouter.py
@@ -27,8 +27,6 @@ from functest.utils import config
from functest.utils import env
from functest.utils import functest_utils
-from git import Repo
-
from snaps.config.flavor import FlavorConfig
from snaps.config.image import ImageConfig
from snaps.config.keypair import KeypairConfig
@@ -136,17 +134,6 @@ class CloudifyVrouter(vrouter_base.VrouterOnBoardingBase):
super(CloudifyVrouter, self).prepare()
self.__logger.info("Additional pre-configuration steps")
self.util.set_credentials(self.snaps_creds)
- self.__logger.info("Upload some OS images if it doesn't exist")
- for image_name, image_file in self.images.iteritems():
- self.__logger.info("image: %s, file: %s", image_name, image_file)
- if image_file and image_name:
- image_creator = OpenStackImage(
- self.snaps_creds,
- ImageConfig(
- name=image_name, image_user='cloud',
- img_format='qcow2', image_file=image_file))
- image_creator.create()
- self.created_object.append(image_creator)
def deploy_orchestrator(self):
# pylint: disable=too-many-locals,too-many-statements
@@ -156,15 +143,54 @@ class CloudifyVrouter(vrouter_base.VrouterOnBoardingBase):
"""
# network creation
start_time = time.time()
+
+ # orchestrator VM flavor
+ self.__logger.info("Get or create flavor for cloudify manager vm ...")
+ flavor_settings = FlavorConfig(
+ name="{}-{}".format(
+ self.orchestrator['requirements']['flavor']['name'],
+ self.uuid),
+ ram=self.orchestrator['requirements']['flavor']['ram_min'],
+ disk=50, vcpus=2)
+ flavor_creator = OpenStackFlavor(self.snaps_creds, flavor_settings)
+ flavor_creator.create()
+ self.created_object.append(flavor_creator)
+
+ user_creator = OpenStackUser(
+ self.snaps_creds,
+ UserConfig(
+ name='cloudify_network_bug-{}'.format(self.uuid),
+ password=str(uuid.uuid4()),
+ project_name=self.tenant_name,
+ domain_name=self.snaps_creds.user_domain_name,
+ roles={'_member_': self.tenant_name}))
+ user_creator.create()
+ self.created_object.append(user_creator)
+
+ snaps_creds = user_creator.get_os_creds(self.snaps_creds.project_name)
+ self.__logger.debug("snaps creds: %s", snaps_creds)
+
self.__logger.info("Creating keypair ...")
kp_file = os.path.join(self.data_dir, "cloudify_vrouter.pem")
keypair_settings = KeypairConfig(
name='cloudify_vrouter_kp-{}'.format(self.uuid),
private_filepath=kp_file)
- keypair_creator = OpenStackKeypair(self.snaps_creds, keypair_settings)
+ keypair_creator = OpenStackKeypair(snaps_creds, keypair_settings)
keypair_creator.create()
self.created_object.append(keypair_creator)
+ self.__logger.info("Upload some OS images if it doesn't exist")
+ for image_name, image_file in self.images.iteritems():
+ self.__logger.info("image: %s, file: %s", image_name, image_file)
+ if image_file and image_name:
+ image_creator = OpenStackImage(
+ snaps_creds,
+ ImageConfig(
+ name=image_name, image_user='cloud',
+ img_format='qcow2', image_file=image_file))
+ image_creator.create()
+ self.created_object.append(image_creator)
+
self.__logger.info("Creating full network ...")
subnet_settings = SubnetConfig(
name='cloudify_vrouter_subnet-{}'.format(self.uuid),
@@ -173,12 +199,12 @@ class CloudifyVrouter(vrouter_base.VrouterOnBoardingBase):
network_settings = NetworkConfig(
name='cloudify_vrouter_network-{}'.format(self.uuid),
subnet_settings=[subnet_settings])
- network_creator = OpenStackNetwork(self.snaps_creds, network_settings)
+ network_creator = OpenStackNetwork(snaps_creds, network_settings)
network_creator.create()
self.created_object.append(network_creator)
- ext_net_name = snaps_utils.get_ext_net_name(self.snaps_creds)
+ ext_net_name = snaps_utils.get_ext_net_name(snaps_creds)
router_creator = OpenStackRouter(
- self.snaps_creds,
+ snaps_creds,
RouterConfig(
name='cloudify_vrouter_router-{}'.format(self.uuid),
external_gateway=ext_net_name,
@@ -201,34 +227,20 @@ class CloudifyVrouter(vrouter_base.VrouterOnBoardingBase):
direction=Direction.ingress,
protocol=Protocol.udp, port_range_min=1,
port_range_max=65535))
-
security_group_creator = OpenStackSecurityGroup(
- self.snaps_creds,
+ snaps_creds,
SecurityGroupConfig(
name="sg-cloudify-manager-{}".format(self.uuid),
rule_settings=sg_rules))
-
security_group_creator.create()
self.created_object.append(security_group_creator)
- # orchestrator VM flavor
- self.__logger.info("Get or create flavor for cloudify manager vm ...")
-
- flavor_settings = FlavorConfig(
- name=self.orchestrator['requirements']['flavor']['name'],
- ram=self.orchestrator['requirements']['flavor']['ram_min'],
- disk=50, vcpus=2)
- flavor_creator = OpenStackFlavor(self.snaps_creds, flavor_settings)
- flavor_creator.create()
- self.created_object.append(flavor_creator)
image_settings = ImageConfig(
name=self.orchestrator['requirements']['os_image'],
image_user='centos', exists=True)
-
port_settings = PortConfig(
name='cloudify_manager_port-{}'.format(self.uuid),
network_name=network_settings.name)
-
manager_settings = VmInstanceConfig(
name='cloudify_manager-{}'.format(self.uuid),
flavor=flavor_settings.name,
@@ -239,9 +251,8 @@ class CloudifyVrouter(vrouter_base.VrouterOnBoardingBase):
name='cloudify_manager_fip-{}'.format(self.uuid),
port_name=port_settings.name,
router_name=router_creator.router_settings.name)])
-
manager_creator = OpenStackVmInstance(
- self.snaps_creds, manager_settings, image_settings,
+ snaps_creds, manager_settings, image_settings,
keypair_settings)
self.__logger.info("Creating cloudify manager VM")
@@ -257,23 +268,23 @@ class CloudifyVrouter(vrouter_base.VrouterOnBoardingBase):
self.cfy_manager_ip = manager_creator.get_floating_ip().ip
self.__logger.info("Attemps running status of the Manager")
- cfy_status = None
- retry = 10
- while str(cfy_status) != 'running' and retry:
+ for loop in range(10):
try:
+ self.__logger.debug(
+ "status %s", cfy_client.manager.get_status())
cfy_status = cfy_client.manager.get_status()['status']
self.__logger.info(
"The current manager status is %s", cfy_status)
+ if str(cfy_status) != 'running':
+ raise Exception("Cloudify Manager isn't up and running")
+ break
except Exception: # pylint: disable=broad-except
- self.__logger.info(
- "Cloudify Manager isn't up and running. Retrying ...")
- retry = retry - 1
- time.sleep(30)
-
- if str(cfy_status) == 'running':
- self.__logger.info("Cloudify Manager is up and running")
+ self.logger.info(
+ "try %s: Cloudify Manager isn't up and running", loop + 1)
+ time.sleep(30)
else:
- raise Exception("Cloudify Manager isn't up and running")
+ self.logger.error("Cloudify Manager isn't up and running")
+ return False
duration = time.time() - start_time
@@ -289,35 +300,17 @@ class CloudifyVrouter(vrouter_base.VrouterOnBoardingBase):
cmd = "sudo yum install -y gcc python-devel"
self.run_blocking_ssh_command(
ssh, cmd, "Unable to install packages on manager")
+ else:
+ self.__logger.error("Cannot connect to manager")
+ return False
self.details['orchestrator'].update(status='PASS', duration=duration)
- self.vnf['inputs'].update(dict(external_network_name=ext_net_name))
-
- return True
-
- def deploy_vnf(self):
- start_time = time.time()
-
- self.__logger.info("Upload VNFD")
- cfy_client = self.orchestrator['object']
- descriptor = self.vnf['descriptor']
- self.deployment_name = descriptor.get('name')
-
- vrouter_blueprint_dir = os.path.join(
- self.data_dir, self.util.blueprint_dir)
- if not os.path.exists(vrouter_blueprint_dir):
- Repo.clone_from(
- descriptor.get('url'), vrouter_blueprint_dir,
- branch=descriptor.get('version'))
-
- cfy_client.blueprints.upload(
- vrouter_blueprint_dir + self.util.blueprint_file_name,
- descriptor.get('name'))
-
self.__logger.info("Get or create flavor for vrouter")
flavor_settings = FlavorConfig(
- name=self.vnf['requirements']['flavor']['name'],
+ name="{}-{}".format(
+ self.vnf['requirements']['flavor']['name'],
+ self.uuid),
ram=self.vnf['requirements']['flavor']['ram_min'],
disk=25, vcpus=1)
flavor_creator = OpenStackFlavor(self.snaps_creds, flavor_settings)
@@ -325,22 +318,9 @@ class CloudifyVrouter(vrouter_base.VrouterOnBoardingBase):
self.created_object.append(flavor_creator)
# set image name
- glance = glance_utils.glance_client(self.snaps_creds)
+ glance = glance_utils.glance_client(snaps_creds)
image = glance_utils.get_image(glance, "vyos1.1.7")
-
- user_creator = OpenStackUser(
- self.snaps_creds,
- UserConfig(
- name='cloudify_network_bug-{}'.format(self.uuid),
- password=str(uuid.uuid4()),
- project_name=self.tenant_name,
- domain=self.snaps_creds.user_domain_name,
- roles={'_member_': self.tenant_name}))
- user_creator.create()
- self.created_object.append(user_creator)
- snaps_creds = user_creator.get_os_creds(self.snaps_creds.project_name)
- self.__logger.debug("snaps creds: %s", snaps_creds)
-
+ self.vnf['inputs'].update(dict(external_network_name=ext_net_name))
self.vnf['inputs'].update(dict(target_vnf_image_id=image.id))
self.vnf['inputs'].update(dict(reference_vnf_image_id=image.id))
self.vnf['inputs'].update(dict(target_vnf_flavor_id=flavor.id))
@@ -361,6 +341,24 @@ class CloudifyVrouter(vrouter_base.VrouterOnBoardingBase):
keystone_url=keystone_utils.get_endpoint(
snaps_creds, 'identity')))
+ credentials = {"snaps_creds": snaps_creds}
+ self.util_info = {"credentials": credentials,
+ "cfy": cfy_client,
+ "vnf_data_dir": self.util.vnf_data_dir}
+
+ return True
+
+ def deploy_vnf(self):
+ start_time = time.time()
+
+ self.__logger.info("Upload VNFD")
+ cfy_client = self.orchestrator['object']
+ descriptor = self.vnf['descriptor']
+ self.deployment_name = descriptor.get('name')
+
+ cfy_client.blueprints.upload(
+ descriptor.get('file_name'), descriptor.get('name'))
+
self.__logger.info("Create VNF Instance")
cfy_client.deployments.create(
descriptor.get('name'), descriptor.get('name'),
@@ -388,19 +386,9 @@ class CloudifyVrouter(vrouter_base.VrouterOnBoardingBase):
return result
def test_vnf(self):
- cfy_client = self.orchestrator['object']
- credentials = {"snaps_creds": self.snaps_creds}
-
- self.util_info = {"credentials": credentials,
- "cfy": cfy_client,
- "vnf_data_dir": self.util.vnf_data_dir}
-
start_time = time.time()
-
result, test_result_data = super(CloudifyVrouter, self).test_vnf()
-
duration = time.time() - start_time
-
if result:
self.details['test_vnf'].update(
status='PASS', result='OK', full_result=test_result_data,
@@ -409,7 +397,6 @@ class CloudifyVrouter(vrouter_base.VrouterOnBoardingBase):
self.details['test_vnf'].update(
status='FAIL', result='NG', full_result=test_result_data,
duration=duration)
-
return True
def clean(self):
@@ -461,7 +448,7 @@ def wait_for_execution(client, execution, logger, timeout=7200, ):
while True:
event_list = client.events.list(
execution_id=execution.id, _offset=offset, _size=batch_size,
- include_logs=False, sort='@timestamp').items
+ include_logs=True, sort='@timestamp').items
offset = offset + len(event_list)
for event in event_list:
diff --git a/functest/opnfv_tests/vnf/router/cloudify_vrouter.yaml b/functest/opnfv_tests/vnf/router/cloudify_vrouter.yaml
index 58bdb66a3..649cd6ccd 100644
--- a/functest/opnfv_tests/vnf/router/cloudify_vrouter.yaml
+++ b/functest/opnfv_tests/vnf/router/cloudify_vrouter.yaml
@@ -5,25 +5,26 @@ tenant_images:
vyos1.1.7: /home/opnfv/functest/images/vyos-1.1.7.img
test_data:
url: 'https://github.com/oolorg/opnfv-vnf-data.git'
- branch: 'master'
+ branch: 'fraser'
orchestrator:
name: cloudify
version: '4.0'
requirements:
flavor:
- name: m1.medium
+ name: cloudify.medium
ram_min: 4096
os_image: 'cloudify_manager_4.0'
vnf:
name: vyos1.1.7
version: '1.1.7'
descriptor:
- url: https://github.com/oolorg/opnfv-vnf-vyos-blueprint/
+ file_name:
+ /src/opnfv-vnf-vyos-blueprint/function-test-openstack-blueprint.yaml
name: vrouter-opnfv
- version: 'master'
+ version: fraser
requirements:
flavor:
- name: m1.medium
+ name: cloudify.medium
ram_min: 2048
inputs:
external_network_name: admin_floating_net
diff --git a/functest/tests/unit/odl/test_odl.py b/functest/tests/unit/odl/test_odl.py
index 6304d37a3..d1dfea8a7 100644
--- a/functest/tests/unit/odl/test_odl.py
+++ b/functest/tests/unit/odl/test_odl.py
@@ -14,6 +14,7 @@ import os
import unittest
import mock
+import munch
from robot.errors import RobotError
import six
from six.moves import urllib
@@ -33,6 +34,7 @@ class ODLTesting(unittest.TestCase):
_keystone_ip = "127.0.0.1"
_neutron_url = u"https://127.0.0.1:9696"
+ _neutron_id = u"dummy"
_sdn_controller_ip = "127.0.0.3"
_os_auth_url = "http://{}:5000/v3".format(_keystone_ip)
_os_projectname = "admin"
@@ -44,6 +46,7 @@ class ODLTesting(unittest.TestCase):
_odl_password = "admin"
_os_userdomainname = 'Default'
_os_projectdomainname = 'Default'
+ _os_interface = "public"
def setUp(self):
for var in ("INSTALLER_TYPE", "SDN_CONTROLLER", "SDN_CONTROLLER_IP"):
@@ -56,6 +59,7 @@ class ODLTesting(unittest.TestCase):
os.environ["OS_PROJECT_NAME"] = self._os_projectname
os.environ["OS_PROJECT_DOMAIN_NAME"] = self._os_projectdomainname
os.environ["OS_PASSWORD"] = self._os_password
+ os.environ["OS_INTERFACE"] = self._os_interface
self.test = odl.ODLTests(case_name='odl', project_name='functest')
self.defaultargs = {'odlusername': self._odl_username,
'odlpassword': self._odl_password,
@@ -265,35 +269,98 @@ class ODLMainTesting(ODLTesting):
class ODLRunTesting(ODLTesting):
-
"""The class testing ODLTests.run()."""
- # pylint: disable=missing-docstring
+ # pylint: disable=too-many-public-methods,missing-docstring
+
+ @mock.patch('os_client_config.make_shade', side_effect=Exception)
+ def test_no_cloud(self, *args):
+ self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
+ args[0].assert_called_once_with()
+
+ @mock.patch('os_client_config.make_shade')
+ def test_no_service1(self, *args):
+ args[0].return_value.search_services.return_value = None
+ self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
+ args[0].return_value.search_services.assert_called_once_with('neutron')
+ args[0].return_value.search_endpoints.assert_not_called()
+
+ @mock.patch('os_client_config.make_shade')
+ def test_no_service2(self, *args):
+ args[0].return_value.search_services.return_value = []
+ self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
+ args[0].return_value.search_services.assert_called_once_with('neutron')
+ args[0].return_value.search_endpoints.assert_not_called()
- @mock.patch('snaps.openstack.utils.keystone_utils.get_endpoint',
- return_value=ODLTesting._neutron_url)
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.'
- 'get_credentials')
+ @mock.patch('os_client_config.make_shade')
+ def test_no_service3(self, *args):
+ args[0].return_value.search_services.return_value = [
+ munch.Munch()]
+ self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
+ args[0].return_value.search_services.assert_called_once_with('neutron')
+ args[0].return_value.search_endpoints.assert_not_called()
+
+ @mock.patch('os_client_config.make_shade')
+ def test_no_endpoint1(self, *args):
+ args[0].return_value.search_services.return_value = [
+ munch.Munch(id=self._neutron_id)]
+ args[0].return_value.search_endpoints.return_value = None
+ self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
+ args[0].return_value.search_services.assert_called_once_with('neutron')
+ args[0].return_value.search_endpoints.assert_called_once_with(
+ filters={'interface': self._os_interface,
+ 'service_id': self._neutron_id})
+
+ @mock.patch('os_client_config.make_shade')
+ def test_no_endpoint2(self, *args):
+ args[0].return_value.search_services.return_value = [
+ munch.Munch(id=self._neutron_id)]
+ args[0].return_value.search_endpoints.return_value = []
+ self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
+ args[0].return_value.search_services.assert_called_once_with('neutron')
+ args[0].return_value.search_endpoints.assert_called_once_with(
+ filters={'interface': self._os_interface,
+ 'service_id': self._neutron_id})
+
+ @mock.patch('os_client_config.make_shade')
+ def test_no_endpoint3(self, *args):
+ args[0].return_value.search_services.return_value = [
+ munch.Munch(id=self._neutron_id)]
+ args[0].return_value.search_endpoints.return_value = [munch.Munch()]
+ self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
+ args[0].return_value.search_services.assert_called_once_with('neutron')
+ args[0].return_value.search_endpoints.assert_called_once_with(
+ filters={'interface': self._os_interface,
+ 'service_id': self._neutron_id})
+
+ @mock.patch('os_client_config.make_shade')
+ def test_endpoint_interface(self, *args):
+ args[0].return_value.search_services.return_value = [
+ munch.Munch(id=self._neutron_id)]
+ args[0].return_value.search_endpoints.return_value = [munch.Munch()]
+ self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
+ args[0].return_value.search_services.assert_called_once_with('neutron')
+ args[0].return_value.search_endpoints.assert_called_once_with(
+ filters={'interface': self._os_interface,
+ 'service_id': self._neutron_id})
+
+ @mock.patch('os_client_config.make_shade')
def _test_no_env_var(self, var, *args):
del os.environ[var]
self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
args[0].assert_called_once_with()
- args[1].assert_called_once_with(mock.ANY, 'network')
- @mock.patch('snaps.openstack.utils.keystone_utils.get_endpoint',
- return_value=ODLTesting._neutron_url)
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.'
- 'get_credentials')
+ @mock.patch('os_client_config.make_shade')
def _test_missing_value(self, *args):
self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
args[0].assert_called_once_with()
- args[1].assert_called_once_with(mock.ANY, 'network')
- @mock.patch('snaps.openstack.utils.keystone_utils.get_endpoint',
- return_value=ODLTesting._neutron_url)
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.'
- 'get_credentials')
+ @mock.patch('os_client_config.make_shade')
def _test_run(self, status=testcase.TestCase.EX_OK,
exception=None, *args, **kwargs):
+ args[0].return_value.search_services.return_value = [
+ munch.Munch(id=self._neutron_id)]
+ args[0].return_value.search_endpoints.return_value = [
+ munch.Munch(url=self._neutron_url)]
odlip = kwargs['odlip'] if 'odlip' in kwargs else '127.0.0.3'
odlwebport = kwargs['odlwebport'] if 'odlwebport' in kwargs else '8080'
odlrestconfport = (kwargs['odlrestconfport']
@@ -313,14 +380,18 @@ class ODLRunTesting(ODLTesting):
osprojectdomainname=self._os_projectdomainname,
osuserdomainname=self._os_userdomainname)
args[0].assert_called_once_with()
- args[1].assert_called_once_with(mock.ANY, 'network')
+ args[0].return_value.search_services.assert_called_once_with('neutron')
+ args[0].return_value.search_endpoints.assert_called_once_with(
+ filters={'interface': os.environ.get("OS_INTERFACE", "public"),
+ 'service_id': self._neutron_id})
- @mock.patch('snaps.openstack.utils.keystone_utils.get_endpoint',
- return_value=ODLTesting._neutron_url)
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.'
- 'get_credentials')
+ @mock.patch('os_client_config.make_shade')
def _test_multiple_suites(self, suites,
status=testcase.TestCase.EX_OK, *args, **kwargs):
+ args[0].return_value.search_endpoints.return_value = [
+ munch.Munch(url=self._neutron_url)]
+ args[0].return_value.search_services.return_value = [
+ munch.Munch(id=self._neutron_id)]
odlip = kwargs['odlip'] if 'odlip' in kwargs else '127.0.0.3'
odlwebport = kwargs['odlwebport'] if 'odlwebport' in kwargs else '8080'
odlrestconfport = (kwargs['odlrestconfport']
@@ -336,10 +407,13 @@ class ODLRunTesting(ODLTesting):
osprojectdomainname=self._os_projectdomainname,
osuserdomainname=self._os_userdomainname)
args[0].assert_called_once_with()
- args[1].assert_called_once_with(mock.ANY, 'network')
+ args[0].return_value.search_services.assert_called_once_with('neutron')
+ args[0].return_value.search_endpoints.assert_called_once_with(
+ filters={'interface': os.environ.get("OS_INTERFACE", "public"),
+ 'service_id': self._neutron_id})
def test_exc(self):
- with mock.patch('snaps.openstack.utils.keystone_utils.get_endpoint',
+ with mock.patch('os_client_config.make_shade',
side_effect=Exception()):
self.assertEqual(self.test.run(),
testcase.TestCase.EX_RUN_ERROR)
@@ -379,6 +453,34 @@ class ODLRunTesting(ODLTesting):
odlip=self._sdn_controller_ip,
odlwebport=self._odl_webport)
+ def test_without_os_interface(self):
+ del os.environ["OS_INTERFACE"]
+ os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
+ self._test_run(testcase.TestCase.EX_OK, None,
+ odlip=self._sdn_controller_ip,
+ odlwebport=self._odl_webport)
+
+ def test_os_interface_public(self):
+ os.environ["OS_INTERFACE"] = "public"
+ os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
+ self._test_run(testcase.TestCase.EX_OK, None,
+ odlip=self._sdn_controller_ip,
+ odlwebport=self._odl_webport)
+
+ def test_os_interface_internal(self):
+ os.environ["OS_INTERFACE"] = "internal"
+ os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
+ self._test_run(testcase.TestCase.EX_OK, None,
+ odlip=self._sdn_controller_ip,
+ odlwebport=self._odl_webport)
+
+ def test_os_interface_admin(self):
+ os.environ["OS_INTERFACE"] = "admin"
+ os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
+ self._test_run(testcase.TestCase.EX_OK, None,
+ odlip=self._sdn_controller_ip,
+ odlwebport=self._odl_webport)
+
def test_suites(self):
os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
self._test_multiple_suites(
diff --git a/functest/tests/unit/openstack/rally/test_rally.py b/functest/tests/unit/openstack/rally/test_rally.py
index 970e5c4f4..3ef90c44e 100644
--- a/functest/tests/unit/openstack/rally/test_rally.py
+++ b/functest/tests/unit/openstack/rally/test_rally.py
@@ -85,15 +85,16 @@ class OSRallyTesting(unittest.TestCase):
None)
def test_task_succeed_fail(self):
- json_raw = json.dumps([None])
+ json_raw = json.dumps({})
self.assertEqual(self.rally_base.task_succeed(json_raw),
False)
- json_raw = json.dumps([{'result': [{'error': ['test_error']}]}])
+ json_raw = json.dumps({'tasks': [{'status': 'crashed'}]})
self.assertEqual(self.rally_base.task_succeed(json_raw),
False)
def test_task_succeed_success(self):
- json_raw = json.dumps('')
+ json_raw = json.dumps({'tasks': [{'status': 'finished',
+ 'pass_sla': True}]})
self.assertEqual(self.rally_base.task_succeed(json_raw),
True)
@@ -214,8 +215,6 @@ class OSRallyTesting(unittest.TestCase):
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'_build_task_args', return_value={})
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
- '_append_summary')
- @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'get_task_id', return_value=None)
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'get_cmd_output', return_value='')
@@ -225,7 +224,8 @@ class OSRallyTesting(unittest.TestCase):
@mock.patch('functest.opnfv_tests.openstack.rally.rally.LOGGER.error')
def test_run_task_taskid_missing(self, mock_logger_error, *args):
# pylint: disable=unused-argument
- self.rally_base._run_task('test_name')
+ with self.assertRaises(Exception):
+ self.rally_base._run_task('test_name')
text = 'Failed to retrieve task_id, validating task...'
mock_logger_error.assert_any_call(text)
@@ -237,8 +237,6 @@ class OSRallyTesting(unittest.TestCase):
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'_build_task_args', return_value={})
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
- '_append_summary')
- @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'get_task_id', return_value='1')
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'get_cmd_output', return_value='')
@@ -250,13 +248,30 @@ class OSRallyTesting(unittest.TestCase):
@mock.patch('functest.opnfv_tests.openstack.rally.rally.os.makedirs')
@mock.patch('functest.opnfv_tests.openstack.rally.rally.LOGGER.info')
@mock.patch('functest.opnfv_tests.openstack.rally.rally.LOGGER.error')
- def test_run_task_default(self, mock_logger_error, mock_logger_info,
- *args):
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
+ '_save_results')
+ def test_run_task_default(self, mock_save_res, *args):
# pylint: disable=unused-argument
self.rally_base._run_task('test_name')
- text = 'Test scenario: "test_name" OK.\n'
- mock_logger_info.assert_any_call(text)
- mock_logger_error.assert_not_called()
+ mock_save_res.assert_called()
+
+ @mock.patch('__builtin__.open', mock.mock_open())
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
+ 'task_succeed', return_value=True)
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
+ 'get_cmd_output', return_value='')
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.os.path.exists',
+ return_value=True)
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.subprocess.Popen')
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.os.makedirs')
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.LOGGER.info')
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.LOGGER.debug')
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
+ '_append_summary')
+ def test_save_results(self, mock_summary, *args):
+ # pylint: disable=unused-argument
+ self.rally_base._save_results('test_name', '1234')
+ mock_summary.assert_called()
def test_prepare_env_testname_invalid(self):
self.rally_base.TESTS = ['test1', 'test2']
@@ -473,15 +488,31 @@ class OSRallyTesting(unittest.TestCase):
mock_prep_env.assert_called()
def test_append_summary(self):
- text = '[{"result":[{"error":[]},{"error":["err"]}],' \
- '"full_duration": 17.312026}]'
+ text = '{"tasks": [{"subtasks": [{"workloads": [{"full_duration": ' \
+ '1.23,"data": [{"error": []}]}]},{"workloads": ' \
+ '[{"full_duration": 2.78, "data": [{"error": ["err"]}]}]}]}]}'
self.rally_base._append_summary(text, "foo_test")
self.assertEqual(self.rally_base.summary[0]['test_name'], "foo_test")
- self.assertEqual(self.rally_base.summary[0]['overall_duration'],
- 17.312026)
+ self.assertEqual(self.rally_base.summary[0]['overall_duration'], 4.01)
self.assertEqual(self.rally_base.summary[0]['nb_tests'], 2)
self.assertEqual(self.rally_base.summary[0]['nb_success'], 1)
+ def test_is_successful_false(self):
+ with mock.patch('__builtin__.super') as mock_super:
+ self.rally_base.summary = [{"task_status": True},
+ {"task_status": False}]
+ self.assertEqual(self.rally_base.is_successful(),
+ testcase.TestCase.EX_TESTCASE_FAILED)
+ mock_super(rally.RallyBase, self).is_successful.assert_not_called()
+
+ def test_is_successful_true(self):
+ with mock.patch('__builtin__.super') as mock_super:
+ mock_super(rally.RallyBase, self).is_successful.return_value = 424
+ self.rally_base.summary = [{"task_status": True},
+ {"task_status": True}]
+ self.assertEqual(self.rally_base.is_successful(), 424)
+ mock_super(rally.RallyBase, self).is_successful.assert_called()
+
if __name__ == "__main__":
logging.disable(logging.CRITICAL)