Merge "Enable Doctor testcase"
authorCedric Ollivier <cedric.ollivier@orange.com>
Wed, 20 Sep 2017 17:27:43 +0000 (17:27 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Wed, 20 Sep 2017 17:27:43 +0000 (17:27 +0000)
31 files changed:
build.sh
docker/parser/testcases.yaml
docker/vnf/testcases.yaml
functest/api/resources/v1/creds.py
functest/api/resources/v1/envs.py
functest/api/resources/v1/tasks.py
functest/api/resources/v1/testcases.py
functest/api/resources/v1/tiers.py
functest/api/server.py
functest/api/swagger/creds.yaml [new file with mode: 0644]
functest/api/swagger/creds_action.yaml [new file with mode: 0644]
functest/api/swagger/envs.yaml [new file with mode: 0644]
functest/api/swagger/envs_action.yaml [new file with mode: 0644]
functest/api/swagger/task.yaml [new file with mode: 0644]
functest/api/swagger/task_log.yaml [new file with mode: 0644]
functest/api/swagger/testcase.yaml [new file with mode: 0644]
functest/api/swagger/testcase_run.yaml [new file with mode: 0644]
functest/api/swagger/testcases.yaml [new file with mode: 0644]
functest/api/swagger/testcases_in_tier.yaml [new file with mode: 0644]
functest/api/swagger/tier.yaml [new file with mode: 0644]
functest/api/swagger/tiers.yaml [new file with mode: 0644]
functest/ci/config_functest.yaml
functest/ci/run_tests.py
functest/opnfv_tests/openstack/rally/rally.py
functest/opnfv_tests/openstack/rally/scenario/full/opnfv-nova.yaml
functest/opnfv_tests/vnf/ims/orchestra_clearwaterims.py
functest/opnfv_tests/vnf/ims/orchestra_openims.py
functest/tests/unit/ci/test_run_tests.py
functest/tests/unit/openstack/rally/test_rally.py
requirements.txt
upper-constraints.txt

index 4a6d68a..18d2e58 100644 (file)
--- a/build.sh
+++ b/build.sh
@@ -9,7 +9,7 @@ docker/healthcheck \
 docker/smoke \
 docker/features \
 docker/components \
-docker/vnf \
+docker/vnf \
 docker/parser \
 docker/restapi"
 
index 4ab3fae..45ccb0b 100644 (file)
@@ -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'
index c0eba82..64c0024 100644 (file)
@@ -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'
index 45e4559..f445017 100644 (file)
@@ -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()
index 8020544..65e61c4 100644 (file)
 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()
index 4921412..6bf625a 100644 (file)
@@ -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:
index cc2d4e1..7cc70bb 100644 (file)
@@ -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()
index b58ab20..523df13 100644 (file)
 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)
index c6eb0b3..3200c1a 100644 (file)
@@ -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 (file)
index 0000000..da3b2d9
--- /dev/null
@@ -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 (file)
index 0000000..d67d082
--- /dev/null
@@ -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 (file)
index 0000000..e723deb
--- /dev/null
@@ -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 (file)
index 0000000..1add066
--- /dev/null
@@ -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 (file)
index 0000000..abf68a0
--- /dev/null
@@ -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 (file)
index 0000000..adaaaf4
--- /dev/null
@@ -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 (file)
index 0000000..70ee1af
--- /dev/null
@@ -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 (file)
index 0000000..d451457
--- /dev/null
@@ -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 (file)
index 0000000..56d9d71
--- /dev/null
@@ -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 (file)
index 0000000..f645082
--- /dev/null
@@ -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 (file)
index 0000000..8616afb
--- /dev/null
@@ -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 (file)
index 0000000..8a71c37
--- /dev/null
@@ -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": ""
index 16ba8b8..575b447 100644 (file)
@@ -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:
index a129ea7..d4acd9c 100644 (file)
@@ -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(
index 5aba388..e92639b 100644 (file)
@@ -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:
index d762209..8fb5f5e 100644 (file)
       args:
         {{ vm_params(image_name, flavor_name) }}
         to_flavor:
-          name: "m1.small"
+          name: {{ flavor_alt_name }}
         confirm: true
         force_delete: false
         nics:
index 5b2e585..6a11160 100644 (file)
@@ -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')))
 
index fa70089..0821e42 100644 (file)
@@ -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')))
 
index 7495c40..bc95f8f 100644 (file)
@@ -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',
index 63c0192..191722d 100644 (file)
@@ -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):
index 650f614..d4a0377 100644 (file)
@@ -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
index 3c27d71..4f1560a 100644 (file)
@@ -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