diff options
31 files changed, 605 insertions, 41 deletions
@@ -9,7 +9,7 @@ docker/healthcheck \ docker/smoke \ docker/features \ docker/components \ -docker/vnf \ +docker/vnf \ docker/parser \ docker/restapi" diff --git a/docker/parser/testcases.yaml b/docker/parser/testcases.yaml index 4ab3fae2..45ccb0be 100644 --- a/docker/parser/testcases.yaml +++ b/docker/parser/testcases.yaml @@ -9,14 +9,13 @@ tiers: testcases: - case_name: parser-basics - enabled: false project_name: parser criteria: 100 blocking: false description: >- Test suite from Parser project. dependencies: - installer: 'fuel' + installer: '' scenario: '^((?!bgpvpn|noha).)*$' run: module: 'functest.core.feature' diff --git a/docker/vnf/testcases.yaml b/docker/vnf/testcases.yaml index c0eba822..64c0024e 100644 --- a/docker/vnf/testcases.yaml +++ b/docker/vnf/testcases.yaml @@ -56,7 +56,7 @@ tiers: description: >- This test case is vRouter testing. dependencies: - installer: 'fuel' + installer: '' scenario: 'nosdn-nofeature' run: module: 'functest.opnfv_tests.vnf.router.cloudify_vrouter' diff --git a/functest/api/resources/v1/creds.py b/functest/api/resources/v1/creds.py index 45e4559f..f445017d 100644 --- a/functest/api/resources/v1/creds.py +++ b/functest/api/resources/v1/creds.py @@ -13,8 +13,11 @@ Resources to handle openstack related requests import collections import logging +import pkg_resources +import socket from flask import jsonify +from flasgger.utils import swag_from from functest.api.base import ApiResource from functest.api.common import api_utils @@ -24,16 +27,26 @@ from functest.utils.constants import CONST LOGGER = logging.getLogger(__name__) +ADDRESS = socket.gethostbyname(socket.gethostname()) +ENDPOINT_CREDS = ('http://{}:5000/api/v1/functest/openstack'.format(ADDRESS)) + class V1Creds(ApiResource): """ V1Creds Resource class""" + @swag_from( + pkg_resources.resource_filename('functest', 'api/swagger/creds.yaml'), + endpoint='{0}/credentials'.format(ENDPOINT_CREDS)) def get(self): # pylint: disable=no-self-use """ Get credentials """ os_utils.source_credentials(CONST.__getattribute__('openstack_creds')) credentials_show = OpenStack.show_credentials() return jsonify(credentials_show) + @swag_from( + pkg_resources.resource_filename('functest', + 'api/swagger/creds_action.yaml'), + endpoint='{0}/action'.format(ENDPOINT_CREDS)) def post(self): """ Used to handle post request """ return self._dispatch_post() diff --git a/functest/api/resources/v1/envs.py b/functest/api/resources/v1/envs.py index 8020544f..65e61c4b 100644 --- a/functest/api/resources/v1/envs.py +++ b/functest/api/resources/v1/envs.py @@ -10,23 +10,37 @@ Resources to handle environment related requests """ +import pkg_resources +import socket + import IPy from flask import jsonify +from flasgger.utils import swag_from from functest.api.base import ApiResource from functest.api.common import api_utils from functest.cli.commands.cli_env import Env import functest.utils.functest_utils as ft_utils +ADDRESS = socket.gethostbyname(socket.gethostname()) +ENDPOINT_ENVS = ('http://{}:5000/api/v1/functest/envs'.format(ADDRESS)) + class V1Envs(ApiResource): """ V1Envs Resource class""" + @swag_from( + pkg_resources.resource_filename('functest', 'api/swagger/envs.yaml'), + endpoint=ENDPOINT_ENVS) def get(self): # pylint: disable=no-self-use """ Get environment """ environment_show = Env().show() return jsonify(environment_show) + @swag_from( + pkg_resources.resource_filename('functest', + 'api/swagger/envs_action.yaml'), + endpoint='{0}/action'.format(ENDPOINT_ENVS)) def post(self): """ Used to handle post request """ return self._dispatch_post() diff --git a/functest/api/resources/v1/tasks.py b/functest/api/resources/v1/tasks.py index 49214124..6bf625a8 100644 --- a/functest/api/resources/v1/tasks.py +++ b/functest/api/resources/v1/tasks.py @@ -15,9 +15,11 @@ import errno import json import logging import os +import pkg_resources import uuid from flask import jsonify +from flasgger.utils import swag_from from functest.api.base import ApiResource from functest.api.common import api_utils @@ -31,6 +33,8 @@ LOGGER = logging.getLogger(__name__) class V1Task(ApiResource): """ V1Task Resource class""" + @swag_from(pkg_resources.resource_filename( + 'functest', 'api/swagger/task.yaml')) def get(self, task_id): # pylint: disable=no-self-use """ GET the result of the task id """ try: @@ -66,6 +70,8 @@ class V1Task(ApiResource): class V1TaskLog(ApiResource): """ V1TaskLog Resource class""" + @swag_from(pkg_resources.resource_filename( + 'functest', 'api/swagger/task_log.yaml')) def get(self, task_id): # pylint: disable=no-self-use """ GET the log of the task id """ try: diff --git a/functest/api/resources/v1/testcases.py b/functest/api/resources/v1/testcases.py index cc2d4e19..7cc70bbc 100644 --- a/functest/api/resources/v1/testcases.py +++ b/functest/api/resources/v1/testcases.py @@ -13,11 +13,14 @@ Resources to handle testcase related requests import logging import os +import re import pkg_resources +import socket import uuid import ConfigParser from flask import jsonify +from flasgger.utils import swag_from from functest.api.base import ApiResource from functest.api.common import api_utils, thread @@ -28,20 +31,30 @@ import functest.utils.functest_utils as ft_utils LOGGER = logging.getLogger(__name__) +ADDRESS = socket.gethostbyname(socket.gethostname()) +ENDPOINT_TESTCASES = ('http://{}:5000/api/v1/functest/testcases' + .format(ADDRESS)) + class V1Testcases(ApiResource): """ V1Testcases Resource class""" + @swag_from(pkg_resources.resource_filename( + 'functest', 'api/swagger/testcases.yaml')) def get(self): # pylint: disable=no-self-use """ GET all testcases """ testcases_list = Testcase().list() - result = {'testcases': testcases_list.split('\n')[:-1]} + result = {'testcases': re.split(' |\n ', testcases_list)[1:]} return jsonify(result) class V1Testcase(ApiResource): """ V1Testcase Resource class""" + @swag_from( + pkg_resources.resource_filename('functest', + 'api/swagger/testcase.yaml'), + endpoint='{0}/<testcase_name>'.format(ENDPOINT_TESTCASES)) def get(self, testcase_name): # pylint: disable=no-self-use """ GET the info of one testcase""" testcase = Testcase().show(testcase_name) @@ -61,6 +74,10 @@ class V1Testcase(ApiResource): result.update({'dependency': dependency_dict}) return jsonify(result) + @swag_from( + pkg_resources.resource_filename('functest', + 'api/swagger/testcase_run.yaml'), + endpoint='{0}/action'.format(ENDPOINT_TESTCASES)) def post(self): """ Used to handle post request """ return self._dispatch_post() diff --git a/functest/api/resources/v1/tiers.py b/functest/api/resources/v1/tiers.py index b58ab205..523df130 100644 --- a/functest/api/resources/v1/tiers.py +++ b/functest/api/resources/v1/tiers.py @@ -11,9 +11,11 @@ Resources to handle tier related requests """ +import pkg_resources import re from flask import jsonify +from flasgger.utils import swag_from from functest.api.base import ApiResource from functest.api.common import api_utils @@ -23,6 +25,8 @@ from functest.cli.commands.cli_tier import Tier class V1Tiers(ApiResource): """ V1Tiers Resource class """ + @swag_from(pkg_resources.resource_filename( + 'functest', 'api/swagger/tiers.yaml')) def get(self): # pylint: disable=no-self-use """ GET all tiers """ @@ -43,6 +47,8 @@ class V1Tiers(ApiResource): class V1Tier(ApiResource): """ V1Tier Resource class """ + @swag_from(pkg_resources.resource_filename( + 'functest', 'api/swagger/tier.yaml')) def get(self, tier_name): # pylint: disable=no-self-use """ GET the info of one tier """ tier_info = Tier().show(tier_name) @@ -62,6 +68,8 @@ class V1Tier(ApiResource): class V1TestcasesinTier(ApiResource): """ V1TestcasesinTier Resource class """ + @swag_from(pkg_resources.resource_filename( + 'functest', 'api/swagger/testcases_in_tier.yaml')) def get(self, tier_name): # pylint: disable=no-self-use """ GET all testcases within given tier """ tier_info = Tier().show(tier_name) diff --git a/functest/api/server.py b/functest/api/server.py index c6eb0b3b..3200c1a2 100644 --- a/functest/api/server.py +++ b/functest/api/server.py @@ -20,6 +20,7 @@ import pkg_resources from flask import Flask from flask_restful import Api +from flasgger import Swagger from functest.api.base import ApiResource from functest.api.common import api_utils @@ -34,6 +35,7 @@ LOGGER = logging.getLogger(__name__) APP = Flask(__name__) API = Api(APP) +Swagger(APP) @APP.teardown_request diff --git a/functest/api/swagger/creds.yaml b/functest/api/swagger/creds.yaml new file mode 100644 index 00000000..da3b2d90 --- /dev/null +++ b/functest/api/swagger/creds.yaml @@ -0,0 +1,35 @@ +Show credentials + +This api offers the interface to show credentials. +The credentials dict will be returned. +--- +tags: + - Creds +definitions: + Credentials: + type: object + properties: + creds_name: + $ref: '#/definitions/Name' + Name: + type: dict +responses: + 200: + description: Show credentials + schema: + $ref: '#/definitions/Credentials' + examples: + "OS_AUTH_URL": "https://192.16.1.222:5000/v3" + "OS_AUTH_VERSION": "3" + "OS_CACERT": "/home/opnfv/functest/conf/os_cacert" + "OS_ENDPOINT_TYPE": "publicURL" + "OS_IDENTITY_API_VERSION": "3" + "OS_INTERFACE": "publicURL" + "OS_NO_CACHE": "1" + "OS_PASSWORD": "990232e0885da343ac805528522d" + "OS_PROJECT_DOMAIN_NAME": "Default" + "OS_PROJECT_NAME": "admin" + "OS_REGION_NAME": "RegionOne" + "OS_TENANT_NAME": "admin" + "OS_USERNAME": "admin" + "OS_USER_DOMAIN_NAME": "Default" diff --git a/functest/api/swagger/creds_action.yaml b/functest/api/swagger/creds_action.yaml new file mode 100644 index 00000000..d67d082d --- /dev/null +++ b/functest/api/swagger/creds_action.yaml @@ -0,0 +1,57 @@ +Update openrc + +This api offers the interface to Update openstack.creds. + +action: update_openrc +--- +tags: + - Creds +parameters: + - in: body + name: body + description: this is the input json dict + schema: + required: + - action + - args + properties: + action: + type: string + description: this is action for creds + default: update_openrc + args: + schema: + required: + - openrc + properties: + openrc: + type: string + description: this is the test case name + default: + "OS_AUTH_URL": "http://192.16.1.222:5000/v3" + "OS_ENDPOINT_TYPE": "publicURL" + "OS_IDENTITY_API_VERSION": "3" + "OS_INTERFACE": "publicURL" + "OS_PASSWORD": "admn" + "OS_PROJECT_DOMAIN_NAME": "Default" + "OS_PROJECT_NAME": "admin" + "OS_REGION_NAME": "RegionOne" + "OS_TENANT_NAME": "admin" + "OS_USERNAME": "admin" + "OS_USER_DOMAIN_NAME": "Default" +definitions: + Credentials: + type: object + properties: + creds_name: + $ref: '#/definitions/Name' + Name: + type: dict +responses: + 200: + description: Update openrc + schema: + $ref: '#/definitions/Credentials' + examples: + 'status': 0 + 'result': 'Update openrc successfully' diff --git a/functest/api/swagger/envs.yaml b/functest/api/swagger/envs.yaml new file mode 100644 index 00000000..e723deb3 --- /dev/null +++ b/functest/api/swagger/envs.yaml @@ -0,0 +1,26 @@ +Show environment + +This api offers the interface to show environment. +The environment dict will be returned. +--- +tags: + - Envs +definitions: + Environment: + type: object + properties: + creds_name: + $ref: '#/definitions/Name' + Name: + type: dict +responses: + 200: + description: Show environment + schema: + $ref: '#/definitions/Environment' + examples: + "DEBUG FLAG": "false" + "INSTALLER": "compass, 192.168.200.2" + "POD": "unknown_pod" + "SCENARIO": "os-nosdn-nofeature-noha" + "STATUS": "ready" diff --git a/functest/api/swagger/envs_action.yaml b/functest/api/swagger/envs_action.yaml new file mode 100644 index 00000000..1add066e --- /dev/null +++ b/functest/api/swagger/envs_action.yaml @@ -0,0 +1,37 @@ +Prepare environment or Update hosts info + +This api offers the interface to prepare environment or update hosts info. + +action: prepare +action: update_hosts +--- +tags: + - Envs +parameters: + - in: body + name: body + description: this is the input json dict + schema: + required: + - action + properties: + action: + type: string + description: this is action for envs + default: prepare +definitions: + Environment: + type: object + properties: + creds_name: + $ref: '#/definitions/Name' + Name: + type: dict +responses: + 200: + description: Prepare environment + schema: + $ref: '#/definitions/Environment' + examples: + 'status': 0 + 'result': 'Prapare env successfully' diff --git a/functest/api/swagger/task.yaml b/functest/api/swagger/task.yaml new file mode 100644 index 00000000..abf68a0d --- /dev/null +++ b/functest/api/swagger/task.yaml @@ -0,0 +1,38 @@ +Get the result of the specified task + +This api offers the interface to get the result of the specified task. + +--- +tags: + - Tasks +parameters: + - name: task_id + description: task id + in: path + type: string + required: true +definitions: + Task: + type: object + properties: + creds_name: + $ref: '#/definitions/Result' + Result: + type: dict +responses: + 200: + description: Get the result of the specified task + schema: + $ref: '#/definitions/Task' + examples: + "result": { + "case_name": "vping_ssh", + "env_info": { + "build_tag": null, + "ci_loop": "weekly", + "installer": "compass", + "scenario": "os-nosdn-nofeature-noha" }, + "result": "PASS", + "task_id": "1a9f3c5d-ce0b-4354-862e-dd08b26fc484"} + "status": 2 + diff --git a/functest/api/swagger/task_log.yaml b/functest/api/swagger/task_log.yaml new file mode 100644 index 00000000..adaaaf40 --- /dev/null +++ b/functest/api/swagger/task_log.yaml @@ -0,0 +1,35 @@ +Get the log of the specified task + +This api offers the interface to get the log of the specified task. + +--- +tags: + - Tasks +parameters: + - name: task_id + description: task id + in: path + type: string + required: true +definitions: + Task: + type: object + properties: + creds_name: + $ref: '#/definitions/Result' + Result: + type: dict +responses: + 200: + description: Get the log of the specified task + schema: + $ref: '#/definitions/Task' + examples: + "result": { + "data": [ + "2017-09-14 06:46:26,106 - functest.ci.run_tests - DEBUG - Sourcing the OpenStack RC file... ", + "2017-09-14 06:46:26,107 - functest.ci.run_tests - DEBUG - Test args: connection_check ", + "2017-09-14 06:46:26,107 - functest.ci.run_tests - INFO - Running test case 'connection_check'... ", + "..."]} + "status": 2 + diff --git a/functest/api/swagger/testcase.yaml b/functest/api/swagger/testcase.yaml new file mode 100644 index 00000000..70ee1af1 --- /dev/null +++ b/functest/api/swagger/testcase.yaml @@ -0,0 +1,36 @@ +Show the info of one testcase + +This api offers the interface to show the detailed info of one testcase. +The info of one testcase will be returned. +--- +tags: + - Testcases +parameters: + - name: testcase_name + description: testcase name + in: path + type: string + required: true +definitions: + Testcases: + type: object + properties: + case_name: + $ref: '#/definitions/Tests' + Tests: + type: dict +responses: + 200: + description: Show the detailed info of one testcase + schema: + $ref: '#/definitions/Testcases' + examples: + "testcase": "" + "blocking": + "criteria": + "dependency": { + "installer": "", + "scenario": "" + } + "description": "" + "enabled": diff --git a/functest/api/swagger/testcase_run.yaml b/functest/api/swagger/testcase_run.yaml new file mode 100644 index 00000000..d451457d --- /dev/null +++ b/functest/api/swagger/testcase_run.yaml @@ -0,0 +1,47 @@ +Run a test case + +This api offers the interface to run a test case + +action: run_test_case +--- +tags: + - Testcases +parameters: + - in: body + name: body + description: this is the input json dict + schema: + required: + - action + - args + properties: + action: + type: string + description: this is action for creds + default: run_test_case + args: + schema: + required: + - testcase + properties: + testcase: + type: string + description: this is the test case name + default: + vping_ssh +definitions: + Testcases: + type: object + properties: + creds_name: + $ref: '#/definitions/Tests' + Tests: + type: dict +responses: + 200: + description: Run a test case + schema: + $ref: '#/definitions/Testcases' + examples: + 'task_id': '94c8ec94-d873-466f-a205-bf592f31ff5b' + 'testcase': 'vping_ssh' diff --git a/functest/api/swagger/testcases.yaml b/functest/api/swagger/testcases.yaml new file mode 100644 index 00000000..56d9d71f --- /dev/null +++ b/functest/api/swagger/testcases.yaml @@ -0,0 +1,22 @@ +List all test cases + +This api offers the interface to list all test cases +The testcases list will be returned +--- +tags: + - Testcases +definitions: + Testcases: + type: object + properties: + creds_name: + $ref: '#/definitions/Tests' + Tests: + type: dict +responses: + 200: + description: List all test cases + schema: + $ref: '#/definitions/Testcases' + examples: + "testcases": [] diff --git a/functest/api/swagger/testcases_in_tier.yaml b/functest/api/swagger/testcases_in_tier.yaml new file mode 100644 index 00000000..f6450826 --- /dev/null +++ b/functest/api/swagger/testcases_in_tier.yaml @@ -0,0 +1,29 @@ +List all testcases within given tier + +This api offers the interface to list all testcases within given tier. +All testcases within given tier will be returned. +--- +tags: + - Tiers +parameters: + - name: tier_name + description: tier name + in: path + type: string + required: true +definitions: + Testcases: + type: object + properties: + creds_name: + $ref: '#/definitions/Tests' + Tests: + type: dict +responses: + 200: + description: List all testcases within given tier + schema: + $ref: '#/definitions/Testcases' + examples: + "tier": "" + "testcases": [] diff --git a/functest/api/swagger/tier.yaml b/functest/api/swagger/tier.yaml new file mode 100644 index 00000000..8616afb5 --- /dev/null +++ b/functest/api/swagger/tier.yaml @@ -0,0 +1,32 @@ +Show the info of one tier + +This api offers the interface to show the detailed info of one tier. +The info of one tier will be returned. +--- +tags: + - Tiers +parameters: + - name: tier_name + description: tier name + in: path + type: string + required: true +definitions: + Tiers: + type: object + properties: + creds_name: + $ref: '#/definitions/Name' + Name: + type: string +responses: + 200: + description: Show the detailed info of one tier + schema: + $ref: '#/definitions/Tiers' + examples: + "tier": "" + "ci_loop": "" + "description": "" + "order": + "testcases": [] diff --git a/functest/api/swagger/tiers.yaml b/functest/api/swagger/tiers.yaml new file mode 100644 index 00000000..8a71c379 --- /dev/null +++ b/functest/api/swagger/tiers.yaml @@ -0,0 +1,22 @@ +List all tiers + +This api offers the interface to list all tiers. +The tiers list will be returned. +--- +tags: + - Tiers +definitions: + Tiers: + type: object + properties: + creds_name: + $ref: '#/definitions/Tier' + Tier: + type: dict +responses: + 200: + description: List all tiers + schema: + $ref: '#/definitions/Tiers' + examples: + "tiers": "" diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml index 16ba8b82..575b4478 100644 --- a/functest/ci/config_functest.yaml +++ b/functest/ci/config_functest.yaml @@ -136,6 +136,8 @@ rally: subnet_name: rally-subnet subnet_cidr: 192.168.140.0/24 router_name: rally-router + flavor_name: rally-tiny + flavor_alt_name: rally-mini vnf: juju_epc: diff --git a/functest/ci/run_tests.py b/functest/ci/run_tests.py index a129ea73..d4acd9c5 100644 --- a/functest/ci/run_tests.py +++ b/functest/ci/run_tests.py @@ -124,16 +124,18 @@ class Runner(object): self.executed_test_cases[test.get_name()] = test_case if self.clean_flag: if test_case.create_snapshot() != test_case.EX_OK: - return result + return testcase.TestCase.EX_RUN_ERROR try: kwargs = run_dict['args'] - result = test_case.run(**kwargs) + test_case.run(**kwargs) except KeyError: - result = test_case.run() - if result == testcase.TestCase.EX_OK: - if self.report_flag: - test_case.push_to_db() + test_case.run() + if self.report_flag: + test_case.push_to_db() + if test.get_project() == "functest": result = test_case.is_successful() + else: + result = testcase.TestCase.EX_OK logger.info("Test result:\n\n%s\n", test_case) if self.clean_flag: test_case.clean() @@ -157,10 +159,12 @@ class Runner(object): else: logger.info("Running tier '%s'" % tier_name) for test in tests: - result = self.run_test(test) - if result != testcase.TestCase.EX_OK: + self.run_test(test) + test_case = self.executed_test_cases[test.get_name()] + if test_case.is_successful() != testcase.TestCase.EX_OK: logger.error("The test case '%s' failed.", test.get_name()) - self.overall_result = Result.EX_ERROR + if test.get_project() == "functest": + self.overall_result = Result.EX_ERROR if test.is_blocking(): raise BlockingTestFailed( "The test case {} failed and is blocking".format( diff --git a/functest/opnfv_tests/openstack/rally/rally.py b/functest/opnfv_tests/openstack/rally/rally.py index 5aba3882..e92639b2 100644 --- a/functest/opnfv_tests/openstack/rally/rally.py +++ b/functest/opnfv_tests/openstack/rally/rally.py @@ -29,6 +29,7 @@ from functest.energy import energy from functest.opnfv_tests.openstack.snaps import snaps_utils from functest.utils.constants import CONST +from snaps.openstack.create_flavor import FlavorSettings, OpenStackFlavor from snaps.openstack.create_image import ImageSettings from snaps.openstack.create_network import NetworkSettings, SubnetSettings from snaps.openstack.create_router import RouterSettings @@ -54,7 +55,11 @@ class RallyBase(testcase.TestCase): if hasattr(CONST, 'openstack_extra_properties'): GLANCE_IMAGE_EXTRA_PROPERTIES = CONST.__getattribute__( 'openstack_extra_properties') - FLAVOR_NAME = "m1.tiny" + FLAVOR_NAME = CONST.__getattribute__('rally_flavor_name') + FLAVOR_ALT_NAME = CONST.__getattribute__('rally_flavor_alt_name') + FLAVOR_EXTRA_SPECS = None + if hasattr(CONST, 'flavor_extra_specs'): + FLAVOR_EXTRA_SPECS = CONST.__getattribute__('flavor_extra_specs') RALLY_DIR = pkg_resources.resource_filename( 'functest', 'opnfv_tests/openstack/rally') @@ -102,8 +107,11 @@ class RallyBase(testcase.TestCase): self.mode = '' self.summary = [] self.scenario_dir = '' + self.image_name = None self.ext_net_name = None self.priv_net_id = None + self.flavor_name = None + self.flavor_alt_name = None self.smoke = None self.test_name = None self.start_time = None @@ -112,8 +120,9 @@ class RallyBase(testcase.TestCase): def _build_task_args(self, test_file_name): task_args = {'service_list': [test_file_name]} - task_args['image_name'] = self.GLANCE_IMAGE_NAME - task_args['flavor_name'] = self.FLAVOR_NAME + task_args['image_name'] = self.image_name + task_args['flavor_name'] = self.flavor_name + task_args['flavor_alt_name'] = self.flavor_alt_name task_args['glance_image_location'] = self.GLANCE_IMAGE_PATH task_args['glance_image_format'] = self.GLANCE_IMAGE_FORMAT task_args['tmpl_dir'] = self.TEMPLATE_DIR @@ -467,24 +476,25 @@ class RallyBase(testcase.TestCase): if self.test_name not in self.TESTS: raise Exception("Test name '%s' is invalid" % self.test_name) - image_name = self.GLANCE_IMAGE_NAME + self.guid network_name = self.RALLY_PRIVATE_NET_NAME + self.guid subnet_name = self.RALLY_PRIVATE_SUBNET_NAME + self.guid router_name = self.RALLY_ROUTER_NAME + self.guid + self.image_name = self.GLANCE_IMAGE_NAME + self.guid + self.flavor_name = self.FLAVOR_NAME + self.guid + self.flavor_alt_name = self.FLAVOR_ALT_NAME + self.guid self.ext_net_name = snaps_utils.get_ext_net_name(self.os_creds) - LOGGER.debug('Getting or creating image...') + LOGGER.debug("Creating image '%s'...", self.image_name) image_creator = deploy_utils.create_image( self.os_creds, ImageSettings( - name=image_name, + name=self.image_name, image_file=self.GLANCE_IMAGE_PATH, img_format=self.GLANCE_IMAGE_FORMAT, image_user=self.GLANCE_IMAGE_USERNAME, public=True, extra_properties=self.GLANCE_IMAGE_EXTRA_PROPERTIES)) if image_creator is None: - raise Exception("Failed to get or create image '%s'" % - image_name) + raise Exception("Failed to create image") self.creators.append(image_creator) LOGGER.debug("Creating network '%s'...", network_name) @@ -511,6 +521,24 @@ class RallyBase(testcase.TestCase): raise Exception("Failed to create router") self.creators.append(router_creator) + LOGGER.debug("Creating flavor '%s'...", self.flavor_name) + flavor_creator = OpenStackFlavor( + self.os_creds, FlavorSettings( + name=self.flavor_name, ram=512, disk=1, vcpus=1, + metadata=self.FLAVOR_EXTRA_SPECS)) + if flavor_creator is None or flavor_creator.create() is None: + raise Exception("Failed to create flavor") + self.creators.append(flavor_creator) + + LOGGER.debug("Creating flavor '%s'...", self.flavor_alt_name) + flavor_alt_creator = OpenStackFlavor( + self.os_creds, FlavorSettings( + name=self.flavor_alt_name, ram=1024, disk=1, vcpus=1, + metadata=self.FLAVOR_EXTRA_SPECS)) + if flavor_alt_creator is None or flavor_alt_creator.create() is None: + raise Exception("Failed to create flavor") + self.creators.append(flavor_alt_creator) + def _run_tests(self): if self.test_name == 'all': for test in self.TESTS: diff --git a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-nova.yaml b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-nova.yaml index d7622093..8fb5f5ee 100644 --- a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-nova.yaml +++ b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-nova.yaml @@ -215,7 +215,7 @@ args: {{ vm_params(image_name, flavor_name) }} to_flavor: - name: "m1.small" + name: {{ flavor_alt_name }} confirm: true force_delete: false nics: diff --git a/functest/opnfv_tests/vnf/ims/orchestra_clearwaterims.py b/functest/opnfv_tests/vnf/ims/orchestra_clearwaterims.py index 5b2e585e..6a111603 100644 --- a/functest/opnfv_tests/vnf/ims/orchestra_clearwaterims.py +++ b/functest/opnfv_tests/vnf/ims/orchestra_clearwaterims.py @@ -494,7 +494,7 @@ class ClearwaterImsVnf(vnf.VnfOnBoarding): self.logger.info("Waiting for Open Baton NFVO to be up and running...") timeout = 0 - while timeout < 200: + while timeout < 45: if servertest( self.mano['details']['fip'].ip, "8080"): @@ -502,11 +502,11 @@ class ClearwaterImsVnf(vnf.VnfOnBoarding): else: self.logger.info( "Open Baton NFVO is not started yet (%ss)", - (timeout * 5)) - time.sleep(5) + (timeout * 60)) + time.sleep(60) timeout += 1 - if timeout >= 200: + if timeout >= 45: duration = time.time() - start_time self.details["orchestrator"].update( status='FAIL', duration=duration) @@ -599,13 +599,13 @@ class ClearwaterImsVnf(vnf.VnfOnBoarding): while self.mano['details']['nsr'].get("status") != 'ACTIVE' \ and self.mano['details']['nsr'].get("status") != 'ERROR': timeout += 1 - self.logger.info("NSR is not yet ACTIVE... (%ss)", 5 * timeout) - if timeout == 300: - self.logger.error("INACTIVE NSR after %s sec..", 5 * timeout) + self.logger.info("NSR is not yet ACTIVE... (%ss)", 60 * timeout) + if timeout == 30: + self.logger.error("INACTIVE NSR after %s sec..", 60 * timeout) duration = time.time() - start_time self.details["vnf"].update(status='FAIL', duration=duration) return False - time.sleep(5) + time.sleep(60) self.mano['details']['nsr'] = json.loads( nsr_agent.find(self.mano['details']['nsr'].get('id'))) diff --git a/functest/opnfv_tests/vnf/ims/orchestra_openims.py b/functest/opnfv_tests/vnf/ims/orchestra_openims.py index fa700890..0821e42a 100644 --- a/functest/opnfv_tests/vnf/ims/orchestra_openims.py +++ b/functest/opnfv_tests/vnf/ims/orchestra_openims.py @@ -488,18 +488,18 @@ class OpenImsVnf(vnf.VnfOnBoarding): self.logger.info("Waiting for Open Baton NFVO to be up and running...") timeout = 0 - while timeout < 200: + while timeout < 45: if servertest( self.mano['details']['fip'].ip, "8080"): break else: self.logger.info("Open Baton NFVO is not started yet (%ss)", - (timeout * 5)) - time.sleep(5) + (timeout * 60)) + time.sleep(60) timeout += 1 - if timeout >= 200: + if timeout >= 45: duration = time.time() - start_time self.details["orchestrator"].update( status='FAIL', duration=duration) @@ -592,13 +592,13 @@ class OpenImsVnf(vnf.VnfOnBoarding): while self.mano['details']['nsr'].get("status") != 'ACTIVE' \ and self.mano['details']['nsr'].get("status") != 'ERROR': timeout += 1 - self.logger.info("NSR is not yet ACTIVE... (%ss)", 5 * timeout) - if timeout == 300: - self.logger.error("INACTIVE NSR after %s sec..", 5 * timeout) + self.logger.info("NSR is not yet ACTIVE... (%ss)", 60 * timeout) + if timeout == 30: + self.logger.error("INACTIVE NSR after %s sec..", 60 * timeout) duration = time.time() - start_time self.details["vnf"].update(status='FAIL', duration=duration) return False - time.sleep(5) + time.sleep(60) self.mano['details']['nsr'] = json.loads( nsr_agent.find(self.mano['details']['nsr'].get('id'))) diff --git a/functest/tests/unit/ci/test_run_tests.py b/functest/tests/unit/ci/test_run_tests.py index 7495c40e..bc95f8f3 100644 --- a/functest/tests/unit/ci/test_run_tests.py +++ b/functest/tests/unit/ci/test_run_tests.py @@ -31,6 +31,10 @@ class RunTestsTesting(unittest.TestCase): def setUp(self): self.runner = run_tests.Runner() + mock_test_case = mock.Mock() + mock_test_case.is_successful.return_value = TestCase.EX_OK + self.runner.executed_test_cases['test1'] = mock_test_case + self.runner.executed_test_cases['test2'] = mock_test_case self.sep = 'test_sep' self.creds = {'OS_AUTH_URL': 'http://test_ip:test_port/v2.0', 'OS_USERNAME': 'test_os_username', @@ -191,8 +195,10 @@ class RunTestsTesting(unittest.TestCase): @mock.patch('functest.ci.run_tests.Runner.summary') def test_main_tier(self, *mock_methods): mock_tier = mock.Mock() + test_mock = mock.Mock() + test_mock.get_name.return_value = 'test1' args = {'get_name.return_value': 'tier_name', - 'get_tests.return_value': ['test_name']} + 'get_tests.return_value': [test_mock]} mock_tier.configure_mock(**args) kwargs = {'test': 'tier_name', 'noclean': True, 'report': True} args = {'get_tier.return_value': mock_tier, @@ -201,7 +207,7 @@ class RunTestsTesting(unittest.TestCase): self.runner._tiers.configure_mock(**args) self.assertEqual(self.runner.main(**kwargs), run_tests.Result.EX_OK) - mock_methods[1].assert_called_once_with('test_name') + mock_methods[1].assert_called() @mock.patch('functest.ci.run_tests.Runner.source_rc_file') @mock.patch('functest.ci.run_tests.Runner.run_test', diff --git a/functest/tests/unit/openstack/rally/test_rally.py b/functest/tests/unit/openstack/rally/test_rally.py index 63c0192b..191722dc 100644 --- a/functest/tests/unit/openstack/rally/test_rally.py +++ b/functest/tests/unit/openstack/rally/test_rally.py @@ -328,6 +328,52 @@ class OSRallyTesting(unittest.TestCase): mock_get_net.assert_called() mock_create_router.assert_called() + @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.' + 'get_ext_net_name', return_value='test_net_name') + @mock.patch('snaps.openstack.utils.deploy_utils.create_image', + return_value=mock.Mock()) + @mock.patch('snaps.openstack.utils.deploy_utils.create_network', + return_value=mock.Mock()) + @mock.patch('snaps.openstack.utils.deploy_utils.create_router', + return_value=mock.Mock()) + @mock.patch('snaps.openstack.create_flavor.OpenStackFlavor.create', + return_value=None) + def test_prepare_env_flavor_creation_failed( + self, mock_create_flavor, mock_create_router, mock_create_net, + mock_get_img, mock_get_net): + self.rally_base.TESTS = ['test1', 'test2'] + self.rally_base.test_name = 'test1' + with self.assertRaises(Exception): + self.rally_base._prepare_env() + mock_create_net.assert_called() + mock_get_img.assert_called() + mock_get_net.assert_called() + mock_create_router.assert_called() + mock_create_flavor.assert_called_once() + + @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.' + 'get_ext_net_name', return_value='test_net_name') + @mock.patch('snaps.openstack.utils.deploy_utils.create_image', + return_value=mock.Mock()) + @mock.patch('snaps.openstack.utils.deploy_utils.create_network', + return_value=mock.Mock()) + @mock.patch('snaps.openstack.utils.deploy_utils.create_router', + return_value=mock.Mock()) + @mock.patch('snaps.openstack.create_flavor.OpenStackFlavor.create', + side_effect=[mock.Mock, None]) + def test_prepare_env_flavor_alt_creation_failed( + self, mock_create_flavor, mock_create_router, mock_create_net, + mock_get_img, mock_get_net): + self.rally_base.TESTS = ['test1', 'test2'] + self.rally_base.test_name = 'test1' + with self.assertRaises(Exception): + self.rally_base._prepare_env() + mock_create_net.assert_called() + mock_get_img.assert_called() + mock_get_net.assert_called() + mock_create_router.assert_called() + self.assertEqual(mock_create_flavor.call_count, 2) + @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.' '_run_task', return_value=mock.Mock()) def test_run_tests_all(self, mock_run_task): diff --git a/requirements.txt b/requirements.txt index 650f6145..d4a0377d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,6 +22,7 @@ cloudify-rest-client Flask!=0.11,<1.0,>=0.10 # BSD Flask-RESTful>=0.3.5 # BSD IPy +flasgger # MIT mock>=2.0 # BSD iniparse==0.4 PrettyTable<0.8,>=0.7.1 # BSD diff --git a/upper-constraints.txt b/upper-constraints.txt index 3c27d71f..4f1560ae 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -15,3 +15,5 @@ robotframework-requests===0.4.7 robotframework-sshlibrary===2.1.3;python_version=='2.7' IPy===0.83 os-faults===0.1.10 +ansible===2.3.2.0 +flasgger===0.6.6 |