summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docker/Dockerfile4
-rwxr-xr-xfunctest/ci/config_functest.yaml5
-rw-r--r--functest/ci/run_tests.py2
-rwxr-xr-xfunctest/ci/testcases.yaml56
-rw-r--r--functest/core/feature_base.py58
-rw-r--r--functest/core/pytest_suite_runner.py55
-rw-r--r--functest/opnfv_tests/openstack/snaps/__init__.py0
-rw-r--r--functest/opnfv_tests/openstack/snaps/api_check.py31
-rw-r--r--functest/opnfv_tests/openstack/snaps/connection_check.py31
-rw-r--r--functest/opnfv_tests/openstack/snaps/smoke.py40
-rw-r--r--functest/opnfv_tests/openstack/snaps/snaps_utils.py22
-rw-r--r--functest/opnfv_tests/vnf/rnc/parser.py65
-rw-r--r--functest/utils/functest_utils.py19
-rwxr-xr-xfunctest/utils/openstack_utils.py35
-rwxr-xr-x[-rw-r--r--]requirements.txt4
-rwxr-xr-x[-rw-r--r--]test-requirements.txt2
16 files changed, 344 insertions, 85 deletions
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 6bdfe5ce6..f76dd7979 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -43,6 +43,7 @@ ARG FUNCTEST_DATA_DIR=${FUNCTEST_BASE_DIR}/data
ARG FUNCTEST_RESULTS_DIR=${FUNCTEST_BASE_DIR}/results
ARG FUNCTEST_REPO_DIR=${REPOS_DIR}/functest
ARG FUNCTEST_TEST_DIR=${FUNCTEST_REPO_DIR}/functest/opnfv_tests
+ARG RELENG_MODULE_DIR=${REPOS_DIR}/releng/modules
# Environment variables
ENV HOME /home/opnfv
@@ -117,6 +118,9 @@ RUN cd ${FUNCTEST_REPO_DIR} \
&& pip install -r requirements.txt \
&& pip install .
+RUN cd ${RELENG_MODULE_DIR} \
+ && pip install .
+
RUN pip install -r ${REPOS_DIR}/rally/requirements.txt
RUN pip install -r ${REPOS_DIR}/tempest/requirements.txt
diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml
index c75afdafe..0da2bb8f3 100755
--- a/functest/ci/config_functest.yaml
+++ b/functest/ci/config_functest.yaml
@@ -26,6 +26,7 @@ general:
dir_repo_ovno: /home/opnfv/repos/ovno
dir_repo_parser: /home/opnfv/repos/parser
dir_repo_domino: /home/opnfv/repos/domino
+ dir_repo_snaps: /home/opnfv/repos/snaps
dir_functest: /home/opnfv/functest
dir_functest_test: /home/opnfv/repos/functest/functest/opnfv_tests
dir_results: /home/opnfv/functest/results
@@ -64,6 +65,10 @@ healthcheck:
disk_format: qcow2
wait_time: 60
+snaps:
+ use_keystone: True
+ use_floating_ips: False
+
vping:
ping_timeout: 200
vm_flavor: m1.tiny # adapt to your environment
diff --git a/functest/ci/run_tests.py b/functest/ci/run_tests.py
index d2a64aea1..3f02c8725 100644
--- a/functest/ci/run_tests.py
+++ b/functest/ci/run_tests.py
@@ -142,7 +142,7 @@ def run_test(test, tier_name):
result = test_case.run()
if (result == testcase_base.TestcaseBase.EX_OK and
GlobalVariables.REPORT_FLAG):
- result = test_case.push_to_db()
+ test_case.push_to_db()
except ImportError:
logger.exception("Cannot import module {}".format(
run_dict['module']))
diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml
index d483e589e..d57ac3060 100755
--- a/functest/ci/testcases.yaml
+++ b/functest/ci/testcases.yaml
@@ -19,6 +19,24 @@ tiers:
installer: ''
scenario: '^((?!lxd).)*$'
+ -
+ name: connection_check
+ criteria: 'status == "PASS"'
+ blocking: true
+ description: >-
+ This test case verifies the retrieval of OpenStack clients:
+ Keystone, Glance, Neutron and Nova and may perform some
+ simple queries. When the config value of
+ snaps.use_keystone is True, functest must have access to
+ the cloud's private network.
+
+ dependencies:
+ installer: ''
+ scenario: ''
+ run:
+ module: 'functest.opnfv_tests.openstack.snaps.connection_check'
+ class: 'ConnectionCheck'
+
-
name: smoke
order: 1
@@ -106,6 +124,44 @@ tiers:
installer: ''
scenario: 'onos'
+ -
+ name: api_check
+ criteria: 'status == "PASS"'
+ blocking: true
+ description: >-
+ This test case verifies the retrieval of OpenStack clients:
+ Keystone, Glance, Neutron and Nova and may perform some
+ simple queries. When the config value of
+ snaps.use_keystone is True, functest must have access to
+ the cloud's private network.
+
+ dependencies:
+ installer: ''
+ scenario: ''
+ run:
+ module: 'functest.opnfv_tests.openstack.snaps.api_check'
+ class: 'ApiCheck'
+
+ -
+ name: snaps_smoke
+ criteria: 'status == "PASS"'
+ blocking: true
+ description: >-
+ This test case contains tests that setup and destroy
+ environments with VMs with and without Floating IPs
+ with a newly created user and project. Set the config
+ value snaps.use_floating_ips (True|False) to toggle
+ this functionality. When the config value of
+ snaps.use_keystone is True, functest must have access to
+ the cloud's private network.
+
+ dependencies:
+ installer: ''
+ scenario: ''
+ run:
+ module: 'functest.opnfv_tests.openstack.snaps.smoke'
+ class: 'SnapsSmoke'
+
-
name: features
order: 2
diff --git a/functest/core/feature_base.py b/functest/core/feature_base.py
new file mode 100644
index 000000000..01a27f305
--- /dev/null
+++ b/functest/core/feature_base.py
@@ -0,0 +1,58 @@
+import time
+
+import testcase_base as base
+import functest.utils.functest_utils as ft_utils
+import functest.utils.functest_logger as ft_logger
+
+
+class FeatureBase(base.TestcaseBase):
+ def __init__(self, project='functest', case='', repo='', cmd=''):
+ super(FeatureBase, self).__init__()
+ self.project_name = project
+ self.case_name = case
+ self.cmd = cmd
+ self.repo = self.get_conf('general.directories.{}'.format(repo))
+ self.result_file = self.get_result_file()
+ self.logger = ft_logger.Logger(project).getLogger()
+
+ def run(self, **kwargs):
+ self.prepare()
+ self.start_time = time.time()
+ ret = ft_utils.execute_command(self.cmd, output_file=self.result_file)
+ self.stop_time = time.time()
+ self.post()
+ self.parse_results(ret)
+ self.log_results()
+ return base.TestcaseBase.EX_OK
+
+ def prepare(self, **kwargs):
+ pass
+
+ def post(self, **kwargs):
+ pass
+
+ def parse_results(self, ret):
+ exit_code = base.TestcaseBase.EX_OK
+ if ret == 0:
+ self.logger.info("{} OK".format(self.project_name))
+ self.criteria = 'PASS'
+ else:
+ self.logger.info("{} FAILED".format(self.project_name))
+ exit_code = base.TestcaseBase.EX_RUN_ERROR
+ self.criteria = "FAIL"
+
+ return exit_code
+
+ def get_result_file(self):
+ dir = self.get_conf('general.directories.dir_results')
+ return "{}/{}.log".format(dir, self.project_name)
+
+ def log_results(self):
+ ft_utils.logger_test_results(self.project_name,
+ self.case_name,
+ self.criteria,
+ self.details)
+
+ @staticmethod
+ def get_conf(parameter):
+ return ft_utils.get_functest_config(parameter)
diff --git a/functest/core/pytest_suite_runner.py b/functest/core/pytest_suite_runner.py
new file mode 100644
index 000000000..2d5b2667b
--- /dev/null
+++ b/functest/core/pytest_suite_runner.py
@@ -0,0 +1,55 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2015 All rights reserved
+# This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import testcase_base as base
+import unittest
+import time
+
+
+class PyTestSuiteRunner(base.TestcaseBase):
+ """
+ This superclass is designed to execute pre-configured unittest.TestSuite()
+ objects
+ """
+ def __init__(self):
+ super(PyTestSuiteRunner, self).__init__()
+ self.suite = None
+
+ def run(self, **kwargs):
+ """
+ Starts test execution from the functest framework
+ """
+ self.start_time = time.time()
+ result = unittest.TextTestRunner(verbosity=2).run(self.suite)
+ self.stop_time = time.time()
+
+ if result.errors:
+ self.logger.error('Number of errors in test suite - ' +
+ str(len(result.errors)))
+ for test, message in result.errors:
+ self.logger.error(str(test) + " ERROR with " + message)
+
+ if result.failures:
+ self.logger.error('Number of failures in test suite - ' +
+ str(len(result.failures)))
+ for test, message in result.failures:
+ self.logger.error(str(test) + " FAILED with " + message)
+
+ if (result.errors and len(result.errors) > 0) \
+ or (result.failures and len(result.failures) > 0):
+ self.logger.info("%s FAILED" % self.case_name)
+ self.criteria = 'FAIL'
+ exit_code = base.TestcaseBase.EX_RUN_ERROR
+ else:
+ self.logger.info("%s OK" % self.case_name)
+ exit_code = base.TestcaseBase.EX_OK
+ self.criteria = 'PASS'
+
+ self.details = {}
+ return exit_code
diff --git a/functest/opnfv_tests/openstack/snaps/__init__.py b/functest/opnfv_tests/openstack/snaps/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/opnfv_tests/openstack/snaps/__init__.py
diff --git a/functest/opnfv_tests/openstack/snaps/api_check.py b/functest/opnfv_tests/openstack/snaps/api_check.py
new file mode 100644
index 000000000..e6ee81e9d
--- /dev/null
+++ b/functest/opnfv_tests/openstack/snaps/api_check.py
@@ -0,0 +1,31 @@
+# Copyright (c) 2015 All rights reserved
+# This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import functest.utils.functest_utils as ft_utils
+from functest.core.pytest_suite_runner import PyTestSuiteRunner
+from functest.opnfv_tests.openstack.snaps import snaps_utils
+from snaps import test_suite_builder
+import unittest
+
+
+class ApiCheck(PyTestSuiteRunner):
+ """
+ This test executes the Python Tests included with the SNAPS libraries
+ that exercise many of the OpenStack APIs within Keystone, Glance, Neutron,
+ and Nova
+ """
+ def __init__(self):
+ super(ApiCheck, self).__init__()
+
+ self.suite = unittest.TestSuite()
+ creds_file = ft_utils.get_functest_config('general.openstack.creds')
+ use_key = ft_utils.get_functest_config('snaps.use_keystone')
+ ext_net_name = snaps_utils.get_ext_net_name()
+
+ test_suite_builder.add_openstack_api_tests(self.suite, creds_file,
+ ext_net_name,
+ use_keystone=use_key)
diff --git a/functest/opnfv_tests/openstack/snaps/connection_check.py b/functest/opnfv_tests/openstack/snaps/connection_check.py
new file mode 100644
index 000000000..42e38d67c
--- /dev/null
+++ b/functest/opnfv_tests/openstack/snaps/connection_check.py
@@ -0,0 +1,31 @@
+# Copyright (c) 2015 All rights reserved
+# This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import functest.utils.functest_utils as ft_utils
+from functest.core.pytest_suite_runner import PyTestSuiteRunner
+from functest.opnfv_tests.openstack.snaps import snaps_utils
+from snaps import test_suite_builder
+import unittest
+
+
+class ConnectionCheck(PyTestSuiteRunner):
+ """
+ This test executes the Python Tests included with the SNAPS libraries
+ that simply obtain the different OpenStack clients and may perform
+ simple queries
+ """
+ def __init__(self):
+ super(ConnectionCheck, self).__init__()
+
+ self.suite = unittest.TestSuite()
+ creds_file = ft_utils.get_functest_config('general.openstack.creds')
+ use_key = ft_utils.get_functest_config('snaps.use_keystone')
+ ext_net_name = snaps_utils.get_ext_net_name()
+
+ test_suite_builder.add_openstack_client_tests(self.suite, creds_file,
+ ext_net_name,
+ use_keystone=use_key)
diff --git a/functest/opnfv_tests/openstack/snaps/smoke.py b/functest/opnfv_tests/openstack/snaps/smoke.py
new file mode 100644
index 000000000..25433a325
--- /dev/null
+++ b/functest/opnfv_tests/openstack/snaps/smoke.py
@@ -0,0 +1,40 @@
+# Copyright (c) 2015 All rights reserved
+# This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import functest.utils.functest_utils as ft_utils
+from functest.core.pytest_suite_runner import PyTestSuiteRunner
+from functest.opnfv_tests.openstack.snaps import snaps_utils
+from snaps import test_suite_builder
+import unittest
+import os
+
+
+class SnapsSmoke(PyTestSuiteRunner):
+ """
+ This test executes the Python Tests included with the SNAPS libraries
+ that exercise many of the OpenStack APIs within Keystone, Glance, Neutron,
+ and Nova
+ """
+ def __init__(self):
+ super(SnapsSmoke, self).__init__()
+
+ self.suite = unittest.TestSuite()
+ creds_file = ft_utils.get_functest_config('general.openstack.creds')
+ use_key = ft_utils.get_functest_config('snaps.use_keystone')
+ use_fip = ft_utils.get_functest_config('snaps.use_floating_ips')
+ ext_net_name = snaps_utils.get_ext_net_name()
+
+ # Tests requiring floating IPs leverage files contained within the
+ # SNAPS repository and are found relative to that path
+ if use_fip:
+ snaps_dir = ft_utils.get_functest_config(
+ 'general.directories.dir_repo_snaps') + '/snaps'
+ os.chdir(snaps_dir)
+
+ test_suite_builder.add_openstack_integration_tests(
+ self.suite, creds_file, ext_net_name, use_keystone=use_key,
+ use_floating_ips=use_fip)
diff --git a/functest/opnfv_tests/openstack/snaps/snaps_utils.py b/functest/opnfv_tests/openstack/snaps/snaps_utils.py
new file mode 100644
index 000000000..a25ad3e0d
--- /dev/null
+++ b/functest/opnfv_tests/openstack/snaps/snaps_utils.py
@@ -0,0 +1,22 @@
+# Copyright (c) 2015 All rights reserved
+# This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import functest.utils.functest_utils as ft_utils
+from snaps.openstack.tests import openstack_tests
+from snaps.openstack.utils import neutron_utils
+
+
+def get_ext_net_name():
+ """
+ Returns the first external network name
+ :return:
+ """
+ os_env_file = ft_utils.get_functest_config('general.openstack.creds')
+ os_creds = openstack_tests.get_credentials(os_env_file=os_env_file)
+ neutron = neutron_utils.neutron_client(os_creds)
+ ext_nets = neutron_utils.get_external_networks(neutron)
+ return ext_nets[0]['network']['name']
diff --git a/functest/opnfv_tests/vnf/rnc/parser.py b/functest/opnfv_tests/vnf/rnc/parser.py
index a50d4f1eb..1cff72209 100644
--- a/functest/opnfv_tests/vnf/rnc/parser.py
+++ b/functest/opnfv_tests/vnf/rnc/parser.py
@@ -14,66 +14,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-import os
-import sys
-import time
-import argparse
+import functest.core.feature_base as base
-import functest.core.testcase_base as testcase_base
-import functest.utils.functest_constants as ft_constants
-import functest.utils.functest_logger as ft_logger
-import functest.utils.functest_utils as ft_utils
-
-
-class Parser(testcase_base.TestcaseBase):
+class Parser(base.FeatureBase):
def __init__(self):
- super(Parser, self).__init__()
- self.project_name = "parser"
- self.case_name = "parser-basics"
- self.logger = ft_logger.Logger("parser").getLogger()
- self.log_file = os.path.join(
- ft_constants.FUNCTEST_RESULTS_DIR, "parser.log")
-
- def run(self, **kwargs):
- cmd = 'cd %s/tests && ./functest_run.sh' % ft_constants.PARSER_REPO_DIR
-
- self.start_time = time.time()
- ret = ft_utils.execute_command(cmd,
- info=True,
- output_file=self.log_file)
- self.stop_time = time.time()
-
- self.criteria, details = ft_utils.check_test_result(self.project_name,
- ret,
- self.start_time,
- self.stop_time)
-
- ft_utils.logger_test_results(self.project_name,
- self.case_name,
- self.criteria,
- details)
-
- return ret
-
- @staticmethod
- def get_conf(parameter):
- return ft_utils.get_functest_config(parameter)
-
-
-if __name__ == '__main__':
- args_parser = argparse.ArgumentParser()
- args_parser.add_argument("-r", "--report",
- help="Create json result file",
- action="store_true")
- args = vars(args_parser.parse_args())
- parser = Parser()
- try:
- result = parser.run(**args)
- if result != testcase_base.TestcaseBase.EX_OK:
- sys.exit(result)
- if args['report']:
- sys.exit(parser.push_to_db())
- except Exception:
- sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR)
+ super(Parser, self).__init__(project='parser',
+ case='parser-basics',
+ repo='dir_repo_parser')
+ self.cmd = 'cd %s/tests && ./functest_run.sh' % self.repo
diff --git a/functest/utils/functest_utils.py b/functest/utils/functest_utils.py
index a25967b69..8f816cdf9 100644
--- a/functest/utils/functest_utils.py
+++ b/functest/utils/functest_utils.py
@@ -418,25 +418,8 @@ def merge_dicts(dict1, dict2):
yield (k, dict2[k])
-def check_test_result(test_name, ret, start_time, stop_time):
- def get_criteria_value():
- return get_criteria_by_test(test_name).split('==')[1].strip()
-
- status = 'FAIL'
- if str(ret) == get_criteria_value():
- status = 'PASS'
-
- details = {
- 'timestart': start_time,
- 'duration': round(stop_time - start_time, 1),
- 'status': status,
- }
-
- return status, details
-
-
def get_testcases_file_dir():
- return "/home/opnfv/repos/functest/functest/ci/testcases.yaml"
+ return get_functest_config('general.functest.testcases_yaml')
def get_functest_yaml():
diff --git a/functest/utils/openstack_utils.py b/functest/utils/openstack_utils.py
index 6f0c5fba5..15dc87c38 100755
--- a/functest/utils/openstack_utils.py
+++ b/functest/utils/openstack_utils.py
@@ -56,8 +56,19 @@ def get_credentials(service):
"""
creds = {}
+ keystone_api_version = os.getenv('OS_IDENTITY_API_VERSION')
+ if (keystone_api_version is None or
+ keystone_api_version == '2'):
+ keystone_v3 = False
+ tenant_env = 'OS_TENANT_NAME'
+ tenant = 'tenant_name'
+ else:
+ keystone_v3 = True
+ tenant_env = 'OS_PROJECT_NAME'
+ tenant = 'project_name'
+
# Check that the env vars exists:
- envvars = ('OS_USERNAME', 'OS_PASSWORD', 'OS_AUTH_URL', 'OS_TENANT_NAME')
+ envvars = ('OS_USERNAME', 'OS_PASSWORD', 'OS_AUTH_URL', tenant_env)
for envvar in envvars:
if os.getenv(envvar) is None:
raise MissingEnvVar(envvar)
@@ -69,7 +80,6 @@ def get_credentials(service):
tenant = "project_id"
else:
password = "password"
- tenant = "tenant_name"
# The most common way to pass these info to the script is to do it through
# environment variables.
@@ -77,8 +87,18 @@ def get_credentials(service):
"username": os.environ.get("OS_USERNAME"),
password: os.environ.get("OS_PASSWORD"),
"auth_url": os.environ.get("OS_AUTH_URL"),
- tenant: os.environ.get("OS_TENANT_NAME")
+ tenant: os.environ.get(tenant_env)
})
+ if keystone_v3:
+ if os.getenv('OS_USER_DOMAIN_NAME') is not None:
+ creds.update({
+ "user_domain_name": os.getenv('OS_USER_DOMAIN_NAME')
+ })
+ if os.getenv('OS_PROJECT_DOMAIN_NAME') is not None:
+ creds.update({
+ "project_domain_name": os.getenv('OS_PROJECT_DOMAIN_NAME')
+ })
+
if os.getenv('OS_ENDPOINT_TYPE') is not None:
creds.update({
"endpoint_type": os.environ.get("OS_ENDPOINT_TYPE")
@@ -113,7 +133,14 @@ def source_credentials(rc_file):
def get_credentials_for_rally():
creds = get_credentials("keystone")
- admin_keys = ['username', 'tenant_name', 'password']
+ keystone_api_version = os.getenv('OS_IDENTITY_API_VERSION')
+ if (keystone_api_version is None or
+ keystone_api_version == '2'):
+ admin_keys = ['username', 'tenant_name', 'password']
+ else:
+ admin_keys = ['username', 'password', 'user_domain_name',
+ 'project_name', 'project_domain_name']
+
endpoint_types = [('internalURL', 'internal'),
('publicURL', 'public'), ('adminURL', 'admin')]
if 'endpoint_type' in creds.keys():
diff --git a/requirements.txt b/requirements.txt
index e4d2877c0..28b3fed3e 100644..100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -12,9 +12,9 @@ python-ceilometerclient==2.6.2
python-keystoneclient==3.5.0
python-neutronclient==6.0.0
python-congressclient==1.5.0
-virtualenv==1.11.4
+virtualenv==15.1.0
pexpect==4.0
-requests==2.8.0
+requests>=2.8.0
robotframework==2.9.1
robotframework-requests==0.3.8
robotframework-sshlibrary==2.1.1
diff --git a/test-requirements.txt b/test-requirements.txt
index d65e12f6e..8be8e2033 100644..100755
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -20,4 +20,4 @@ requests==2.8.0
robotframework==2.9.1
robotframework-requests==0.3.8
robotframework-sshlibrary==2.1.1
-virtualenv==1.11.4 \ No newline at end of file
+virtualenv==15.1.0 \ No newline at end of file