diff options
21 files changed, 311 insertions, 128 deletions
@@ -20,9 +20,9 @@ Juha Kosonen <juha.kosonen@nokia.com> Valentin Boucher <valentin.boucher@orange.com> Viktor Tikkanen <viktor.tikkanen@nokia.com> Mei Mei <meimei@huawei.com> +Linda Wang <wangwulin@huawei.com> Additional contributors: -Linda Wang <wangwulin@huawei.com> Georgios Paraskevopoulos <georgepar.91@gmail.com> Romanos Skiadas <rom.skiad@gmail.com> Michael Polenchuk <mpolenchuk@mirantis.com> diff --git a/docker/Dockerfile b/docker/Dockerfile index a9eebeb7..a3ebc1a1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -14,7 +14,6 @@ LABEL version="0.1" description="OPNFV Functest Docker container" # Environment variables ARG BRANCH=master ARG RALLY_TAG=0.8.1 -ARG TEMPEST_TAG=15.0.0 ARG REFSTACK_TAG=15.0.0 ARG ODL_TAG=release/beryllium-sr4 ARG KINGBIRD_TAG=1.1.0 @@ -121,7 +120,7 @@ RUN find -L ${FUNCTEST_REPO_DIR} -name "*.py" \ RUN /bin/bash ${REPOS_DIR}/parser/tests/parser_install.sh ${REPOS_DIR} RUN wget -q https://raw.githubusercontent.com/openstack/rally/${RALLY_TAG}/install_rally.sh \ - && bash install_rally.sh --yes && rm install_rally.sh + && bash install_rally.sh --branch ${RALLY_TAG} --yes && rm install_rally.sh RUN add_images.sh diff --git a/docker/Dockerfile.aarch64 b/docker/Dockerfile.aarch64 index f9d98b23..1a7dc027 100644 --- a/docker/Dockerfile.aarch64 +++ b/docker/Dockerfile.aarch64 @@ -14,7 +14,6 @@ LABEL version="0.1" description="OPNFV Functest Aarch64 Docker container" # Environment variables ARG BRANCH=master ARG RALLY_TAG=0.8.1 -ARG TEMPEST_TAG=15.0.0 ARG REFSTACK_TAG=15.0.0 ARG ODL_TAG=release/beryllium-sr4 ARG KINGBIRD_TAG=0.2.2 @@ -113,7 +112,7 @@ RUN find -L ${FUNCTEST_REPO_DIR} -name "*.py" \ RUN /bin/bash ${REPOS_DIR}/parser/tests/parser_install.sh ${REPOS_DIR} RUN wget -q https://raw.githubusercontent.com/openstack/rally/${RALLY_TAG}/install_rally.sh \ - && bash install_rally.sh --yes && rm install_rally.sh + && bash install_rally.sh --branch ${RALLY_TAG} --yes && rm install_rally.sh RUN add_images.sh diff --git a/docker/thirdparty-requirements.txt b/docker/thirdparty-requirements.txt index 4fe98147..f51a5e29 100644 --- a/docker/thirdparty-requirements.txt +++ b/docker/thirdparty-requirements.txt @@ -5,5 +5,5 @@ git+https://gerrit.opnfv.org/gerrit/securityscanning#egg=securityscanning git+https://gerrit.opnfv.org/gerrit/sfc#egg=sfc networking-bgpvpn rally -tempest>=12.1.0 # Apache-2.0 +tempest>=15.0.0 # Apache-2.0 git+https://github.com/openstack/refstack-client#egg=refstack-client diff --git a/functest/ci/check_os.sh b/functest/ci/check_os.sh index ce0bc20c..7b66f3da 100755 --- a/functest/ci/check_os.sh +++ b/functest/ci/check_os.sh @@ -6,12 +6,18 @@ # jose.lausuch@ericsson.com # +if [[ ${OS_INSECURE,,} == "true" ]]; then + options='--insecure' +else + options='' +fi + declare -A service_cmd_array -service_cmd_array['nova']='openstack server list' -service_cmd_array['neutron']='openstack network list' -service_cmd_array['keystone']='openstack endpoint list' -service_cmd_array['cinder']='openstack volume list' -service_cmd_array['glance']='openstack image list' +service_cmd_array['nova']="openstack $options server list" +service_cmd_array['neutron']="openstack $options network list" +service_cmd_array['keystone']="openstack $options endpoint list" +service_cmd_array['cinder']="openstack $options volume list" +service_cmd_array['glance']="openstack $options image list" MANDATORY_SERVICES='nova neutron keystone glance' OPTIONAL_SERVICES='cinder' @@ -41,7 +47,7 @@ check_service() { required=$2 fi echo ">>Checking ${service} service..." - if ! openstack service list | grep -i ${service} > /dev/null; then + if ! openstack $options service list | grep -i ${service} > /dev/null; then if [ "$required" == 'false' ]; then echo "WARN: Optional Service ${service} is not enabled!" return @@ -67,7 +73,7 @@ fi echo "Checking OpenStack endpoints:" -publicURL=$(openstack catalog show identity |awk '/public/ {print $4}') +publicURL=$(openstack $options catalog show identity |awk '/public/ {print $4}') publicIP=$(echo $publicURL|sed 's/^.*http.*\:\/\///'|sed 's/.[^:]*$//') publicPort=$(echo $publicURL|grep -Po '(?<=:)\d+') https_enabled=$(echo $publicURL | grep 'https') @@ -99,11 +105,11 @@ for service in $OPTIONAL_SERVICES; do done echo "Checking External network..." -networks=($(neutron net-list -F id | tail -n +4 | head -n -1 | awk '{print $2}')) +networks=($(neutron $options net-list -F id | tail -n +4 | head -n -1 | awk '{print $2}')) is_external=False for net in "${networks[@]}" do - is_external=$(neutron net-show $net|grep "router:external"|awk '{print $4}') + is_external=$(neutron $options net-show $net|grep "router:external"|awk '{print $4}') if [ $is_external == "True" ]; then echo "External network found: $net" break diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml index ed3f2475..1199be5a 100644 --- a/functest/ci/config_functest.yaml +++ b/functest/ci/config_functest.yaml @@ -3,7 +3,7 @@ general: home: /home/opnfv repos: /home/opnfv/repos dir_repo_rally: /home/opnfv/repos/rally - repo_tempest: /home/opnfv/repos/tempest + repo_tempest: /home/opnfv/.tempest dir_repo_releng: /home/opnfv/repos/releng repo_vims_test: /home/opnfv/repos/vnfs/vims-test repo_onos: /home/opnfv/repos/onos @@ -57,9 +57,9 @@ general: snaps: use_keystone: True use_floating_ips: True -# images: -# cirros: -# disk_url: http://download.cirros-cloud.net/0.3.5/cirros-0.3.5-x86_64-disk.img + images: + cirros: + disk_file: /home/opnfv/functest/images/cirros-0.3.5-x86_64-disk.img # ARM # disk_url: http://download.cirros-cloud.net/daily/20161201/cirros-d161201-aarch64-disk.img # kernel_url: http://download.cirros-cloud.net/daily/20161201/cirros-d161201-aarch64-kernel diff --git a/functest/ci/prepare_env.py b/functest/ci/prepare_env.py index fd1f5dbf..64fcc925 100755 --- a/functest/ci/prepare_env.py +++ b/functest/ci/prepare_env.py @@ -251,8 +251,8 @@ def update_db_url(): def verify_deployment(): print_separator() logger.info("Verifying OpenStack services...") - cmd = ("sh %s" % pkg_resources.resource_filename( - 'functest', 'ci/check_os.sh')) + cmd = ("%s" % pkg_resources.resource_filename( + 'functest', 'ci/check_os.sh')) logger.debug("Executing command: %s" % cmd) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) @@ -366,7 +366,6 @@ def main(**kwargs): elif kwargs['action'] == "start": logger.info("######### Preparing Functest environment #########\n") check_env_variables() - get_deployment_handler() create_directories() source_rc_file() update_config_file() @@ -377,7 +376,6 @@ def main(**kwargs): with open(CONST.__getattribute__('env_active'), "w") as env_file: env_file.write("1") check_environment() - print_deployment_info() elif kwargs['action'] == "check": check_environment() except Exception as e: diff --git a/functest/ci/run_tests.py b/functest/ci/run_tests.py index 430f0ca8..722df14f 100755 --- a/functest/ci/run_tests.py +++ b/functest/ci/run_tests.py @@ -252,16 +252,18 @@ class Runner(object): msg.add_row([env_var, CONST.__getattribute__(env_var)]) logger.info("Deployment description: \n\n%s\n", msg) - msg = prettytable.PrettyTable( - header_style='upper', padding_width=5, - field_names=['test case', 'project', 'tier', 'duration', 'result']) - for test_case in self.executed_test_cases: - result = 'PASS' if(test_case.is_successful( - ) == test_case.EX_OK) else 'FAIL' - msg.add_row([test_case.case_name, test_case.project_name, - _tiers.get_tier_name(test_case.case_name), - test_case.get_duration(), result]) - logger.info("FUNCTEST REPORT: \n\n%s\n", msg) + if len(self.executed_test_cases) > 1: + msg = prettytable.PrettyTable( + header_style='upper', padding_width=5, + field_names=['test case', 'project', 'tier', + 'duration', 'result']) + for test_case in self.executed_test_cases: + result = 'PASS' if(test_case.is_successful( + ) == test_case.EX_OK) else 'FAIL' + msg.add_row([test_case.case_name, test_case.project_name, + _tiers.get_tier_name(test_case.case_name), + test_case.get_duration(), result]) + logger.info("FUNCTEST REPORT: \n\n%s\n", msg) logger.info("Execution exit value: %s" % self.overall_result) return self.overall_result diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml index c30292bc..2763d0c2 100644 --- a/functest/ci/testcases.yaml +++ b/functest/ci/testcases.yaml @@ -269,7 +269,6 @@ tiers: - case_name: doctor-notification - enabled: false project_name: doctor criteria: 100 blocking: false diff --git a/functest/opnfv_tests/openstack/snaps/api_check.py b/functest/opnfv_tests/openstack/snaps/api_check.py index 50f67094..43518cb4 100644 --- a/functest/opnfv_tests/openstack/snaps/api_check.py +++ b/functest/opnfv_tests/openstack/snaps/api_check.py @@ -1,4 +1,5 @@ -# Copyright (c) 2015 All rights reserved +# Copyright (c) 2017 Cable Television Laboratories, Inc. and others. +# # 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 @@ -26,8 +27,15 @@ class ApiCheck(SnapsTestRunner): self.suite = unittest.TestSuite() + def run(self, **kwargs): + """ + Builds the test suite then calls super.run() + :param kwargs: the arguments to pass on + :return: + """ test_suite_builder.add_openstack_api_tests( suite=self.suite, os_creds=self.os_creds, ext_net_name=self.ext_net_name, use_keystone=self.use_keystone) + return super(self.__class__, self).run() diff --git a/functest/opnfv_tests/openstack/snaps/health_check.py b/functest/opnfv_tests/openstack/snaps/health_check.py index 0daddcdd..4e94460c 100644 --- a/functest/opnfv_tests/openstack/snaps/health_check.py +++ b/functest/opnfv_tests/openstack/snaps/health_check.py @@ -1,4 +1,5 @@ -# Copyright (c) 2015 All rights reserved +# Copyright (c) 2017 Cable Television Laboratories, Inc. and others. +# # 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 @@ -28,6 +29,12 @@ class HealthCheck(SnapsTestRunner): self.suite = unittest.TestSuite() + def run(self, **kwargs): + """ + Builds the test suite then calls super.run() + :param kwargs: the arguments to pass on + :return: + """ image_custom_config = None if hasattr(CONST, 'snaps_images_cirros'): @@ -39,3 +46,4 @@ class HealthCheck(SnapsTestRunner): use_keystone=self.use_keystone, flavor_metadata=self.flavor_metadata, image_metadata=image_custom_config)) + return super(self.__class__, self).run() diff --git a/functest/opnfv_tests/openstack/snaps/smoke.py b/functest/opnfv_tests/openstack/snaps/smoke.py index d9f95e90..c3c55c7c 100644 --- a/functest/opnfv_tests/openstack/snaps/smoke.py +++ b/functest/opnfv_tests/openstack/snaps/smoke.py @@ -1,4 +1,5 @@ -# Copyright (c) 2015 All rights reserved +# Copyright (c) 2017 Cable Television Laboratories, Inc. and others. +# # 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 @@ -28,6 +29,12 @@ class SnapsSmoke(SnapsTestRunner): self.suite = unittest.TestSuite() + def run(self, **kwargs): + """ + Builds the test suite then calls super.run() + :param kwargs: the arguments to pass on + :return: + """ image_config = None if hasattr(CONST, 'snaps_images_cirros'): image_config = CONST.__getattribute__('snaps_images_cirros') @@ -47,3 +54,4 @@ class SnapsSmoke(SnapsTestRunner): flavor_metadata=self.flavor_metadata, image_metadata=image_config, use_floating_ips=self.use_fip) + return super(self.__class__, self).run() diff --git a/functest/opnfv_tests/openstack/vping/vping_userdata.py b/functest/opnfv_tests/openstack/vping/vping_userdata.py index b69b3955..718f47f0 100755 --- a/functest/opnfv_tests/openstack/vping/vping_userdata.py +++ b/functest/opnfv_tests/openstack/vping/vping_userdata.py @@ -97,7 +97,7 @@ class VPingUserdata(vping_base.VPingBase): while True: time.sleep(1) - p_console = vm_creator.get_vm_inst().get_console_output() + p_console = vm_creator.get_os_vm_server_obj().get_console_output() if "vPing OK" in p_console: self.logger.info("vPing detected!") exit_code = TestCase.EX_OK diff --git a/functest/tests/unit/ci/test_prepare_env.py b/functest/tests/unit/ci/test_prepare_env.py index f3e15a01..69abd643 100644 --- a/functest/tests/unit/ci/test_prepare_env.py +++ b/functest/tests/unit/ci/test_prepare_env.py @@ -424,7 +424,6 @@ class PrepareEnvTesting(unittest.TestCase): mock_logger_info.assert_any_call("Functest environment" " is installed.") - @mock.patch('functest.ci.prepare_env.print_deployment_info') @mock.patch('functest.ci.prepare_env.check_environment') @mock.patch('functest.ci.prepare_env.create_flavor') @mock.patch('functest.ci.prepare_env.install_tempest') @@ -433,21 +432,19 @@ class PrepareEnvTesting(unittest.TestCase): @mock.patch('functest.ci.prepare_env.update_config_file') @mock.patch('functest.ci.prepare_env.source_rc_file') @mock.patch('functest.ci.prepare_env.create_directories') - @mock.patch('functest.ci.prepare_env.get_deployment_handler') @mock.patch('functest.ci.prepare_env.check_env_variables') @mock.patch('functest.ci.prepare_env.logger.info') - def test_main_start(self, mock_logger_info, mock_env_var, mock_dep_handler, + def test_main_start(self, mock_logger_info, mock_env_var, mock_create_dir, mock_source_rc, mock_update_config, mock_verify_depl, mock_install_rally, mock_install_temp, mock_create_flavor, - mock_check_env, mock_print_info): + mock_check_env): with mock.patch("__builtin__.open", mock.mock_open()) as m: args = {'action': 'start'} self.assertEqual(prepare_env.main(**args), 0) mock_logger_info.assert_any_call("######### Preparing Functest " "environment #########\n") self.assertTrue(mock_env_var.called) - self.assertTrue(mock_dep_handler.called) self.assertTrue(mock_create_dir.called) self.assertTrue(mock_source_rc.called) self.assertTrue(mock_update_config.called) @@ -458,7 +455,6 @@ class PrepareEnvTesting(unittest.TestCase): m.assert_called_once_with( CONST.__getattribute__('env_active'), "w") self.assertTrue(mock_check_env.called) - self.assertTrue(mock_print_info.called) @mock.patch('functest.ci.prepare_env.check_environment') def test_main_check(self, mock_check_env): diff --git a/functest/tests/unit/openstack/snaps/test_snaps.py b/functest/tests/unit/openstack/snaps/test_snaps.py index 9cfcc0a6..7cf53b39 100644 --- a/functest/tests/unit/openstack/snaps/test_snaps.py +++ b/functest/tests/unit/openstack/snaps/test_snaps.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # Copyright (c) 2017 Cable Television Laboratories, Inc. and others. # # All rights reserved. This program and the accompanying materials @@ -9,12 +7,14 @@ # http://www.apache.org/licenses/LICENSE-2.0 import mock +import os import unittest from snaps.openstack.os_credentials import OSCreds from functest.core.testcase import TestCase -from functest.opnfv_tests.openstack.snaps import connection_check +from functest.opnfv_tests.openstack.snaps import (connection_check, api_check, + health_check, smoke) class ConnectionCheckTesting(unittest.TestCase): @@ -31,10 +31,8 @@ class ConnectionCheckTesting(unittest.TestCase): self.connection_check = connection_check.ConnectionCheck( os_creds=self.os_creds, ext_net_name='foo') - @mock.patch('functest.opnfv_tests.openstack.snaps.connection_check.' - 'ConnectionCheck') @mock.patch('snaps.test_suite_builder.add_openstack_client_tests') - def test_run_success(self, mock_test, add_os_client_tests): + def test_run_success(self, add_os_client_tests): result = mock.MagicMock(name='unittest.TextTestResult') result.testsRun = 100 result.failures = [] @@ -44,10 +42,8 @@ class ConnectionCheckTesting(unittest.TestCase): self.assertEquals(TestCase.EX_OK, self.connection_check.is_successful()) - @mock.patch('functest.opnfv_tests.openstack.snaps.connection_check.' - 'ConnectionCheck') @mock.patch('snaps.test_suite_builder.add_openstack_client_tests') - def test_run_1_of_100_failures(self, mock_test, add_os_client_tests): + def test_run_1_of_100_failures(self, add_os_client_tests): result = mock.MagicMock(name='unittest.TextTestResult') result.testsRun = 100 result.failures = ['foo'] @@ -57,11 +53,8 @@ class ConnectionCheckTesting(unittest.TestCase): self.assertEquals(TestCase.EX_TESTCASE_FAILED, self.connection_check.is_successful()) - @mock.patch('functest.opnfv_tests.openstack.snaps.connection_check.' - 'ConnectionCheck') @mock.patch('snaps.test_suite_builder.add_openstack_client_tests') - def test_run_1_of_100_failures_within_criteria(self, mock_test, - add_os_client_tests): + def test_run_1_of_100_failures_within_criteria(self, add_os_client_tests): self.connection_check.criteria = 90 result = mock.MagicMock(name='unittest.TextTestResult') result.testsRun = 100 @@ -71,3 +64,153 @@ class ConnectionCheckTesting(unittest.TestCase): self.assertEquals(TestCase.EX_OK, self.connection_check.run()) self.assertEquals(TestCase.EX_OK, self.connection_check.is_successful()) + + +class APICheckTesting(unittest.TestCase): + """ + Ensures the VPingUserdata class can run in Functest. This test does not + actually connect with an OpenStack pod. + """ + + def setUp(self): + self.os_creds = OSCreds( + username='user', password='pass', + auth_url='http://foo.com:5000/v3', project_name='bar') + + self.api_check = api_check.ApiCheck( + os_creds=self.os_creds, ext_net_name='foo') + + @mock.patch('snaps.test_suite_builder.add_openstack_api_tests') + def test_run_success(self, add_tests): + result = mock.MagicMock(name='unittest.TextTestResult') + result.testsRun = 100 + result.failures = [] + result.errors = [] + with mock.patch('unittest.TextTestRunner.run', return_value=result): + self.assertEquals(TestCase.EX_OK, self.api_check.run()) + self.assertEquals(TestCase.EX_OK, + self.api_check.is_successful()) + + @mock.patch('snaps.test_suite_builder.add_openstack_api_tests') + def test_run_1_of_100_failures(self, add_tests): + result = mock.MagicMock(name='unittest.TextTestResult') + result.testsRun = 100 + result.failures = ['foo'] + result.errors = [] + with mock.patch('unittest.TextTestRunner.run', return_value=result): + self.assertEquals(TestCase.EX_OK, self.api_check.run()) + self.assertEquals(TestCase.EX_TESTCASE_FAILED, + self.api_check.is_successful()) + + @mock.patch('snaps.test_suite_builder.add_openstack_api_tests') + def test_run_1_of_100_failures_within_criteria(self, add_tests): + self.api_check.criteria = 90 + result = mock.MagicMock(name='unittest.TextTestResult') + result.testsRun = 100 + result.failures = ['foo'] + result.errors = [] + with mock.patch('unittest.TextTestRunner.run', return_value=result): + self.assertEquals(TestCase.EX_OK, self.api_check.run()) + self.assertEquals(TestCase.EX_OK, + self.api_check.is_successful()) + + +class HealthCheckTesting(unittest.TestCase): + """ + Ensures the VPingUserdata class can run in Functest. This test does not + actually connect with an OpenStack pod. + """ + + def setUp(self): + self.os_creds = OSCreds( + username='user', password='pass', + auth_url='http://foo.com:5000/v3', project_name='bar') + + self.health_check = health_check.HealthCheck( + os_creds=self.os_creds, ext_net_name='foo') + + @mock.patch('snaps.test_suite_builder.add_openstack_client_tests') + def test_run_success(self, add_tests): + result = mock.MagicMock(name='unittest.TextTestResult') + result.testsRun = 100 + result.failures = [] + result.errors = [] + with mock.patch('unittest.TextTestRunner.run', return_value=result): + self.assertEquals(TestCase.EX_OK, self.health_check.run()) + self.assertEquals(TestCase.EX_OK, + self.health_check.is_successful()) + + @mock.patch('snaps.test_suite_builder.add_openstack_client_tests') + def test_run_1_of_100_failures(self, add_tests): + result = mock.MagicMock(name='unittest.TextTestResult') + result.testsRun = 100 + result.failures = ['foo'] + result.errors = [] + with mock.patch('unittest.TextTestRunner.run', return_value=result): + self.assertEquals(TestCase.EX_OK, self.health_check.run()) + self.assertEquals(TestCase.EX_TESTCASE_FAILED, + self.health_check.is_successful()) + + @mock.patch('snaps.test_suite_builder.add_openstack_client_tests') + def test_run_1_of_100_failures_within_criteria(self, add_tests): + self.health_check.criteria = 90 + result = mock.MagicMock(name='unittest.TextTestResult') + result.testsRun = 100 + result.failures = ['foo'] + result.errors = [] + with mock.patch('unittest.TextTestRunner.run', return_value=result): + self.assertEquals(TestCase.EX_OK, self.health_check.run()) + self.assertEquals(TestCase.EX_OK, + self.health_check.is_successful()) + + +class SmokeTesting(unittest.TestCase): + """ + Ensures the VPingUserdata class can run in Functest. This test does not + actually connect with an OpenStack pod. + """ + + def setUp(self): + self.os_creds = OSCreds( + username='user', password='pass', + auth_url='http://foo.com:5000/v3', project_name='bar') + + self.smoke = smoke.SnapsSmoke( + os_creds=self.os_creds, ext_net_name='foo') + + @mock.patch('snaps.test_suite_builder.add_openstack_integration_tests') + @mock.patch('os.path.join', return_value=os.getcwd()) + def test_run_success(self, add_tests, cwd): + result = mock.MagicMock(name='unittest.TextTestResult') + result.testsRun = 100 + result.failures = [] + result.errors = [] + with mock.patch('unittest.TextTestRunner.run', return_value=result): + self.assertEquals(TestCase.EX_OK, self.smoke.run()) + self.assertEquals(TestCase.EX_OK, + self.smoke.is_successful()) + + @mock.patch('snaps.test_suite_builder.add_openstack_integration_tests') + @mock.patch('os.path.join', return_value=os.getcwd()) + def test_run_1_of_100_failures(self, add_tests, cwd): + result = mock.MagicMock(name='unittest.TextTestResult') + result.testsRun = 100 + result.failures = ['foo'] + result.errors = [] + with mock.patch('unittest.TextTestRunner.run', return_value=result): + self.assertEquals(TestCase.EX_OK, self.smoke.run()) + self.assertEquals(TestCase.EX_TESTCASE_FAILED, + self.smoke.is_successful()) + + @mock.patch('snaps.test_suite_builder.add_openstack_integration_tests') + @mock.patch('os.path.join', return_value=os.getcwd()) + def test_run_1_of_100_failures_within_criteria(self, add_tests, cwd): + self.smoke.criteria = 90 + result = mock.MagicMock(name='unittest.TextTestResult') + result.testsRun = 100 + result.failures = ['foo'] + result.errors = [] + with mock.patch('unittest.TextTestRunner.run', return_value=result): + self.assertEquals(TestCase.EX_OK, self.smoke.run()) + self.assertEquals(TestCase.EX_OK, + self.smoke.is_successful()) diff --git a/functest/tests/unit/utils/test_openstack_clean.py b/functest/tests/unit/utils/test_openstack_clean.py index fe7b50d4..6ae7faa4 100644 --- a/functest/tests/unit/utils/test_openstack_clean.py +++ b/functest/tests/unit/utils/test_openstack_clean.py @@ -61,6 +61,8 @@ class OSCleanTesting(unittest.TestCase): {'id': 'id2', 'name': 'name2', 'ip': 'ip2', 'router:external': False, 'external_gateway_info': None}] + self.floatingips_list = [{'id': 'id1', 'floating_ip_address': 'ip1'}, + {'id': 'id2', 'floating_ip_address': 'ip2'}] self.routers = [mock.Mock()] self.ports = [mock.Mock()] @@ -254,7 +256,8 @@ class OSCleanTesting(unittest.TestCase): @mock.patch('functest.utils.openstack_clean.logger.debug') def test_remove_floatingips(self, mock_logger_debug): with mock.patch('functest.utils.openstack_clean.os_utils' - '.get_floating_ips', return_value=self.test_list): + '.get_floating_ips', + return_value=self.floatingips_list): openstack_clean.remove_floatingips(self.client, self.update_list) mock_logger_debug.assert_any_call("Removing floating IPs...") mock_logger_debug.assert_any_call(" > this is a default " @@ -272,9 +275,10 @@ class OSCleanTesting(unittest.TestCase): @mock.patch('functest.utils.openstack_clean.logger.debug') def test_remove_floatingips_delete_success(self, mock_logger_debug): with mock.patch('functest.utils.openstack_clean.os_utils' - '.get_floating_ips', return_value=self.test_list), \ + '.get_floating_ips', + return_value=self.floatingips_list), \ mock.patch('functest.utils.openstack_clean.os_utils' - '.delete_volume', return_value=True): + '.delete_floating_ip', return_value=True): openstack_clean.remove_floatingips(self.client, self.remove_list) mock_logger_debug.assert_any_call("Removing floating IPs...") mock_logger_debug.assert_any_call(" > Done!") @@ -287,7 +291,8 @@ class OSCleanTesting(unittest.TestCase): def test_remove_floatingips_delete_failed(self, mock_logger_debug, mock_logger_error): with mock.patch('functest.utils.openstack_clean.os_utils' - '.get_floating_ips', return_value=self.test_list), \ + '.get_floating_ips', + return_value=self.floatingips_list), \ mock.patch('functest.utils.openstack_clean.os_utils' '.delete_floating_ip', return_value=False): openstack_clean.remove_floatingips(self.client, self.remove_list) @@ -672,6 +677,7 @@ class OSCleanTesting(unittest.TestCase): RegexMatch(" Removing " "\s*\S+...")) + @mock.patch('functest.utils.openstack_clean.os_utils.get_glance_client') @mock.patch('functest.utils.openstack_clean.os_utils.get_cinder_client') @mock.patch('functest.utils.openstack_clean.os_utils' '.get_keystone_client') @@ -684,7 +690,7 @@ class OSCleanTesting(unittest.TestCase): @mock.patch('functest.utils.openstack_clean.logger.debug') def test_main_default(self, mock_logger_debug, mock_logger_info, mock_creds, mock_nova, mock_neutron, - mock_keystone, mock_cinder): + mock_keystone, mock_cinder, mock_glance): with mock.patch('functest.utils.openstack_clean.remove_instances') \ as mock_remove_instances, \ diff --git a/functest/tests/unit/utils/test_openstack_snapshot.py b/functest/tests/unit/utils/test_openstack_snapshot.py index d3f93994..33e74609 100644 --- a/functest/tests/unit/utils/test_openstack_snapshot.py +++ b/functest/tests/unit/utils/test_openstack_snapshot.py @@ -12,7 +12,7 @@ import unittest from functest.utils import openstack_snapshot -class OSTackerTesting(unittest.TestCase): +class OSSnapshotTesting(unittest.TestCase): def _get_instance(self, key): mock_obj = mock.Mock() @@ -26,6 +26,8 @@ class OSTackerTesting(unittest.TestCase): self.test_list = [self._get_instance(1), self._get_instance(2)] self.update_list = {'id1': 'name1', 'id2': 'name2'} self.update_floatingips = {'id1': 'ip1', 'id2': 'ip2'} + self.floatingips_list = [{'id': 'id1', 'floating_ip_address': 'ip1'}, + {'id': 'id2', 'floating_ip_address': 'ip2'}] self.test_dict_list = [{'id': 'id1', 'name': 'name1', 'ip': 'ip1'}, {'id': 'id2', 'name': 'name2', 'ip': 'ip2'}] @@ -138,8 +140,9 @@ class OSTackerTesting(unittest.TestCase): @mock.patch('functest.utils.openstack_snapshot.logger.debug') def test_get_floatingips(self, mock_logger_debug): with mock.patch('functest.utils.openstack_snapshot.os_utils' - '.get_floating_ips', return_value=self.test_list): - resp = openstack_snapshot.get_floatinips(self.client) + '.get_floating_ips', + return_value=self.floatingips_list): + resp = openstack_snapshot.get_floatingips(self.client) mock_logger_debug.assert_called_once_with("Getting Floating " "IPs...") self.assertDictEqual(resp, {'floatingips': @@ -149,7 +152,7 @@ class OSTackerTesting(unittest.TestCase): def test_get_floatingips_missing_floatingips(self, mock_logger_debug): with mock.patch('functest.utils.openstack_snapshot.os_utils' '.get_floating_ips', return_value=[]): - resp = openstack_snapshot.get_floatinips(self.client) + resp = openstack_snapshot.get_floatingips(self.client) mock_logger_debug.assert_called_once_with("Getting Floating " "IPs...") self.assertDictEqual(resp, {'floatingips': {}}) @@ -186,6 +189,7 @@ class OSTackerTesting(unittest.TestCase): mock_logger_debug.assert_called_once_with("Getting tenants...") self.assertDictEqual(resp, {'tenants': {}}) + @mock.patch('functest.utils.openstack_clean.os_utils.get_glance_client') @mock.patch('functest.utils.openstack_snapshot.os_utils.get_cinder_client') @mock.patch('functest.utils.openstack_snapshot.os_utils' '.get_keystone_client') @@ -197,7 +201,7 @@ class OSTackerTesting(unittest.TestCase): @mock.patch('functest.utils.openstack_snapshot.logger.debug') def test_main_default(self, mock_logger_debug, mock_logger_info, mock_creds, mock_nova, mock_neutron, - mock_keystone, mock_cinder): + mock_keystone, mock_cinder, mock_glance): with mock.patch('functest.utils.openstack_snapshot.get_instances', return_value=self.update_list), \ mock.patch('functest.utils.openstack_snapshot.get_images', @@ -212,7 +216,7 @@ class OSTackerTesting(unittest.TestCase): return_value=self.update_list), \ mock.patch('functest.utils.openstack_snapshot.get_security_groups', return_value=self.update_list), \ - mock.patch('functest.utils.openstack_snapshot.get_floatinips', + mock.patch('functest.utils.openstack_snapshot.get_floatingips', return_value=self.update_floatingips), \ mock.patch('functest.utils.openstack_snapshot.get_users', return_value=self.update_list), \ diff --git a/functest/tests/unit/utils/test_openstack_utils.py b/functest/tests/unit/utils/test_openstack_utils.py index 0f06b1e1..74b49aaa 100644 --- a/functest/tests/unit/utils/test_openstack_utils.py +++ b/functest/tests/unit/utils/test_openstack_utils.py @@ -27,7 +27,8 @@ class OSUtilsTesting(unittest.TestCase): 'OS_PROJECT_NAME': os_prefix + 'project_name', 'OS_ENDPOINT_TYPE': os_prefix + 'endpoint_type', 'OS_REGION_NAME': os_prefix + 'region_name', - 'OS_CACERT': os_prefix + 'https_cacert'} + 'OS_CACERT': os_prefix + 'https_cacert', + 'OS_INSECURE': os_prefix + 'https_insecure'} def _get_os_env_vars(self): return {'username': 'test_username', 'password': 'test_password', @@ -37,7 +38,8 @@ class OSUtilsTesting(unittest.TestCase): 'project_name': 'test_project_name', 'endpoint_type': 'test_endpoint_type', 'region_name': 'test_region_name', - 'https_cacert': 'test_https_cacert'} + 'https_cacert': 'test_https_cacert', + 'https_insecure': 'test_https_insecure'} def setUp(self): self.env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD'] @@ -75,9 +77,8 @@ class OSUtilsTesting(unittest.TestCase): self.availability_zone = mock_obj mock_obj = mock.Mock() - attrs = {'id': 'floating_id', - 'zoneName': 'test_floating_ip', - 'status': 'ok'} + attrs = {'floating_network_id': 'floating_id', + 'floating_ip_address': 'test_floating_ip'} mock_obj.configure_mock(**attrs) self.floating_ip = mock_obj @@ -113,8 +114,6 @@ class OSUtilsTesting(unittest.TestCase): 'aggregates.delete.return_value': mock.Mock(), 'availability_zones.list.return_value': [self.availability_zone], - 'floating_ips.list.return_value': [self.floating_ip], - 'floating_ips.delete.return_value': mock.Mock(), 'hypervisors.list.return_value': [self.hypervisor], 'create.return_value': mock.Mock(), 'add_security_group.return_value': mock.Mock(), @@ -271,7 +270,10 @@ class OSUtilsTesting(unittest.TestCase): 'create_security_group.return_value': {'security_group': self.sec_group}, 'update_quota.return_value': mock.Mock(), - 'delete_security_group.return_value': mock.Mock() + 'delete_security_group.return_value': mock.Mock(), + 'list_floatingips.return_value': {'floatingips': + [self.floating_ip]}, + 'delete_floatingip.return_value': mock.Mock(), } self.neutron_client.configure_mock(**attrs) @@ -721,7 +723,7 @@ class OSUtilsTesting(unittest.TestCase): def test_get_floating_ips_default(self): self.assertEqual(openstack_utils. - get_floating_ips(self.nova_client), + get_floating_ips(self.neutron_client), [self.floating_ip]) @mock.patch('functest.utils.openstack_utils.logger.error') @@ -867,7 +869,7 @@ class OSUtilsTesting(unittest.TestCase): def test_delete_floating_ip_default(self): self.assertTrue(openstack_utils. - delete_floating_ip(self.nova_client, + delete_floating_ip(self.neutron_client, 'floating_ip_id')) @mock.patch('functest.utils.openstack_utils.logger.error') @@ -1472,7 +1474,7 @@ class OSUtilsTesting(unittest.TestCase): def test_get_images_default(self): self.assertEqual(openstack_utils. - get_images(self.nova_client), + get_images(self.glance_client), [self.image]) @mock.patch('functest.utils.openstack_utils.logger.error') diff --git a/functest/utils/openstack_clean.py b/functest/utils/openstack_clean.py index 0ce08798..e88245d6 100755 --- a/functest/utils/openstack_clean.py +++ b/functest/utils/openstack_clean.py @@ -80,22 +80,25 @@ def remove_instances(nova_client, default_instances): break -def remove_images(nova_client, default_images): +def remove_images(glance_client, default_images): logger.debug("Removing Glance images...") - images = os_utils.get_images(nova_client) - if images is None or len(images) == 0: + images = os_utils.get_images(glance_client) + if images is None: + return -1 + images = {image.id: image.name for image in images} + if len(images) == 0: logger.debug("No images found.") return for image in images: - image_name = getattr(image, 'name') - image_id = getattr(image, 'id') + image_id = image + image_name = images.get(image_id) logger.debug("'%s', ID=%s " % (image_name, image_id)) if (image_id not in default_images and image_name not in default_images.values()): logger.debug("Removing image '%s', ID=%s ..." % (image_name, image_id)) - if os_utils.delete_glance_image(nova_client, image_id): + if os_utils.delete_glance_image(glance_client, image_id): logger.debug(" > Done!") else: logger.error("There has been a problem removing the" @@ -135,9 +138,9 @@ def remove_volumes(cinder_client, default_volumes): "NOT be deleted.") -def remove_floatingips(nova_client, default_floatingips): +def remove_floatingips(neutron_client, default_floatingips): logger.debug("Removing floating IPs...") - floatingips = os_utils.get_floating_ips(nova_client) + floatingips = os_utils.get_floating_ips(neutron_client) if floatingips is None or len(floatingips) == 0: logger.debug("No floating IPs found.") return @@ -145,13 +148,13 @@ def remove_floatingips(nova_client, default_floatingips): init_len = len(floatingips) deleted = 0 for fip in floatingips: - fip_id = getattr(fip, 'id') - fip_ip = getattr(fip, 'ip') + fip_id = fip['id'] + fip_ip = fip['floating_ip_address'] logger.debug("'%s', ID=%s " % (fip_ip, fip_id)) if (fip_id not in default_floatingips and fip_ip not in default_floatingips.values()): logger.debug("Removing floating IP %s ..." % fip_id) - if os_utils.delete_floating_ip(nova_client, fip_id): + if os_utils.delete_floating_ip(neutron_client, fip_id): logger.debug(" > Done!") deleted += 1 else: @@ -163,7 +166,7 @@ def remove_floatingips(nova_client, default_floatingips): timeout = 50 while timeout > 0: - floatingips = os_utils.get_floating_ips(nova_client) + floatingips = os_utils.get_floating_ips(neutron_client) if floatingips is None or len(floatingips) == (init_len - deleted): break else: @@ -385,6 +388,7 @@ def main(): neutron_client = os_utils.get_neutron_client() keystone_client = os_utils.get_keystone_client() cinder_client = os_utils.get_cinder_client() + glance_client = os_utils.get_glance_client() try: with open(OS_SNAPSHOT_FILE) as f: @@ -411,11 +415,11 @@ def main(): remove_instances(nova_client, default_instances) separator() - remove_images(nova_client, default_images) + remove_images(glance_client, default_images) separator() remove_volumes(cinder_client, default_volumes) separator() - remove_floatingips(nova_client, default_floatingips) + remove_floatingips(neutron_client, default_floatingips) separator() remove_networks(neutron_client, default_networks, default_routers) separator() diff --git a/functest/utils/openstack_snapshot.py b/functest/utils/openstack_snapshot.py index 233c316a..f4ef751c 100755 --- a/functest/utils/openstack_snapshot.py +++ b/functest/utils/openstack_snapshot.py @@ -48,13 +48,13 @@ def get_instances(nova_client): return {'instances': dic_instances} -def get_images(nova_client): +def get_images(glance_client): logger.debug("Getting images...") dic_images = {} - images = os_utils.get_images(nova_client) - if not (images is None or len(images) == 0): - for image in images: - dic_images.update({getattr(image, 'id'): getattr(image, 'name')}) + images = os_utils.get_images(glance_client) + if images is None: + return -1 + dic_images.update({image.id: image.name for image in images}) return {'images': dic_images} @@ -98,13 +98,14 @@ def get_security_groups(neutron_client): return {'secgroups': dic_secgroups} -def get_floatinips(nova_client): +def get_floatingips(neutron_client): logger.debug("Getting Floating IPs...") dic_floatingips = {} - floatingips = os_utils.get_floating_ips(nova_client) + floatingips = os_utils.get_floating_ips(neutron_client) if not (floatingips is None or len(floatingips) == 0): for floatingip in floatingips: - dic_floatingips.update({floatingip.id: floatingip.ip}) + dic_floatingips.update({floatingip['id']: + floatingip['floating_ip_address']}) return {'floatingips': dic_floatingips} @@ -136,6 +137,7 @@ def main(): neutron_client = os_utils.get_neutron_client() keystone_client = os_utils.get_keystone_client() cinder_client = os_utils.get_cinder_client() + glance_client = os_utils.get_glance_client() if not os_utils.check_credentials(): logger.error("Please source the openrc credentials and run the" + @@ -144,12 +146,12 @@ def main(): snapshot = {} snapshot.update(get_instances(nova_client)) - snapshot.update(get_images(nova_client)) + snapshot.update(get_images(glance_client)) snapshot.update(get_volumes(cinder_client)) snapshot.update(get_networks(neutron_client)) snapshot.update(get_routers(neutron_client)) snapshot.update(get_security_groups(neutron_client)) - snapshot.update(get_floatinips(nova_client)) + snapshot.update(get_floatingips(neutron_client)) snapshot.update(get_users(keystone_client)) snapshot.update(get_tenants(keystone_client)) diff --git a/functest/utils/openstack_utils.py b/functest/utils/openstack_utils.py index f155449d..e7cdfc86 100644 --- a/functest/utils/openstack_utils.py +++ b/functest/utils/openstack_utils.py @@ -82,7 +82,8 @@ def get_env_cred_dict(): 'OS_PROJECT_NAME': 'project_name', 'OS_ENDPOINT_TYPE': 'endpoint_type', 'OS_REGION_NAME': 'region_name', - 'OS_CACERT': 'https_cacert' + 'OS_CACERT': 'https_cacert', + 'OS_INSECURE': 'https_insecure' } return env_cred_dict @@ -150,10 +151,12 @@ def get_credentials_for_rally(): cred_key = env_cred_dict.get('OS_REGION_NAME') rally_conf[cred_key] = region_name - cacert = os.getenv('OS_CACERT') - if cacert is not None: - cred_key = env_cred_dict.get('OS_CACERT') - rally_conf[cred_key] = cacert + cred_key = env_cred_dict.get('OS_CACERT') + rally_conf[cred_key] = os.getenv('OS_CACERT', '') + + insecure_key = env_cred_dict.get('OS_INSECURE') + rally_conf[insecure_key] = os.getenv('OS_INSECURE', '').lower() == 'true' + return rally_conf @@ -181,14 +184,10 @@ def get_endpoint(service_type, endpoint_type='publicURL'): def get_session(other_creds={}): auth = get_session_auth(other_creds) - cacert = os.getenv('OS_CACERT') - if cacert is not None: - if not os.path.isfile(cacert): - raise Exception("The 'OS_CACERT' environment" - "variable is set to %s but the file" - "does not exist.", cacert) - - return session.Session(auth=auth, verify=cacert) + https_cacert = os.getenv('OS_CACERT', '') + https_insecure = os.getenv('OS_INSECURE', '').lower() == 'true' + return session.Session(auth=auth, + verify=(https_cacert or not https_insecure)) # ********************************************* @@ -426,12 +425,12 @@ def get_or_create_flavor(flavor_name, ram, disk, vcpus, public=True): return flavor_exists, flavor_id -def get_floating_ips(nova_client): +def get_floating_ips(neutron_client): try: - floating_ips = nova_client.floating_ips.list() - return floating_ips + floating_ips = neutron_client.list_floatingips() + return floating_ips['floatingips'] except Exception as e: - logger.error("Error [get_floating_ips(nova_client)]: %s" % e) + logger.error("Error [get_floating_ips(neutron_client)]: %s" % e) return None @@ -594,12 +593,12 @@ def delete_instance(nova_client, instance_id): return False -def delete_floating_ip(nova_client, floatingip_id): +def delete_floating_ip(neutron_client, floatingip_id): try: - nova_client.floating_ips.delete(floatingip_id) + neutron_client.delete_floatingip(floatingip_id) return True except Exception as e: - logger.error("Error [delete_floating_ip(nova_client, '%s')]: %s" + logger.error("Error [delete_floating_ip(neutron_client, '%s')]: %s" % (floatingip_id, e)) return False @@ -1192,9 +1191,9 @@ def delete_security_group(neutron_client, secgroup_id): # ********************************************* # GLANCE # ********************************************* -def get_images(nova_client): +def get_images(glance_client): try: - images = nova_client.images.list() + images = glance_client.images.list() return images except Exception as e: logger.error("Error [get_images]: %s" % e) @@ -1258,12 +1257,12 @@ def get_or_create_image(name, path, format): return image_exists, image_id -def delete_glance_image(nova_client, image_id): +def delete_glance_image(glance_client, image_id): try: - nova_client.images.delete(image_id) + glance_client.images.delete(image_id) return True except Exception as e: - logger.error("Error [delete_glance_image(nova_client, '%s')]: %s" + logger.error("Error [delete_glance_image(glance_client, '%s')]: %s" % (image_id, e)) return False |