diff options
53 files changed, 1932 insertions, 231 deletions
diff --git a/docker/Dockerfile b/docker/Dockerfile index 81c3c540..af3f8ecd 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -14,7 +14,8 @@ LABEL version="0.1" description="OPNFV Functest Docker container" # Environment variables ARG BRANCH=master ARG RALLY_TAG=0.8.1 -ARG TEMPEST_TAG=14.0.0 +ARG TEMPEST_TAG=15.0.0 +ARG REFSTACK_TAG=15.0.0 ARG ODL_TAG=release/beryllium-sr4 ARG OPENSTACK_TAG=stable/mitaka ARG KINGBIRD_TAG=0.2.2 @@ -83,9 +84,9 @@ RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/sdnvpn ${REPO RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/domino ${REPOS_DIR}/domino RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/parser ${REPOS_DIR}/parser RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/doctor ${REPOS_DIR}/doctor -RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/ovno ${REPOS_DIR}/ovno RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/promise ${REPOS_DIR}/promise RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/netready ${REPOS_DIR}/netready +RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/fds ${REPOS_DIR}/fds RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/barometer ${REPOS_DIR}/barometer RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/sfc ${REPOS_DIR}/sfc RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/snaps ${REPOS_DIR}/snaps @@ -97,6 +98,7 @@ RUN git clone --depth 1 -b $OPENSTACK_TAG https://github.com/openstack/networkin RUN git clone --depth 1 -b $KINGBIRD_TAG https://github.com/openstack/kingbird.git ${REPOS_DIR}/kingbird RUN git clone --depth 1 -b $RALLY_TAG https://github.com/openstack/rally.git ${REPOS_DIR}/rally RUN git clone --depth 1 -b $TEMPEST_TAG https://github.com/openstack/tempest.git ${REPOS_DIR}/tempest +RUN git clone https://github.com/openstack/refstack-client ${REPOS_DIR}/refstack-client # other repositories RUN git clone --depth 1 -b $ODL_TAG https://git.opendaylight.org/gerrit/p/integration/test.git ${REPOS_DIR}/odl_test @@ -118,8 +120,20 @@ RUN cd ${REPOS_DIR}/barometer \ && pip install . RUN find ${FUNCTEST_REPO_DIR} -name "*.py" \ - -not -path "*tests/unit*" |xargs grep __main__ |cut -d\: -f 1 |xargs chmod -c 755 \ - && find ${FUNCTEST_REPO_DIR} -name "*.sh" |xargs grep \#\! |cut -d\: -f 1 |xargs chmod -c 755 + -not -path "*tests/unit*" \ + -not -path "*functest_venv*" \ + |xargs grep -L __main__ |cut -d\: -f 1 |xargs chmod -c 644 \ + && find ${FUNCTEST_REPO_DIR} -name "*.sh" \ + -not -path "*functest_venv*" \ + |xargs grep -L \#\! |cut -d\: -f 1 |xargs chmod -c 644 + +RUN find ${FUNCTEST_REPO_DIR} -name "*.py" \ + -not -path "*tests/unit*" \ + -not -path "*functest_venv*" \ + |xargs grep __main__ |cut -d\: -f 1 |xargs chmod -c 755 \ + && find ${FUNCTEST_REPO_DIR} -name "*.sh" \ + -not -path "*functest_venv*" \ + |xargs grep \#\! |cut -d\: -f 1 |xargs chmod -c 755 RUN /bin/bash ${REPOS_DIR}/parser/tests/parser_install.sh ${REPOS_DIR} RUN ${REPOS_DIR}/rally/install_rally.sh --yes @@ -143,6 +157,9 @@ RUN cd ${REPOS_DIR}/bgpvpn && pip install -e . # Kingbird integration RUN cd ${REPOS_DIR}/kingbird && pip install -e . +# refstack-client integration +RUN cd ${REPOS_DIR}/refstack-client && ./setup_env -t ${REFSTACK_TAG} + RUN /bin/bash -c ". /etc/profile.d/rvm.sh \ && cd ${REPOS_VNFS_DIR}/vims-test \ && rvm autolibs enable" diff --git a/docker/Dockerfile.aarch64 b/docker/Dockerfile.aarch64 index 82add067..60f72a29 100644 --- a/docker/Dockerfile.aarch64 +++ b/docker/Dockerfile.aarch64 @@ -14,7 +14,8 @@ LABEL version="0.1" description="OPNFV Functest Aarch64 Docker container" # Environment variables ARG BRANCH=master ARG RALLY_TAG=0.8.1 -ARG TEMPEST_TAG=14.0.0 +ARG TEMPEST_TAG=15.0.0 +ARG REFSTACK_TAG=15.0.0 ARG ODL_TAG=release/beryllium-sr4 ARG OPENSTACK_TAG=stable/mitaka ARG KINGBIRD_TAG=0.2.2 @@ -82,7 +83,6 @@ RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/sdnvpn ${REPO RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/domino ${REPOS_DIR}/domino RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/parser ${REPOS_DIR}/parser RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/doctor ${REPOS_DIR}/doctor -RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/ovno ${REPOS_DIR}/ovno RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/promise ${REPOS_DIR}/promise RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/sfc ${REPOS_DIR}/sfc RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/snaps ${REPOS_DIR}/snaps @@ -94,6 +94,7 @@ RUN git clone --depth 1 -b $OPENSTACK_TAG https://github.com/openstack/networkin RUN git clone --depth 1 -b $KINGBIRD_TAG https://github.com/openstack/kingbird.git ${REPOS_DIR}/kingbird RUN git clone --depth 1 -b $RALLY_TAG https://github.com/openstack/rally.git ${REPOS_DIR}/rally RUN git clone --depth 1 -b $TEMPEST_TAG https://github.com/openstack/tempest.git ${REPOS_DIR}/tempest +RUN git clone https://github.com/openstack/refstack-client ${REPOS_DIR}/refstack-client # other repositories RUN git clone --depth 1 -b $ODL_TAG https://git.opendaylight.org/gerrit/p/integration/test.git ${REPOS_DIR}/odl_test @@ -111,8 +112,20 @@ RUN cd ${RELENG_MODULE_DIR} \ && pip install -e . RUN find ${FUNCTEST_REPO_DIR} -name "*.py" \ - -not -path "*tests/unit*" |xargs grep __main__ |cut -d\: -f 1 |xargs chmod -c 755 \ - && find ${FUNCTEST_REPO_DIR} -name "*.sh" |xargs grep \#\! |cut -d\: -f 1 |xargs chmod -c 755 + -not -path "*tests/unit*" \ + -not -path "*functest_venv*" \ + |xargs grep -L __main__ |cut -d\: -f 1 |xargs chmod -c 644 && + find ${FUNCTEST_REPO_DIR} -name "*.sh" \ + -not -path "*functest_venv*" \ + |xargs grep -L \#\! |cut -d\: -f 1 |xargs chmod -c 644 + +RUN find ${FUNCTEST_REPO_DIR} -name "*.py" \ + -not -path "*tests/unit*" \ + -not -path "*functest_venv*" \ + |xargs grep __main__ |cut -d\: -f 1 |xargs chmod -c 755 && + find ${FUNCTEST_REPO_DIR} -name "*.sh" \ + -not -path "*functest_venv*" \ + |xargs grep \#\! |cut -d\: -f 1 |xargs chmod -c 755 RUN /bin/bash ${REPOS_DIR}/parser/tests/parser_install.sh ${REPOS_DIR} RUN ${REPOS_DIR}/rally/install_rally.sh --yes @@ -136,6 +149,9 @@ RUN cd ${REPOS_DIR}/bgpvpn && pip install -e . # Kingbird integration RUN cd ${REPOS_DIR}/kingbird && pip install -e . +# refstack-client integration +RUN cd ${REPOS_DIR}/refstack-client && ./setup_env -t ${REFSTACK_TAG} + RUN /bin/bash -c ". /etc/profile.d/rvm.sh \ && cd ${REPOS_VNFS_DIR}/vims-test \ && rvm autolibs enable" diff --git a/docs/testing/user/configguide/configguide.rst b/docs/testing/user/configguide/configguide.rst index 6bec8925..56a414d3 100644 --- a/docs/testing/user/configguide/configguide.rst +++ b/docs/testing/user/configguide/configguide.rst @@ -333,7 +333,6 @@ should now be in place:: |-- kingbird |-- odl_test |-- onos - |-- ovno |-- parser |-- promise |-- rally diff --git a/functest/ci/__init__.py b/functest/ci/__init__.py index e69de29b..e69de29b 100755..100644 --- a/functest/ci/__init__.py +++ b/functest/ci/__init__.py diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml index 3d576318..4d5a6217 100755 --- a/functest/ci/config_functest.yaml +++ b/functest/ci/config_functest.yaml @@ -24,10 +24,10 @@ general: repo_barometer: /home/opnfv/repos/barometer repo_doctor: /home/opnfv/repos/doctor repo_copper: /home/opnfv/repos/copper - dir_repo_ovno: /home/opnfv/repos/ovno repo_parser: /home/opnfv/repos/parser repo_domino: /home/opnfv/repos/domino repo_snaps: /home/opnfv/repos/snaps + repo_fds: /home/opnfv/repos/fds repo_securityscan: /home/opnfv/repos/securityscanning repo_vrouter: /home/opnfv/repos/vnfs/vrouter functest: /home/opnfv/functest @@ -38,18 +38,22 @@ general: functest_data: /home/opnfv/functest/data ims_data: /home/opnfv/functest/data/ims/ rally_inst: /home/opnfv/.rally + repo_kingbird: /home/opnfv/repos/kingbird + refstack_client: /home/opnfv/repos/refstack-client openstack: creds: /home/opnfv/functest/conf/openstack.creds snapshot_file: /home/opnfv/functest/conf/openstack_snapshot.yaml image_name: Cirros-0.3.5 + image_name_alt: Cirros-0.3.5-1 image_file_name: cirros-0.3.5-x86_64-disk.img image_disk_format: qcow2 image_username: cirros image_password: cubswin:) flavor_name: opnfv_flavor + flavor_name_alt: opnfv_flavor_1 flavor_ram: 512 flavor_disk: 1 flavor_vcpus: 1 @@ -110,6 +114,7 @@ tempest: router_name: tempest-router use_custom_images: False use_custom_flavors: False + volume_device_name: vdc rally: deployment_name: opnfv-rally @@ -118,6 +123,10 @@ rally: subnet_cidr: 192.168.140.0/24 router_name: rally-router +refstack: + tempest_conf_path: openstack/refstack_client/tempest.conf + defcore_list: openstack/refstack_client/defcore.txt + vnf: aaa: tenant_name: aaa diff --git a/functest/ci/generate_report.py b/functest/ci/generate_report.py index 89d8fc62..3872a07e 100755 --- a/functest/ci/generate_report.py +++ b/functest/ci/generate_report.py @@ -26,7 +26,7 @@ COL_5_LEN = 75 logger = ft_logger.Logger("generate_report").getLogger() -def init(tiers_to_run): +def init(tiers_to_run=[]): test_cases_arr = [] for tier in tiers_to_run: for test in tier.get_tests(): @@ -91,7 +91,7 @@ def print_separator(char="=", delimiter="+"): return str -def main(args): +def main(args=[]): executed_test_cases = args if CONST.IS_CI_RUN: diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml index 1a1d0f4b..5f54b975 100755 --- a/functest/ci/testcases.yaml +++ b/functest/ci/testcases.yaml @@ -8,22 +8,6 @@ tiers: operations in the VIM. testcases: - - name: snaps_health_check - criteria: 'status == "PASS"' - blocking: true - clean_flag: false - description: >- - This test case creates executes the SimpleHealthCheck - Python test class which creates an, image, flavor, network, - and Cirros VM instance and observes the console output to - validate the single port obtains the correct IP address. - dependencies: - installer: '' - scenario: '^((?!lxd).)*$' - run: - module: 'functest.opnfv_tests.openstack.snaps.health_check' - class: 'HealthCheck' - - name: connection_check criteria: 'status == "PASS"' blocking: true @@ -60,6 +44,22 @@ tiers: run: module: 'functest.opnfv_tests.openstack.snaps.api_check' class: 'ApiCheck' + - + name: snaps_health_check + criteria: 'status == "PASS"' + blocking: true + clean_flag: false + description: >- + This test case creates executes the SimpleHealthCheck + Python test class which creates an, image, flavor, network, + and Cirros VM instance and observes the console output to + validate the single port obtains the correct IP address. + dependencies: + installer: '' + scenario: '^((?!lxd).)*$' + run: + module: 'functest.opnfv_tests.openstack.snaps.health_check' + class: 'HealthCheck' - name: smoke order: 1 @@ -131,6 +131,21 @@ tiers: class: 'RallySanity' - + name: refstack_defcore + criteria: 'success_rate == 100%' + blocking: false + clean_flag: false + description: >- + This test case runs a sub group of tests of the OpenStack + Defcore testcases by using refstack client. + dependencies: + installer: '' + scenario: '' + run: + module: 'functest.opnfv_tests.openstack.refstack_client.refstack_client' + class: 'RefstackClient' + + - name: odl criteria: 'success_rate == 100%' blocking: true @@ -153,7 +168,7 @@ tiers: - name: odl_netvirt criteria: 'success_rate == 100%' - blocking: true + blocking: false clean_flag: false description: >- Test Suite for the OpenDaylight SDN Controller when @@ -161,8 +176,8 @@ tiers: some test suites from upstream using Robot as the test framework. dependencies: - installer: '' - scenario: 'netvirt' + installer: 'apex' + scenario: 'os-odl_l3-nofeature' run: module: 'functest.opnfv_tests.sdn.odl.odl' class: 'ODLTests' @@ -173,6 +188,25 @@ tiers: - /home/opnfv/repos/odl_test/csit/suites/openstack/connectivity - + name: fds + criteria: 'success_rate == 100%' + blocking: false + clean_flag: false + description: >- + Test Suite for the OpenDaylight SDN Controller when GBP features are + installed. It integrates some test suites from upstream using + Robot as the test framework. + dependencies: + installer: 'apex' + scenario: 'odl_l2-fdio' + run: + module: 'functest.opnfv_tests.sdn.odl.odl' + class: 'ODLTests' + args: + suites: + - /home/opnfv/repos/fds/testing/robot + + - name: onos criteria: 'status == "PASS"' blocking: true @@ -204,7 +238,7 @@ tiers: dependencies: installer: '^((?!netvirt).)*$' - scenario: '' + scenario: '^((?!lxd).)*$' run: module: 'functest.opnfv_tests.openstack.snaps.smoke' class: 'SnapsSmoke' @@ -239,7 +273,7 @@ tiers: description: >- Test suite from Doctor project. dependencies: - installer: '(apex)|(fuel)|(joid)' + installer: '(apex)|(fuel)' scenario: '^((?!fdio).)*$' run: module: 'functest.opnfv_tests.features.doctor' @@ -351,19 +385,6 @@ tiers: module: 'functest.opnfv_tests.features.domino' class: 'Domino' - - name: orchestra - criteria: 'ret == 0' - blocking: false - clean_flag: true - description: >- - Test OpenBaton (Orchestra) stack - dependencies: - installer: 'joid' - scenario: 'unknown' - run: - module: 'functest.opnfv_tests.features.orchestrator.orchestra' - class: 'OpenbatonOrchestrator' - - name: netready criteria: 'status == "PASS"' blocking: false @@ -415,20 +436,6 @@ tiers: # module: 'functest.opnfv_tests.openstack.tempest.tempest' # class: 'TempestFullParallel' - - name: tempest_defcore - criteria: 'success_rate == 100%' - blocking: false - clean_flag: false - description: >- - This is the set of Tempest test cases created by OpenStack - Interop Working Group for certification purposes. - dependencies: - installer: '' - scenario: 'nosdn-nofeature-ha' - run: - module: 'functest.opnfv_tests.openstack.tempest.tempest' - class: 'TempestDefcore' - - name: tempest_custom criteria: 'success_rate == 100%' blocking: false @@ -481,34 +488,19 @@ tiers: run: module: 'functest.opnfv_tests.vnf.ims.cloudify_ims' class: 'ImsVnf' - - - name: aaa - criteria: 'ret == 0' - blocking: false - clean_flag: true - description: >- - Test suite from Parser project. - dependencies: - installer: '' - scenario: '' - run: - module: 'functest.opnfv_tests.vnf.aaa.aaa' - class: 'AaaVnf' - - - - name: juju_epc - criteria: 'ret == 0' - blocking: false - clean_flag: true - description: >- - Test suite from OAI project, vEPC deployed with Juju. - dependencies: - installer: 'unknown' - scenario: 'unknown' - run: - module: 'functest.opnfv_tests.vnf.epc.epc' - class: 'EpcVnf' - +# - +# name: aaa +# criteria: 'ret == 0' +# blocking: false +# clean_flag: true +# description: >- +# Test suite from Parser project. +# dependencies: +# installer: '' +# scenario: '' +# run: +# module: 'functest.opnfv_tests.vnf.aaa.aaa' +# class: 'AaaVnf' - name: orchestra_ims criteria: 'ret == 0' diff --git a/functest/ci/tier_builder.py b/functest/ci/tier_builder.py index f4c6f70f..f4c6f70f 100755..100644 --- a/functest/ci/tier_builder.py +++ b/functest/ci/tier_builder.py diff --git a/functest/ci/tier_handler.py b/functest/ci/tier_handler.py index 6b4864b5..6b4864b5 100755..100644 --- a/functest/ci/tier_handler.py +++ b/functest/ci/tier_handler.py diff --git a/functest/core/vnf_base.py b/functest/core/vnf_base.py index 9438dca1..f5e86054 100644 --- a/functest/core/vnf_base.py +++ b/functest/core/vnf_base.py @@ -40,7 +40,8 @@ class VnfOnBoardingBase(base.TestcaseBase): self.tenant_description = CONST.__getattribute__( 'vnf_{}_tenant_description'.format(self.case_name)) except: - raise Exception("Unknown VNF case=" + self.case_name) + # raise Exception("Unknown VNF case=" + self.case_name) + self.logger.error("Unknown VNF case={}".format(self.case_name)) try: self.images = CONST.__getattribute__( @@ -51,8 +52,13 @@ class VnfOnBoardingBase(base.TestcaseBase): def execute(self): self.start_time = time.time() # Prepare the test (Create Tenant, User, ...) - self.logger.info("Create VNF Onboarding environment") - self.prepare() + try: + self.logger.info("Create VNF Onboarding environment") + self.prepare() + except Exception: + self.logger.error("Error during VNF Onboarding environment" + + "creation", exc_info=True) + return base.TestcaseBase.EX_TESTCASE_FAILED # Deploy orchestrator try: @@ -79,8 +85,9 @@ class VnfOnBoardingBase(base.TestcaseBase): self.details['vnf']['result'] = res_deploy_vnf['result'] self.details['vnf']['duration'] = round( vnf_ready_time - orchestrator_ready_time, 1) - except: - raise Exception("Error during VNF deployment") + except Exception: + self.logger.error("Error during VNF deployment", exc_info=True) + return base.TestcaseBase.EX_TESTCASE_FAILED # Test VNF try: @@ -91,8 +98,9 @@ class VnfOnBoardingBase(base.TestcaseBase): self.details['test_vnf']['result'] = res_test_vnf['result'] self.details['test_vnf']['duration'] = round( test_vnf_done_time - vnf_ready_time, 1) - except: - raise Exception("Error when running VNF tests") + except Exception: + self.logger.error("Error when running VNF tests", exc_info=True) + return base.TestcaseBase.EX_TESTCASE_FAILED # Clean the system self.clean() @@ -228,4 +236,5 @@ class VnfOnBoardingBase(base.TestcaseBase): part = inspect.stack()[1][3] self.details[part]['status'] = 'FAIL' self.details[part]['result'] = error_msg + self.logger.error("Step failure:{}".format(error_msg)) raise Exception(error_msg) diff --git a/functest/opnfv_tests/features/barometer.py b/functest/opnfv_tests/features/barometer.py index aec2bce5..32067284 100644 --- a/functest/opnfv_tests/features/barometer.py +++ b/functest/opnfv_tests/features/barometer.py @@ -6,11 +6,9 @@ # # http://www.apache.org/licenses/LICENSE-2.0 +from baro_tests import collectd import functest.core.feature_base as base -import functest.utils.functest_logger as ft_logger - -from baro_tests import collectd class BarometerCollectd(base.FeatureBase): @@ -22,7 +20,6 @@ class BarometerCollectd(base.FeatureBase): super(BarometerCollectd, self).__init__(project='barometer', case='barometercollectd', repo='dir_repo_barometer') - self.logger = ft_logger.Logger("BarometerCollectd").getLogger() def execute(self): return collectd.main(self.logger) diff --git a/functest/opnfv_tests/features/copper.py b/functest/opnfv_tests/features/copper.py index 735b315d..735b315d 100755..100644 --- a/functest/opnfv_tests/features/copper.py +++ b/functest/opnfv_tests/features/copper.py diff --git a/functest/opnfv_tests/features/doctor.py b/functest/opnfv_tests/features/doctor.py index 4d295a67..4d295a67 100755..100644 --- a/functest/opnfv_tests/features/doctor.py +++ b/functest/opnfv_tests/features/doctor.py diff --git a/functest/opnfv_tests/features/domino.py b/functest/opnfv_tests/features/domino.py index b36220fa..b36220fa 100755..100644 --- a/functest/opnfv_tests/features/domino.py +++ b/functest/opnfv_tests/features/domino.py diff --git a/functest/opnfv_tests/features/odl_sfc.py b/functest/opnfv_tests/features/odl_sfc.py index 3b68d420..1956c9c8 100644 --- a/functest/opnfv_tests/features/odl_sfc.py +++ b/functest/opnfv_tests/features/odl_sfc.py @@ -14,7 +14,7 @@ class OpenDaylightSFC(base.FeatureBase): def __init__(self): super(OpenDaylightSFC, self).__init__(project='sfc', - case='functest-odl-sfc"', + case='functest-odl-sfc', repo='dir_repo_sfc') dir_sfc_functest = '{}/sfc/tests/functest'.format(self.repo) self.cmd = 'cd %s && python ./run_tests.py' % dir_sfc_functest diff --git a/functest/opnfv_tests/features/promise.py b/functest/opnfv_tests/features/promise.py index 15636fbf..15636fbf 100755..100644 --- a/functest/opnfv_tests/features/promise.py +++ b/functest/opnfv_tests/features/promise.py diff --git a/functest/opnfv_tests/features/sdnvpn.py b/functest/opnfv_tests/features/sdnvpn.py index 1919a03c..1919a03c 100755..100644 --- a/functest/opnfv_tests/features/sdnvpn.py +++ b/functest/opnfv_tests/features/sdnvpn.py diff --git a/functest/opnfv_tests/features/security_scan.py b/functest/opnfv_tests/features/security_scan.py index 58f0ec74..58f0ec74 100755..100644 --- a/functest/opnfv_tests/features/security_scan.py +++ b/functest/opnfv_tests/features/security_scan.py diff --git a/functest/opnfv_tests/mano/orchestra.py b/functest/opnfv_tests/mano/orchestra.py index fd5e40d0..fd5e40d0 100755..100644 --- a/functest/opnfv_tests/mano/orchestra.py +++ b/functest/opnfv_tests/mano/orchestra.py diff --git a/functest/opnfv_tests/openstack/healthcheck/healthcheck.sh b/functest/opnfv_tests/openstack/healthcheck/healthcheck.sh index 7fa957c0..7fa957c0 100755..100644 --- a/functest/opnfv_tests/openstack/healthcheck/healthcheck.sh +++ b/functest/opnfv_tests/openstack/healthcheck/healthcheck.sh diff --git a/functest/opnfv_tests/openstack/refstack_client/__init__.py b/functest/opnfv_tests/openstack/refstack_client/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/functest/opnfv_tests/openstack/refstack_client/__init__.py diff --git a/functest/opnfv_tests/openstack/refstack_client/defcore.txt b/functest/opnfv_tests/openstack/refstack_client/defcore.txt new file mode 100644 index 00000000..be8fd899 --- /dev/null +++ b/functest/opnfv_tests/openstack/refstack_client/defcore.txt @@ -0,0 +1,248 @@ +# Set of DefCore tempest test cases not flagged and required. It only contains OpenStack core (no object storage) +# The approved guidelines (2016.08) are valid for Kilo, Liberty, Mitaka and Newton releases of OpenStack +# The list can be generated using the Rest API from RefStack project: +# https://refstack.openstack.org/api/v1/guidelines/2016.08/tests?target=compute&type=required&alias=true&flag=false +tempest.api.compute.images.test_images_oneserver.ImagesOneServerTestJSON.test_create_delete_image[id-3731d080-d4c5-4872-b41a-64d0d0021314] +tempest.api.compute.images.test_images_oneserver.ImagesOneServerTestJSON.test_create_image_specify_multibyte_character_image_name[id-3b7c6fe4-dfe7-477c-9243-b06359db51e6] +tempest.api.compute.servers.test_create_server.ServersTestJSON.test_host_name_is_same_as_server_name[id-ac1ad47f-984b-4441-9274-c9079b7a0666] +tempest.api.compute.servers.test_create_server.ServersTestJSON.test_list_servers[id-9a438d88-10c6-4bcd-8b5b-5b6e25e1346f] +tempest.api.compute.servers.test_create_server.ServersTestJSON.test_list_servers_with_detail[id-585e934c-448e-43c4-acbf-d06a9b899997] +tempest.api.compute.servers.test_create_server.ServersTestJSON.test_verify_created_server_vcpus[id-cbc0f52f-05aa-492b-bdc1-84b575ca294b] +tempest.api.compute.servers.test_create_server.ServersTestJSON.test_verify_server_details[id-5de47127-9977-400a-936f-abcfbec1218f] +tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_host_name_is_same_as_server_name[id-ac1ad47f-984b-4441-9274-c9079b7a0666] +tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_list_servers[id-9a438d88-10c6-4bcd-8b5b-5b6e25e1346f] +tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_list_servers_with_detail[id-585e934c-448e-43c4-acbf-d06a9b899997] +tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_verify_created_server_vcpus[id-cbc0f52f-05aa-492b-bdc1-84b575ca294b] +tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_verify_server_details[id-5de47127-9977-400a-936f-abcfbec1218f] +tempest.api.compute.servers.test_instance_actions.InstanceActionsTestJSON.test_get_instance_action[id-aacc71ca-1d70-4aa5-bbf6-0ff71470e43c] +tempest.api.compute.servers.test_instance_actions.InstanceActionsTestJSON.test_list_instance_actions[id-77ca5cc5-9990-45e0-ab98-1de8fead201a] +tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_flavor[id-80c574cc-0925-44ba-8602-299028357dd9] +tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_image[id-b3304c3b-97df-46d2-8cd3-e2b6659724e7] +tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_server_name[id-f9eb2b70-735f-416c-b260-9914ac6181e4] +tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_server_status[id-de2612ab-b7dd-4044-b0b1-d2539601911f] +tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_limit_results[id-67aec2d0-35fe-4503-9f92-f13272b867ed] +tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_active_status[id-ca78e20e-fddb-4ce6-b7f7-bcbf8605e66e] +tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_flavor[id-573637f5-7325-47bb-9144-3476d0416908] +tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_image[id-05e8a8e7-9659-459a-989d-92c2f501f4ba] +tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_limit[id-614cdfc1-d557-4bac-915b-3e67b48eee76] +tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_server_name[id-9b067a7b-7fee-4f6a-b29c-be43fe18fc5a] +tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_server_status[id-ca78e20e-fddb-4ce6-b7f7-bcbf8605e66e] +tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filtered_by_name_wildcard[id-e9f624ee-92af-4562-8bec-437945a18dcb] +tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_changes_since_future_date[id-74745ad8-b346-45b5-b9b8-509d7447fc1f] +tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_changes_since_invalid_date[id-87d12517-e20a-4c9c-97b6-dd1628d6d6c9] +tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_limits[id-12c80a9f-2dec-480e-882b-98ba15757659] +tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_limits_greater_than_actual_count[id-d47c17fb-eebd-4287-8e95-f20a7e627b18] +tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_limits_pass_negative_value[id-62610dd9-4713-4ee0-8beb-fd2c1aa7f950] +tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_limits_pass_string[id-679bc053-5e70-4514-9800-3dfab1a380a6] +tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_non_existing_flavor[id-5913660b-223b-44d4-a651-a0fbfd44ca75] +tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_non_existing_image[id-ff01387d-c7ad-47b4-ae9e-64fa214638fe] +tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_non_existing_server_name[id-e2c77c4a-000a-4af3-a0bd-629a328bde7c] +tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_detail_server_is_deleted[id-93055106-2d34-46fe-af68-d9ddbf7ee570] +tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_status_non_existing[id-fcdf192d-0f74-4d89-911f-1ec002b822c4] +tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_with_a_deleted_server[id-24a26f1a-1ddc-4eea-b0d7-a90cc874ad8f] +tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_lock_unlock_server[id-80a8094c-211e-440a-ab88-9e59d556c7ee] +tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_reboot_server_hard[id-2cb1baf6-ac8d-4429-bf0d-ba8a0ba53e32] +tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_rebuild_server[id-aaa6cdf3-55a7-461a-add9-1c8596b9a07c] +tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_stop_start_server[id-af8eafd4-38a7-4a4b-bdbc-75145a580560] +tempest.api.compute.servers.test_server_metadata.ServerMetadataTestJSON.test_delete_server_metadata_item[id-127642d6-4c7b-4486-b7cd-07265a378658] +tempest.api.compute.servers.test_server_metadata.ServerMetadataTestJSON.test_get_server_metadata_item[id-3043c57d-7e0e-49a6-9a96-ad569c265e6a] +tempest.api.compute.servers.test_server_metadata.ServerMetadataTestJSON.test_list_server_metadata[id-479da087-92b3-4dcf-aeb3-fd293b2d14ce] +tempest.api.compute.servers.test_server_metadata.ServerMetadataTestJSON.test_set_server_metadata[id-211021f6-21de-4657-a68f-908878cfe251] +tempest.api.compute.servers.test_server_metadata.ServerMetadataTestJSON.test_set_server_metadata_item[id-58c02d4f-5c67-40be-8744-d3fa5982eb1c] +tempest.api.compute.servers.test_server_metadata.ServerMetadataTestJSON.test_update_server_metadata[id-344d981e-0c33-4997-8a5d-6c1d803e4134] +tempest.api.compute.servers.test_servers.ServersTestJSON.test_create_server_with_admin_password[id-b92d5ec7-b1dd-44a2-87e4-45e888c46ef0] +tempest.api.compute.servers.test_servers.ServersTestJSON.test_create_specify_keypair[id-f9e15296-d7f9-4e62-b53f-a04e89160833] +tempest.api.compute.servers.test_servers.ServersTestJSON.test_create_with_existing_server_name[id-8fea6be7-065e-47cf-89b8-496e6f96c699] +tempest.api.compute.servers.test_servers.ServersTestJSON.test_update_access_server_address[id-89b90870-bc13-4b73-96af-f9d4f2b70077] +tempest.api.compute.servers.test_servers.ServersTestJSON.test_update_server_name[id-5e6ccff8-349d-4852-a8b3-055df7988dd2] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_numeric_server_name[id-fd57f159-68d6-4c2a-902b-03070828a87e] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_server_metadata_exceeds_length_limit[id-7fc74810-0bd2-4cd7-8244-4f33a9db865a] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_server_name_length_exceeds_256[id-c3e0fb12-07fc-4d76-a22e-37409887afe8] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_with_invalid_flavor[id-18f5227f-d155-4429-807c-ccb103887537] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_with_invalid_image[id-fcba1052-0a50-4cf3-b1ac-fae241edf02f] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_with_invalid_network_uuid[id-4e72dc2d-44c5-4336-9667-f7972e95c402] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_delete_server_pass_id_exceeding_length_limit[id-f4d7279b-5fd2-4bf2-9ba4-ae35df0d18c5] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_delete_server_pass_negative_id[id-75f79124-277c-45e6-a373-a1d6803f4cc4] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_get_non_existent_server[id-3436b02f-1b1e-4f03-881e-c6a602327439] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_invalid_ip_v6_address[id-5226dd80-1e9c-4d8a-b5f9-b26ca4763fd0] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_reboot_non_existent_server[id-d4c023a0-9c55-4747-9dd5-413b820143c7] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_rebuild_deleted_server[id-98fa0458-1485-440f-873b-fe7f0d714930] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_rebuild_non_existent_server[id-d86141a7-906e-4731-b187-d64a2ea61422] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_rebuild_reboot_deleted_server[id-98fa0458-1485-440f-873b-fe7f0d714930] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_server_name_blank[id-dbbfd247-c40c-449e-8f6c-d2aa7c7da7cf] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_stop_non_existent_server[id-a31460a9-49e1-42aa-82ee-06e0bb7c2d03] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_update_name_of_non_existent_server[id-aa8eed43-e2cb-4ebf-930b-da14f6a21d81] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_update_server_name_length_exceeds_256[id-5c8e244c-dada-4590-9944-749c455b431f] +tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_update_server_set_empty_name[id-38204696-17c6-44da-9590-40f87fb5a899] +tempest.api.compute.test_quotas.QuotasTestJSON.test_get_default_quotas[id-9bfecac7-b966-4f47-913f-1a9e2c12134a] +tempest.api.compute.test_quotas.QuotasTestJSON.test_get_quotas[id-f1ef0a97-dbbb-4cca-adc5-c9fbc4f76107] +tempest.api.compute.test_versions.TestVersions.test_list_api_versions[id-6c0a0990-43b6-4529-9b61-5fd8daf7c55c] +# tempest.api.compute.volumes.test_attach_volume.AttachVolumeTestJSON.test_attach_detach_volume[id-52e9045a-e90d-4c0d-9087-79d657faffff] +tempest.api.compute.volumes.test_attach_volume.AttachVolumeTestJSON.test_list_get_volume_attachments[id-7fa563fe-f0f7-43eb-9e22-a1ece036b513] +tempest.api.identity.v3.TestApiDiscovery.test_api_media_types[id-657c1970-4722-4189-8831-7325f3bc4265] +tempest.api.identity.v3.TestApiDiscovery.test_api_version_resources[id-b9232f5e-d9e5-4d97-b96c-28d3db4de1bd] +tempest.api.identity.v3.TestApiDiscovery.test_api_version_statuses[id-8879a470-abfb-47bb-bb8d-5a7fd279ad1e] +tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_api_media_types[id-657c1970-4722-4189-8831-7325f3bc4265] +tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_api_version_resources[id-b9232f5e-d9e5-4d97-b96c-28d3db4de1bd] +tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_api_version_statuses[id-8879a470-abfb-47bb-bb8d-5a7fd279ad1e] +tempest.api.identity.v3.test_tokens.TokensV3Test.test_create_token[id-6f8e4436-fc96-4282-8122-e41df57197a9] +tempest.api.image.v2.test_images.BasicOperationsImagesTest.test_delete_image[id-f848bb94-1c6e-45a4-8726-39e3a5b23535] +tempest.api.image.v2.test_images.BasicOperationsImagesTest.test_update_image[id-f66891a7-a35c-41a8-b590-a065c2a1caa6] +tempest.api.image.v2.test_images.ListImagesTest.test_get_image_schema[id-622b925c-479f-4736-860d-adeaf13bc371] +tempest.api.image.v2.test_images.ListImagesTest.test_get_images_schema[id-25c8d7b2-df21-460f-87ac-93130bcdc684] +tempest.api.image.v2.test_images.ListImagesTest.test_index_no_params[id-1e341d7a-90a9-494c-b143-2cdf2aeb6aee] +tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_container_format[id-9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e] +tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_disk_format[id-4a4735a7-f22f-49b6-b0d9-66e1ef7453eb] +tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_limit[id-e914a891-3cc8-4b40-ad32-e0a39ffbddbb] +tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_min_max_size[id-4ad8c157-971a-4ba8-aa84-ed61154b1e7f] +tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_size[id-cf1b9a48-8340-480e-af7b-fe7e17690876] +tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_status[id-7fc9e369-0f58-4d05-9aa5-0969e2d59d15] +tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_visibility[id-7a95bb92-d99e-4b12-9718-7bc6ab73e6d2] +tempest.api.image.v2.test_images.ListImagesTest.test_list_no_params[id-1e341d7a-90a9-494c-b143-2cdf2aeb6aee] +tempest.api.image.v2.test_images.ListUserImagesTest.test_get_image_schema[id-622b925c-479f-4736-860d-adeaf13bc371] +tempest.api.image.v2.test_images.ListUserImagesTest.test_get_images_schema[id-25c8d7b2-df21-460f-87ac-93130bcdc684] +tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_container_format[id-9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e] +tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_disk_format[id-4a4735a7-f22f-49b6-b0d9-66e1ef7453eb] +tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_limit[id-e914a891-3cc8-4b40-ad32-e0a39ffbddbb] +tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_min_max_size[id-4ad8c157-971a-4ba8-aa84-ed61154b1e7f] +tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_size[id-cf1b9a48-8340-480e-af7b-fe7e17690876] +tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_status[id-7fc9e369-0f58-4d05-9aa5-0969e2d59d15] +tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_visibility[id-7a95bb92-d99e-4b12-9718-7bc6ab73e6d2] +tempest.api.image.v2.test_images.ListUserImagesTest.test_list_no_params[id-1e341d7a-90a9-494c-b143-2cdf2aeb6aee] +tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_delete_image_null_id[id-32248db1-ab88-4821-9604-c7c369f1f88c] +tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_delete_non_existing_image[id-6fe40f1c-57bd-4918-89cc-8500f850f3de] +tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_get_delete_deleted_image[id-e57fc127-7ba0-4693-92d7-1d8a05ebcba9] +tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_get_image_null_id[id-ef45000d-0a72-4781-866d-4cb7bf2562ad] +tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_get_non_existent_image[id-668743d5-08ad-4480-b2b8-15da34f81d9f] +tempest.api.image.v2.test_images_tags.ImagesTagsTest.test_update_delete_tags_for_image[id-10407036-6059-4f95-a2cd-cbbbee7ed329] +tempest.api.image.v2.test_images_tags_negative.ImagesTagsNegativeTest.test_delete_non_existing_tag[id-39c023a2-325a-433a-9eea-649bf1414b19] +tempest.api.image.v2.test_images_tags_negative.ImagesTagsNegativeTest.test_update_tags_for_non_existing_image[id-8cd30f82-6f9a-4c6e-8034-c1b51fba43d9] +tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_all_attributes[id-a4d9ec4c-0306-4111-a75c-db01a709030b] +tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_allocation_pools[id-bec949c4-3147-4ba6-af5f-cd2306118404] +tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_dhcp_enabled[id-94ce038d-ff0a-4a4c-a56b-09da3ca0b55d] +tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_gw[id-9393b468-186d-496d-aa36-732348cd76e7] +tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_gw_and_allocation_pools[id-8217a149-0c6c-4cfb-93db-0486f707d13f] +tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_host_routes_and_dns_nameservers[id-d830de0a-be47-468f-8f02-1fd996118289] +tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_without_gateway[id-d2d596e2-8e76-47a9-ac51-d4648009f4d3] +tempest.api.network.test_networks.NetworksTest.test_create_update_delete_network_subnet[id-0e269138-0da6-4efc-a46d-578161e7b221] +tempest.api.network.test_networks.NetworksTest.test_delete_network_with_subnet[id-f04f61a9-b7f3-4194-90b2-9bcf660d1bfe] +tempest.api.network.test_networks.NetworksTest.test_list_networks[id-f7ffdeda-e200-4a7a-bcbe-05716e86bf43] +tempest.api.network.test_networks.NetworksTest.test_list_networks_fields[id-6ae6d24f-9194-4869-9c85-c313cb20e080] +tempest.api.network.test_networks.NetworksTest.test_list_subnets[id-db68ba48-f4ea-49e9-81d1-e367f6d0b20a] +tempest.api.network.test_networks.NetworksTest.test_list_subnets_fields[id-842589e3-9663-46b0-85e4-7f01273b0412] +tempest.api.network.test_networks.NetworksTest.test_show_network[id-2bf13842-c93f-4a69-83ed-717d2ec3b44e] +tempest.api.network.test_networks.NetworksTest.test_show_network_fields[id-867819bb-c4b6-45f7-acf9-90edcf70aa5e] +tempest.api.network.test_networks.NetworksTest.test_show_subnet[id-bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc] +tempest.api.network.test_networks.NetworksTest.test_show_subnet_fields[id-270fff0b-8bfc-411f-a184-1e8fd35286f0] +tempest.api.network.test_networks.NetworksTest.test_update_subnet_gw_dns_host_routes_dhcp[id-3d3852eb-3009-49ec-97ac-5ce83b73010a] +tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_all_attributes[id-a4d9ec4c-0306-4111-a75c-db01a709030b] +tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_allocation_pools[id-bec949c4-3147-4ba6-af5f-cd2306118404] +tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_dhcp_enabled[id-94ce038d-ff0a-4a4c-a56b-09da3ca0b55d] +tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_gw[id-9393b468-186d-496d-aa36-732348cd76e7] +tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_gw_and_allocation_pools[id-8217a149-0c6c-4cfb-93db-0486f707d13f] +tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_host_routes_and_dns_nameservers[id-d830de0a-be47-468f-8f02-1fd996118289] +tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_without_gateway[id-d2d596e2-8e76-47a9-ac51-d4648009f4d3] +tempest.api.network.test_networks.NetworksTestJSON.test_create_update_delete_network_subnet[id-0e269138-0da6-4efc-a46d-578161e7b221] +tempest.api.network.test_networks.NetworksTestJSON.test_delete_network_with_subnet[id-f04f61a9-b7f3-4194-90b2-9bcf660d1bfe] +tempest.api.network.test_networks.NetworksTestJSON.test_list_networks[id-f7ffdeda-e200-4a7a-bcbe-05716e86bf43] +tempest.api.network.test_networks.NetworksTestJSON.test_list_networks_fields[id-6ae6d24f-9194-4869-9c85-c313cb20e080] +tempest.api.network.test_networks.NetworksTestJSON.test_list_subnets[id-db68ba48-f4ea-49e9-81d1-e367f6d0b20a] +tempest.api.network.test_networks.NetworksTestJSON.test_list_subnets_fields[id-842589e3-9663-46b0-85e4-7f01273b0412] +tempest.api.network.test_networks.NetworksTestJSON.test_show_network[id-2bf13842-c93f-4a69-83ed-717d2ec3b44e] +tempest.api.network.test_networks.NetworksTestJSON.test_show_network_fields[id-867819bb-c4b6-45f7-acf9-90edcf70aa5e] +tempest.api.network.test_networks.NetworksTestJSON.test_show_subnet[id-bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc] +tempest.api.network.test_networks.NetworksTestJSON.test_show_subnet_fields[id-270fff0b-8bfc-411f-a184-1e8fd35286f0] +tempest.api.network.test_networks.NetworksTestJSON.test_update_subnet_gw_dns_host_routes_dhcp[id-3d3852eb-3009-49ec-97ac-5ce83b73010a] +tempest.api.network.test_ports.PortsTestJSON.test_create_bulk_port[id-67f1b811-f8db-43e2-86bd-72c074d4a42c] +tempest.api.network.test_ports.PortsTestJSON.test_create_port_in_allowed_allocation_pools[id-0435f278-40ae-48cb-a404-b8a087bc09b1] +tempest.api.network.test_ports.PortsTestJSON.test_create_update_delete_port[id-c72c1c0c-2193-4aca-aaa4-b1442640f51c] +tempest.api.network.test_ports.PortsTestJSON.test_list_ports[id-cf95b358-3e92-4a29-a148-52445e1ac50e] +tempest.api.network.test_ports.PortsTestJSON.test_list_ports_fields[id-ff7f117f-f034-4e0e-abff-ccef05c454b4] +tempest.api.network.test_ports.PortsTestJSON.test_show_port[id-c9a685bd-e83f-499c-939f-9f7863ca259f] +tempest.api.network.test_ports.PortsTestJSON.test_show_port_fields[id-45fcdaf2-dab0-4c13-ac6c-fcddfb579dbd] +tempest.api.network.test_ports.PortsTestJSON.test_update_port_with_security_group_and_extra_attributes[id-58091b66-4ff4-4cc1-a549-05d60c7acd1a] +tempest.api.network.test_ports.PortsTestJSON.test_update_port_with_two_security_groups_and_extra_attributes[id-edf6766d-3d40-4621-bc6e-2521a44c257d] +tempest.api.network.test_security_groups.SecGroupTest.test_create_list_update_show_delete_security_group[id-bfd128e5-3c92-44b6-9d66-7fe29d22c802] +tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_additional_args[id-87dfbcf9-1849-43ea-b1e4-efa3eeae9f71] +tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_icmp_type_code[id-c9463db8-b44d-4f52-b6c0-8dbda99f26ce] +tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_protocol_integer_value[id-0a307599-6655-4220-bebc-fd70c64f2290] +tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_remote_group_id[id-c2ed2deb-7a0c-44d8-8b4c-a5825b5c310b] +tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_remote_ip_prefix[id-16459776-5da2-4634-bce4-4b55ee3ec188] +tempest.api.network.test_security_groups.SecGroupTest.test_create_show_delete_security_group_rule[id-cfb99e0e-7410-4a3d-8a0c-959a63ee77e9] +tempest.api.network.test_security_groups.SecGroupTest.test_list_security_groups[id-e30abd17-fef9-4739-8617-dc26da88e686] +tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_additional_default_security_group_fails[id-2323061e-9fbf-4eb0-b547-7e8fafc90849] +tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_duplicate_security_group_rule_fails[id-8fde898f-ce88-493b-adc9-4e4692879fc5] +tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_bad_ethertype[id-5666968c-fff3-40d6-9efc-df1c8bd01abb] +tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_bad_protocol[id-981bdc22-ce48-41ed-900a-73148b583958] +tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_bad_remote_ip_prefix[id-5f8daf69-3c5f-4aaa-88c9-db1d66f68679] +tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_invalid_ports[id-0d9c7791-f2ad-4e2f-ac73-abf2373b0d2d] +tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_non_existent_remote_groupid[id-4bf786fd-2f02-443c-9716-5b98e159a49a] +tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_non_existent_security_group[id-be308db6-a7cf-4d5c-9baf-71bafd73f35e] +tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_delete_non_existent_security_group[id-1f1bb89d-5664-4956-9fcd-83ee0fa603df] +tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_show_non_existent_security_group[id-424fd5c3-9ddc-486a-b45f-39bf0c820fc6] +tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_show_non_existent_security_group_rule[id-4c094c09-000b-4e41-8100-9617600c02a6] +tempest.api.volume.test_availability_zone.AvailabilityZoneV2TestJSON.test_get_availability_zone_list[id-01f1ae88-eba9-4c6b-a011-6f7ace06b725] +tempest.api.volume.test_extensions.ExtensionsV2TestJSON.test_list_extensions[id-94607eb0-43a5-47ca-82aa-736b41bd2e2c] +tempest.api.volume.test_snapshot_metadata.SnapshotV2MetadataTestJSON.test_create_get_delete_snapshot_metadata[id-a2f20f99-e363-4584-be97-bc33afb1a56c] +tempest.api.volume.test_snapshot_metadata.SnapshotV2MetadataTestJSON.test_crud_snapshot_metadata[id-a2f20f99-e363-4584-be97-bc33afb1a56c] +tempest.api.volume.test_snapshot_metadata.SnapshotV2MetadataTestJSON.test_update_snapshot_metadata_item[id-e8ff85c5-8f97-477f-806a-3ac364a949ed] +tempest.api.volume.test_volume_metadata.VolumesV2MetadataTest.test_create_get_delete_volume_metadata[id-6f5b125b-f664-44bf-910f-751591fe5769] +tempest.api.volume.test_volume_metadata.VolumesV2MetadataTest.test_crud_volume_metadata[id-6f5b125b-f664-44bf-910f-751591fe5769] +tempest.api.volume.test_volume_metadata.VolumesV2MetadataTest.test_update_volume_metadata_item[id-862261c5-8df4-475a-8c21-946e50e36a20] +tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_attach_detach_volume_to_instance[id-fff42874-7db5-4487-a8e1-ddda5fb5288d] +tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_get_volume_attachment[id-9516a2c8-9135-488c-8dd6-5677a7e5f371] +tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_reserve_unreserve_volume[id-92c4ef64-51b2-40c0-9f7e-4749fbaaba33] +tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_volume_bootable[id-63e21b4c-0a0c-41f6-bfc3-7c2816815599] +tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_volume_readonly_update[id-fff74e1e-5bd3-4b33-9ea9-24c103bc3f59] +tempest.api.volume.test_volumes_get.VolumesV2GetTest.test_volume_create_get_update_delete[id-27fb0e9f-fb64-41dd-8bdb-1ffa762f0d51] +tempest.api.volume.test_volumes_get.VolumesV2GetTest.test_volume_create_get_update_delete_as_clone[id-3f591b4a-7dc6-444c-bd51-77469506b3a1] +tempest.api.volume.test_volumes_get.VolumesV2GetTest.test_volume_create_get_update_delete_from_image[id-54a01030-c7fc-447c-86ee-c1182beae638] +tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list[id-0b6ddd39-b948-471f-8038-4787978747c4] +tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_by_name[id-a28e8da4-0b56-472f-87a8-0f4d3f819c02] +tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_details_by_name[id-2de3a6d4-12aa-403b-a8f2-fdeb42a89623] +tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_param_display_name_and_status[id-777c87c1-2fc4-4883-8b8e-5c0b951d1ec8] +tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_detail_param_display_name_and_status[id-856ab8ca-6009-4c37-b691-be1065528ad4] +tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_detail_param_metadata[id-1ca92d3c-4a8e-4b43-93f5-e4c7fb3b291d] +tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_details[id-adcbb5a7-5ad8-4b61-bd10-5380e111a877] +tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_param_metadata[id-b5ebea1b-0603-40a0-bb41-15fcd0a53214] +tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_by_availability_zone[id-c0cfa863-3020-40d7-b587-e35f597d5d87] +tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_by_status[id-39654e13-734c-4dab-95ce-7613bf8407ce] +tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_details_by_availability_zone[id-e1b80d13-94f0-4ba2-a40e-386af29f8db1] +tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_details_by_status[id-2943f712-71ec-482a-bf49-d5ca06216b9f] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_attach_volumes_with_nonexistent_volume_id[id-f5e56b0a-5d02-43c1-a2a7-c9b792c2e3f6] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_invalid_size[id-1ed83a8a-682d-4dfb-a30e-ee63ffd6c049] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_nonexistent_snapshot_id[id-0c36f6ae-4604-4017-b0a9-34fdc63096f9] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_nonexistent_source_volid[id-47c73e08-4be8-45bb-bfdf-0c4e79b88344] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_nonexistent_volume_type[id-10254ed8-3849-454e-862e-3ab8e6aa01d2] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_out_passing_size[id-9387686f-334f-4d31-a439-33494b9e2683] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_size_negative[id-8b472729-9eba-446e-a83b-916bdb34bef7] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_size_zero[id-41331caa-eaf4-4001-869d-bc18c1869360] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_without_passing_size[id-9387686f-334f-4d31-a439-33494b9e2683] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_delete_invalid_volume_id[id-1f035827-7c32-4019-9240-b4ec2dbd9dfd] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_delete_volume_without_passing_volume_id[id-441a1550-5d44-4b30-af0f-a6d402f52026] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_detach_volumes_with_invalid_volume_id[id-9f9c24e4-011d-46b5-b992-952140ce237a] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_get_invalid_volume_id[id-30799cfd-7ee4-446c-b66c-45b383ed211b] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_get_volume_without_passing_volume_id[id-c6c3db06-29ad-4e91-beb0-2ab195fe49e3] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_detail_with_invalid_status[id-ba94b27b-be3f-496c-a00e-0283b373fa75] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_detail_with_nonexistent_name[id-9ca17820-a0e7-4cbd-a7fa-f4468735e359] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_with_invalid_status[id-143b279b-7522-466b-81be-34a87d564a7c] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_with_nonexistent_name[id-0f4aa809-8c7b-418f-8fb3-84c7a5dfc52f] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_reserve_volume_with_negative_volume_status[id-449c4ed2-ecdd-47bb-98dc-072aeccf158c] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_reserve_volume_with_nonexistent_volume_id[id-ac6084c0-0546-45f9-b284-38a367e0e0e2] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_unreserve_volume_with_nonexistent_volume_id[id-eb467654-3dc1-4a72-9b46-47c29d22654c] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_update_volume_with_empty_volume_id[id-72aeca85-57a5-4c1f-9057-f320f9ea575b] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_update_volume_with_invalid_volume_id[id-e66e40d6-65e6-4e75-bdc7-636792fa152d] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_update_volume_with_nonexistent_volume_id[id-0186422c-999a-480e-a026-6a665744c30c] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_volume_delete_nonexistent_volume_id[id-555efa6e-efcd-44ef-8a3b-4a7ca4837a29] +tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_volume_get_nonexistent_volume_id[id-f131c586-9448-44a4-a8b0-54ca838aa43e] +tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_snapshot_create_get_list_update_delete[id-2a8abbe4-d871-46db-b049-c41f5af8216e] +tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_snapshots_list_details_with_params[id-220a1022-1fcd-4a74-a7bd-6b859156cda2] +tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_snapshots_list_with_params[id-59f41f43-aebf-48a9-ab5d-d76340fab32b] +tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_volume_from_snapshot[id-677863d1-3142-456d-b6ac-9924f667a7f4] +tempest.api.volume.test_volumes_snapshots_list.VolumesV2SnapshotListTestJSON.test_snapshots_list_details_with_params[id-220a1022-1fcd-4a74-a7bd-6b859156cda2] +tempest.api.volume.test_volumes_snapshots_list.VolumesV2SnapshotListTestJSON.test_snapshots_list_with_params[id-59f41f43-aebf-48a9-ab5d-d76340fab32b] +tempest.api.volume.test_volumes_snapshots_negative.VolumesV2SnapshotNegativeTestJSON.test_create_snapshot_with_nonexistent_volume_id[id-e3e466af-70ab-4f4b-a967-ab04e3532ea7] +tempest.api.volume.test_volumes_snapshots_negative.VolumesV2SnapshotNegativeTestJSON.test_create_snapshot_without_passing_volume_id[id-bb9da53e-d335-4309-9c15-7e76fd5e4d6d] +tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_details_pagination[id-e9138a2c-f67b-4796-8efa-635c196d01de] +tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_details_with_multiple_params[id-2a7064eb-b9c3-429b-b888-33928fc5edd3] +tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_pagination[id-af55e775-8e4b-4feb-8719-215c43b0238c] diff --git a/functest/opnfv_tests/openstack/refstack_client/refstack_client.py b/functest/opnfv_tests/openstack/refstack_client/refstack_client.py new file mode 100755 index 00000000..7d4c568a --- /dev/null +++ b/functest/opnfv_tests/openstack/refstack_client/refstack_client.py @@ -0,0 +1,233 @@ +#!/usr/bin/env python + +# matthew.lijun@huawei.com wangwulin@huawei.com +# 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 argparse +import os +import re +import sys +import subprocess +import time + +from functest.core import testcase_base +from functest.opnfv_tests.openstack.tempest import conf_utils +from functest.utils import openstack_utils +from functest.utils.constants import CONST +import functest.utils.functest_logger as ft_logger +import functest.utils.functest_utils as ft_utils + +""" logging configuration """ +logger = ft_logger.Logger("refstack_defcore").getLogger() + + +class RefstackClient(testcase_base.TestcaseBase): + + def __init__(self): + super(RefstackClient, self).__init__() + self.case_name = "refstack_defcore" + self.FUNCTEST_TEST = CONST.dir_functest_test + self.CONF_PATH = CONST.refstack_tempest_conf_path + self.DEFCORE_LIST = CONST.refstack_defcore_list + self.confpath = os.path.join(self.FUNCTEST_TEST, + self.CONF_PATH) + self.defcorelist = os.path.join(self.FUNCTEST_TEST, + self.DEFCORE_LIST) + self.VERIFIER_ID = conf_utils.get_verifier_id() + self.VERIFIER_REPO_DIR = conf_utils.get_verifier_repo_dir( + self.VERIFIER_ID) + self.DEPLOYMENT_ID = conf_utils.get_verifier_deployment_id() + self.DEPLOYMENT_DIR = conf_utils.get_verifier_deployment_dir( + self.VERIFIER_ID, self.DEPLOYMENT_ID) + + def source_venv(self): + + cmd = ("cd {0};" + ". .venv/bin/activate;" + "cd -;".format(CONST.dir_refstack_client)) + ft_utils.execute_command(cmd) + + def run_defcore(self, conf, testlist): + logger.debug("Generating test case list...") + + cmd = ("cd {0};" + "./refstack-client test -c {1} -v --test-list {2};" + "cd -;".format(CONST.dir_refstack_client, + conf, + testlist)) + ft_utils.execute_command(cmd) + + def run_defcore_default(self): + logger.debug("Generating test case list...") + + cmd = ("cd {0};" + "./refstack-client test -c {1} -v --test-list {2};" + "cd -;".format(CONST.dir_refstack_client, + self.confpath, + self.defcorelist)) + logger.info("Starting Refstack_defcore test case: '%s'." % cmd) + + header = ("Tempest environment:\n" + " Installer: %s\n Scenario: %s\n Node: %s\n Date: %s\n" % + (CONST.INSTALLER_TYPE, + CONST.DEPLOY_SCENARIO, + CONST.NODE_NAME, + time.strftime("%a %b %d %H:%M:%S %Z %Y"))) + + f_stdout = open( + os.path.join(conf_utils.REFSTACK_RESULTS_DIR, + "refstack.log"), 'w+') + f_stderr = open( + os.path.join(conf_utils.REFSTACK_RESULTS_DIR, + "refstack-error.log"), 'w+') + f_env = open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR, + "environment.log"), 'w+') + f_env.write(header) + + p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, + stderr=f_stderr, bufsize=1) + + with p.stdout: + for line in iter(p.stdout.readline, b''): + if 'Tests' in line: + break + logger.info(line.replace('\n', '')) + f_stdout.write(line) + p.wait() + + f_stdout.close() + f_stderr.close() + f_env.close() + + def parse_refstack_result(self): + try: + with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR, + "refstack.log"), 'r') as logfile: + output = logfile.read() + + for match in re.findall("Ran: (\d+) tests in (\d+\.\d{4}) sec.", + output): + num_tests = match[0] + for match in re.findall("- Passed: (\d+)", output): + num_success = match + for match in re.findall("- Skipped: (\d+)", output): + num_skipped = match + for match in re.findall("- Failed: (\d+)", output): + num_failures = match + success_testcases = "" + for match in re.findall(r"\{0\}(.*?)[. ]*ok", output): + success_testcases += match + ", " + failed_testcases = "" + for match in re.findall(r"\{0\}(.*?)[. ]*FAILED", output): + failed_testcases += match + ", " + skipped_testcases = "" + for match in re.findall(r"\{0\}(.*?)[. ]*SKIPPED:", output): + skipped_testcases += match + ", " + + num_executed = int(num_tests) - int(num_skipped) + success_rate = 100 * int(num_success) / int(num_executed) + + self.details = {"tests": int(num_tests), + "failures": int(num_failures), + "success": success_testcases, + "errors": failed_testcases, + "skipped": skipped_testcases} + except Exception: + success_rate = 0 + + self.criteria = ft_utils.check_success_rate( + self.case_name, success_rate) + logger.info("Testcase %s success_rate is %s%%, is marked as %s" + % (self.case_name, success_rate, self.criteria)) + + def defcore_env_prepare(self): + try: + img_flavor_dict = conf_utils.create_tempest_resources( + use_custom_images=True, use_custom_flavors=True) + conf_utils.configure_tempest_defcore( + self.DEPLOYMENT_DIR, img_flavor_dict) + self.source_venv() + res = testcase_base.TestcaseBase.EX_OK + except KeyError as e: + logger.error("defcore prepare env error with: %s", e) + res = testcase_base.TestcaseBase.EX_RUN_ERROR + + return res + + def run(self): + self.start_time = time.time() + + if not os.path.exists(conf_utils.REFSTACK_RESULTS_DIR): + os.makedirs(conf_utils.REFSTACK_RESULTS_DIR) + + try: + self.defcore_env_prepare() + self.run_defcore_default() + self.parse_refstack_result() + res = testcase_base.TestcaseBase.EX_OK + except Exception as e: + logger.error('Error with run: %s', e) + res = testcase_base.TestcaseBase.EX_RUN_ERROR + + self.stop_time = time.time() + return res + + def main(self, **kwargs): + try: + tempestconf = kwargs['config'] + testlist = kwargs['testlist'] + except KeyError as e: + logger.error("Cannot run refstack client. Please check " + "%s", e) + return self.EX_RUN_ERROR + try: + openstack_utils.source_credentials(CONST.openstack_creds) + self.defcore_env_prepare() + self.run_defcore(tempestconf, testlist) + res = testcase_base.TestcaseBase.EX_OK + except Exception as e: + logger.error('Error with run: %s', e) + res = testcase_base.TestcaseBase.EX_RUN_ERROR + + return res + + +class RefstackClientParser(testcase_base.TestcaseBase): + + def __init__(self): + super(RefstackClientParser, self).__init__() + self.FUNCTEST_TEST = CONST.dir_functest_test + self.CONF_PATH = CONST.refstack_tempest_conf_path + self.DEFCORE_LIST = CONST.refstack_defcore_list + self.confpath = os.path.join(self.FUNCTEST_TEST, + self.CONF_PATH) + self.defcorelist = os.path.join(self.FUNCTEST_TEST, + self.DEFCORE_LIST) + self.parser = argparse.ArgumentParser() + self.parser.add_argument( + '-c', '--config', + help='the file path of tempest.conf', + default=self.confpath) + self.parser.add_argument( + '-t', '--testlist', + help='Specify the file path or URL of a test list text file. ' + 'This test list will contain specific test cases that ' + 'should be tested.', + default=self.defcorelist) + + def parse_args(self, argv=[]): + return vars(self.parser.parse_args(argv)) + + +if __name__ == '__main__': + refstackclient = RefstackClient() + parser = RefstackClientParser() + args = parser.parse_args(sys.argv[1:]) + try: + result = refstackclient.main(**args) + if result != testcase_base.TestcaseBase.EX_OK: + sys.exit(result) + except Exception: + sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR) diff --git a/functest/opnfv_tests/openstack/snaps/smoke.py b/functest/opnfv_tests/openstack/snaps/smoke.py index 864bca5e..45fa6de8 100644 --- a/functest/opnfv_tests/openstack/snaps/smoke.py +++ b/functest/opnfv_tests/openstack/snaps/smoke.py @@ -45,5 +45,6 @@ class SnapsSmoke(SnapsTestRunner): CONST.openstack_creds, self.ext_net_name, use_keystone=CONST.snaps_use_keystone, + flavor_metadata=self.flavor_metadata, image_metadata=image_custom_config, use_floating_ips=use_fip) diff --git a/functest/opnfv_tests/openstack/tempest/conf_utils.py b/functest/opnfv_tests/openstack/tempest/conf_utils.py index 893fff8c..a21322d8 100644 --- a/functest/opnfv_tests/openstack/tempest/conf_utils.py +++ b/functest/opnfv_tests/openstack/tempest/conf_utils.py @@ -35,6 +35,8 @@ TEMPEST_DEFCORE = os.path.join(REPO_PATH, TEMPEST_TEST_LIST_DIR, 'defcore_req.txt') TEMPEST_RAW_LIST = os.path.join(TEMPEST_RESULTS_DIR, 'test_raw_list.txt') TEMPEST_LIST = os.path.join(TEMPEST_RESULTS_DIR, 'test_list.txt') +REFSTACK_RESULTS_DIR = os.path.join(CONST.dir_results, + 'refstack') CI_INSTALLER_TYPE = CONST.INSTALLER_TYPE CI_INSTALLER_IP = CONST.INSTALLER_IP @@ -43,6 +45,88 @@ CI_INSTALLER_IP = CONST.INSTALLER_IP logger = ft_logger.Logger("Tempest").getLogger() +def create_tempest_resources(use_custom_images=False, + use_custom_flavors=False): + keystone_client = os_utils.get_keystone_client() + + logger.debug("Creating tenant and user for Tempest suite") + tenant_id = os_utils.create_tenant( + keystone_client, + CONST.tempest_identity_tenant_name, + CONST.tempest_identity_tenant_description) + if not tenant_id: + logger.error("Failed to create %s tenant" + % CONST.tempest_identity_tenant_name) + + user_id = os_utils.create_user(keystone_client, + CONST.tempest_identity_user_name, + CONST.tempest_identity_user_password, + None, tenant_id) + if not user_id: + logger.error("Failed to create %s user" % + CONST.tempest_identity_user_name) + + logger.debug("Creating private network for Tempest suite") + network_dic = os_utils.create_shared_network_full( + CONST.tempest_private_net_name, + CONST.tempest_private_subnet_name, + CONST.tempest_router_name, + CONST.tempest_private_subnet_cidr) + if network_dic is None: + raise Exception('Failed to create private network') + + image_id = "" + image_id_alt = "" + flavor_id = "" + flavor_id_alt = "" + + if CONST.tempest_use_custom_images or use_custom_images: + # adding alternative image should be trivial should we need it + logger.debug("Creating image for Tempest suite") + _, image_id = os_utils.get_or_create_image( + CONST.openstack_image_name, GLANCE_IMAGE_PATH, + CONST.openstack_image_disk_format) + if image_id is None: + raise Exception('Failed to create image') + + if use_custom_images: + logger.debug("Creating 2nd image for Tempest suite") + _, image_id_alt = os_utils.get_or_create_image( + CONST.openstack_image_name_alt, GLANCE_IMAGE_PATH, + CONST.openstack_image_disk_format) + if image_id_alt is None: + raise Exception('Failed to create image') + + if CONST.tempest_use_custom_flavors or use_custom_flavors: + # adding alternative flavor should be trivial should we need it + logger.debug("Creating flavor for Tempest suite") + _, flavor_id = os_utils.get_or_create_flavor( + CONST.openstack_flavor_name, + CONST.openstack_flavor_ram, + CONST.openstack_flavor_disk, + CONST.openstack_flavor_vcpus) + if flavor_id is None: + raise Exception('Failed to create flavor') + + if use_custom_flavors: + logger.debug("Creating 2nd flavor for tempest_defcore") + _, flavor_id_alt = os_utils.get_or_create_flavor( + CONST.openstack_flavor_name_alt, + CONST.openstack_flavor_ram, + CONST.openstack_flavor_disk, + CONST.openstack_flavor_vcpus) + if flavor_id_alt is None: + raise Exception('Failed to create flavor') + + img_flavor_dict = {} + img_flavor_dict['image_id'] = image_id + img_flavor_dict['image_id_alt'] = image_id_alt + img_flavor_dict['flavor_id'] = flavor_id + img_flavor_dict['flavor_id_alt'] = flavor_id_alt + + return img_flavor_dict + + def get_verifier_id(): """ Returns verifer id for current Tempest @@ -106,6 +190,17 @@ def get_verifier_deployment_dir(verifier_id, deployment_id): 'for-deployment-{}'.format(deployment_id)) +def get_repo_tag(repo): + """ + Returns last tag of current branch + """ + cmd = ("git -C {0} describe --abbrev=0 HEAD".format(repo)) + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) + tag = p.stdout.readline().rstrip() + + return str(tag) + + def backup_tempest_config(conf_file): """ Copy config file to tempest results directory @@ -130,6 +225,33 @@ def configure_tempest(deployment_dir, IMAGE_ID=None, FLAVOR_ID=None, configure_tempest_multisite_params(conf_file) +def configure_tempest_defcore(deployment_dir, img_flavor_dict): + """ + Add/update needed parameters into tempest.conf file + """ + conf_file = configure_verifier(deployment_dir) + configure_tempest_update_params(conf_file, + img_flavor_dict.get("image_id"), + img_flavor_dict.get("flavor_id")) + + logger.debug("Updating selected tempest.conf parameters for defcore...") + config = ConfigParser.RawConfigParser() + config.read(conf_file) + config.set('compute', 'image_ref', img_flavor_dict.get("image_id")) + config.set('compute', 'image_ref_alt', + img_flavor_dict['image_id_alt']) + config.set('compute', 'flavor_ref', img_flavor_dict.get("flavor_id")) + config.set('compute', 'flavor_ref_alt', + img_flavor_dict['flavor_id_alt']) + + with open(conf_file, 'wb') as config_file: + config.write(config_file) + + confpath = os.path.join(CONST.dir_functest_test, + CONST.refstack_tempest_conf_path) + shutil.copyfile(conf_file, confpath) + + def configure_tempest_update_params(tempest_conf_file, IMAGE_ID=None, FLAVOR_ID=None): """ @@ -142,6 +264,8 @@ def configure_tempest_update_params(tempest_conf_file, 'compute', 'fixed_network_name', CONST.tempest_private_net_name) + config.set('compute', 'volume_device_name', + CONST.tempest_volume_device_name) if CONST.tempest_use_custom_images: if IMAGE_ID is not None: config.set('compute', 'image_ref', IMAGE_ID) @@ -276,3 +400,16 @@ def configure_tempest_multisite_params(tempest_conf_file): config.write(config_file) backup_tempest_config(tempest_conf_file) + + +def install_verifier_ext(path): + """ + Install extension to active verifier + """ + logger.info("Installing verifier from existing repo...") + tag = get_repo_tag(path) + cmd = ("rally verify add-verifier-ext --source {0} " + "--version {1}" + .format(path, tag)) + error_msg = ("Problem while adding verifier extension from %s" % path) + ft_utils.execute_command_raise(cmd, error_msg=error_msg) diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/defcore_req.txt b/functest/opnfv_tests/openstack/tempest/custom_tests/defcore_req.txt index 1456db87..fbbee2ff 100644 --- a/functest/opnfv_tests/openstack/tempest/custom_tests/defcore_req.txt +++ b/functest/opnfv_tests/openstack/tempest/custom_tests/defcore_req.txt @@ -1,7 +1,7 @@ # Set of DefCore tempest test cases not flagged and required. It only contains OpenStack core (no object storage) # The approved guidelines (2016.08) are valid for Kilo, Liberty, Mitaka and Newton releases of OpenStack # The list can be generated using the Rest API from RefStack project: -# https://refstack.openstack.org/api/v1/guidelines/2016.08/tests?target=compute&type=required&alias=true&flag=false +# https://refstack.openstack.org/api/v1/guidelines/2017.01/tests?target=compute&type=required&alias=true&flag=false tempest.api.compute.images.test_images_oneserver.ImagesOneServerTestJSON.test_create_delete_image[id-3731d080-d4c5-4872-b41a-64d0d0021314] tempest.api.compute.images.test_images_oneserver.ImagesOneServerTestJSON.test_create_image_specify_multibyte_character_image_name[id-3b7c6fe4-dfe7-477c-9243-b06359db51e6] tempest.api.compute.servers.test_create_server.ServersTestJSON.test_host_name_is_same_as_server_name[id-ac1ad47f-984b-4441-9274-c9079b7a0666] @@ -14,6 +14,7 @@ tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_list_s tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_list_servers_with_detail[id-585e934c-448e-43c4-acbf-d06a9b899997] tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_verify_created_server_vcpus[id-cbc0f52f-05aa-492b-bdc1-84b575ca294b] tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_verify_server_details[id-5de47127-9977-400a-936f-abcfbec1218f] +tempest.api.compute.servers.test_delete_server.DeleteServersTestJSON.test_delete_active_server[id-925fdfb4-5b13-47ea-ac8a-c36ae6fddb05] tempest.api.compute.servers.test_instance_actions.InstanceActionsTestJSON.test_get_instance_action[id-aacc71ca-1d70-4aa5-bbf6-0ff71470e43c] tempest.api.compute.servers.test_instance_actions.InstanceActionsTestJSON.test_list_instance_actions[id-77ca5cc5-9990-45e0-ab98-1de8fead201a] tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_flavor[id-80c574cc-0925-44ba-8602-299028357dd9] @@ -245,4 +246,4 @@ tempest.api.volume.test_volumes_snapshots_negative.VolumesV2SnapshotNegativeTest tempest.api.volume.test_volumes_snapshots_negative.VolumesV2SnapshotNegativeTestJSON.test_create_snapshot_without_passing_volume_id[id-bb9da53e-d335-4309-9c15-7e76fd5e4d6d] tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_details_pagination[id-e9138a2c-f67b-4796-8efa-635c196d01de] tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_details_with_multiple_params[id-2a7064eb-b9c3-429b-b888-33928fc5edd3] -tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_pagination[id-af55e775-8e4b-4feb-8719-215c43b0238c]
\ No newline at end of file +tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_pagination[id-af55e775-8e4b-4feb-8719-215c43b0238c] diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py index 4c96500d..d3b15926 100644 --- a/functest/opnfv_tests/openstack/tempest/tempest.py +++ b/functest/opnfv_tests/openstack/tempest/tempest.py @@ -21,7 +21,6 @@ from functest.opnfv_tests.openstack.tempest import conf_utils from functest.utils.constants import CONST import functest.utils.functest_logger as ft_logger import functest.utils.functest_utils as ft_utils -import functest.utils.openstack_utils as os_utils """ logging configuration """ logger = ft_logger.Logger("Tempest").getLogger() @@ -33,8 +32,6 @@ class TempestCommon(testcase_base.TestcaseBase): super(TempestCommon, self).__init__() self.MODE = "" self.OPTION = "" - self.FLAVOR_ID = None - self.IMAGE_ID = None self.VERIFIER_ID = conf_utils.get_verifier_id() self.VERIFIER_REPO_DIR = conf_utils.get_verifier_repo_dir( self.VERIFIER_ID) @@ -48,55 +45,6 @@ class TempestCommon(testcase_base.TestcaseBase): with open(filename) as src: return [line.strip() for line in src.readlines()] - def create_tempest_resources(self): - keystone_client = os_utils.get_keystone_client() - - logger.debug("Creating tenant and user for Tempest suite") - tenant_id = os_utils.create_tenant( - keystone_client, - CONST.tempest_identity_tenant_name, - CONST.tempest_identity_tenant_description) - if not tenant_id: - logger.error("Failed to create %s tenant" - % CONST.tempest_identity_tenant_name) - - user_id = os_utils.create_user(keystone_client, - CONST.tempest_identity_user_name, - CONST.tempest_identity_user_password, - None, tenant_id) - if not user_id: - logger.error("Failed to create %s user" % - CONST.tempest_identity_user_name) - - logger.debug("Creating private network for Tempest suite") - network_dic = os_utils.create_shared_network_full( - CONST.tempest_private_net_name, - CONST.tempest_private_subnet_name, - CONST.tempest_router_name, - CONST.tempest_private_subnet_cidr) - if network_dic is None: - raise Exception('Failed to create private network') - - if CONST.tempest_use_custom_images: - # adding alternative image should be trivial should we need it - logger.debug("Creating image for Tempest suite") - _, self.IMAGE_ID = os_utils.get_or_create_image( - CONST.openstack_image_name, conf_utils.GLANCE_IMAGE_PATH, - CONST.openstack_image_disk_format) - if self.IMAGE_ID is None: - raise Exception('Failed to create image') - - if CONST.tempest_use_custom_flavors: - # adding alternative flavor should be trivial should we need it - logger.debug("Creating flavor for Tempest suite") - _, self.FLAVOR_ID = os_utils.get_or_create_flavor( - CONST.openstack_flavor_name, - CONST.openstack_flavor_ram, - CONST.openstack_flavor_disk, - CONST.openstack_flavor_vcpus) - if self.FLAVOR_ID is None: - raise Exception('Failed to create flavor') - def generate_test_list(self, verifier_repo_dir): logger.debug("Generating test case list...") if self.MODE == 'defcore': @@ -160,13 +108,9 @@ class TempestCommon(testcase_base.TestcaseBase): result_file.write(str(cases_line) + '\n') result_file.close() - def _parse_verification_id(line): - first_pos = line.index("UUID=") + len("UUID=") - last_pos = line.index(") for deployment") - return line[first_pos:last_pos] - def run_verifier_tests(self): - self.OPTION += (" --load-list {}".format(conf_utils.TEMPEST_LIST)) + self.OPTION += (" --load-list {} --detailed" + .format(conf_utils.TEMPEST_LIST)) cmd_line = "rally verify start " + self.OPTION logger.info("Starting Tempest test suite: '%s'." % cmd_line) @@ -269,11 +213,12 @@ class TempestCommon(testcase_base.TestcaseBase): os.makedirs(conf_utils.TEMPEST_RESULTS_DIR) try: - self.create_tempest_resources() - conf_utils.configure_tempest(self.DEPLOYMENT_DIR, - self.IMAGE_ID, - self.FLAVOR_ID, - self.MODE) + image_and_flavor = conf_utils.create_tempest_resources() + conf_utils.configure_tempest( + self.DEPLOYMENT_DIR, + IMAGE_ID=image_and_flavor.get("image_id"), + FLAVOR_ID=image_and_flavor.get("flavor_id"), + MODE=self.MODE) self.generate_test_list(self.VERIFIER_REPO_DIR) self.apply_tempest_blacklist() self.run_verifier_tests() @@ -320,6 +265,7 @@ class TempestMultisite(TempestCommon): self.case_name = "multisite" self.MODE = "feature_multisite" self.OPTION = "--concurrency 1" + conf_utils.install_verifier_ext(CONST.dir_repo_kingbird) class TempestCustom(TempestCommon): diff --git a/functest/opnfv_tests/sdn/odl/odl.py b/functest/opnfv_tests/sdn/odl/odl.py index 69818f5a..c8e9c492 100755 --- a/functest/opnfv_tests/sdn/odl/odl.py +++ b/functest/opnfv_tests/sdn/odl/odl.py @@ -94,8 +94,11 @@ class ODLTests(testcase_base.TestcaseBase): try: odlusername = kwargs['odlusername'] odlpassword = kwargs['odlpassword'] - variables = ['KEYSTONE:' + kwargs['keystoneip'], + osauthurl = kwargs['osauthurl'] + keystoneip = urlparse.urlparse(osauthurl).hostname + variables = ['KEYSTONE:' + keystoneip, 'NEUTRON:' + kwargs['neutronip'], + 'OS_AUTH_URL:"' + osauthurl + '"', 'OSUSERNAME:"' + kwargs['osusername'] + '"', 'OSTENANTNAME:"' + kwargs['ostenantname'] + '"', 'OSPASSWORD:"' + kwargs['ospassword'] + '"', @@ -147,10 +150,8 @@ class ODLTests(testcase_base.TestcaseBase): suites = kwargs["suites"] except KeyError: pass - keystone_url = op_utils.get_endpoint(service_type='identity') neutron_url = op_utils.get_endpoint(service_type='network') - kwargs = {'keystoneip': urlparse.urlparse(keystone_url).hostname} - kwargs['neutronip'] = urlparse.urlparse(neutron_url).hostname + kwargs = {'neutronip': urlparse.urlparse(neutron_url).hostname} kwargs['odlip'] = kwargs['neutronip'] kwargs['odlwebport'] = '8080' kwargs['odlrestconfport'] = '8181' @@ -161,6 +162,7 @@ class ODLTests(testcase_base.TestcaseBase): installer_type = os.environ['INSTALLER_TYPE'] kwargs['osusername'] = os.environ['OS_USERNAME'] kwargs['ostenantname'] = os.environ['OS_TENANT_NAME'] + kwargs['osauthurl'] = os.environ['OS_AUTH_URL'] kwargs['ospassword'] = os.environ['OS_PASSWORD'] if installer_type == 'fuel': kwargs['odlwebport'] = '8282' @@ -191,12 +193,12 @@ class ODLParser(object): def __init__(self): self.parser = argparse.ArgumentParser() self.parser.add_argument( - '-k', '--keystoneip', help='Keystone IP', - default='127.0.0.1') - self.parser.add_argument( '-n', '--neutronip', help='Neutron IP', default='127.0.0.1') self.parser.add_argument( + '-k', '--osauthurl', help='OS_AUTH_URL as defined by OpenStack', + default='http://127.0.0.1:5000/v2.0') + self.parser.add_argument( '-a', '--osusername', help='Username for OpenStack', default='admin') self.parser.add_argument( diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.py b/functest/opnfv_tests/vnf/ims/cloudify_ims.py index c2c251ad..f7dfd532 100644 --- a/functest/opnfv_tests/vnf/ims/cloudify_ims.py +++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.py @@ -203,7 +203,7 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): flavor_exist, flavor_id = os_utils.get_or_create_flavor( "m1.small", self.vnf['requirements']['ram_min'], - '20', + '30', '1', public=True) self.logger.debug("Flavor id: %s" % flavor_id) @@ -234,7 +234,7 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): cw.set_external_network_name(ext_net) - error = cw.deploy_vnf() + error = cw.deploy_vnf(self.vnf['blueprint']) if error: self.logger.error(error) return {'status': 'FAIL', 'result': error} @@ -261,6 +261,9 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): dns_ip = dep_outputs.json()['outputs']['dns_ip'] ellis_ip = dep_outputs.json()['outputs']['ellis_ip'] + self.logger.debug("DNS ip : %s" % dns_ip) + self.logger.debug("ELLIS ip : %s" % ellis_ip) + ellis_url = "http://" + ellis_ip + "/" url = ellis_url + "accounts" @@ -270,9 +273,11 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): "signup_code": "secret"} rq = requests.post(url, data=params) - i = 20 + i = 30 while rq.status_code != 201 and i > 0: rq = requests.post(url, data=params) + self.logger.debug("Account creation http status code: %s" + % rq.status_code) i = i - 1 time.sleep(10) @@ -280,6 +285,8 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): url = ellis_url + "session" rq = requests.post(url, data=params) cookies = rq.cookies + else: + self.step_failure("Unable to create an account") url = ellis_url + "accounts/" + params['email'] + "/numbers" if cookies != "": @@ -287,6 +294,8 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): i = 24 while rq.status_code != 200 and i > 0: rq = requests.post(url, cookies=cookies) + self.logger.debug("Number creation http status code: %s" + % rq.status_code) i = i - 1 time.sleep(25) diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml b/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml index 775685fa..74b9e958 100644 --- a/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml +++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml @@ -6,7 +6,7 @@ cloudify: url: https://github.com/boucherv-orange/cloudify-manager-blueprints.git branch: '3.3.1-build' requirements: - ram_min: 4000 + ram_min: 4096 os_image: centos_7 inputs: keystone_username: "" @@ -29,11 +29,11 @@ clearwater: branch: stable deployment_name: clearwater-opnfv requirements: - ram_min: 2000 + ram_min: 2048 os_image: ubuntu_14.04 inputs: image_id: '' flavor_id: '' agent_user: ubuntu external_network_name: '' - public_domain: clearwaterfv + public_domain: clearwater.opnfv diff --git a/functest/opnfv_tests/vnf/ims/opera_ims.py b/functest/opnfv_tests/vnf/ims/opera_ims.py index 7ead401f..7ead401f 100644..100755 --- a/functest/opnfv_tests/vnf/ims/opera_ims.py +++ b/functest/opnfv_tests/vnf/ims/opera_ims.py diff --git a/functest/opnfv_tests/vnf/ims/orchestra_ims.py b/functest/opnfv_tests/vnf/ims/orchestra_ims.py index 42b218e6..d13fe8fe 100644..100755 --- a/functest/opnfv_tests/vnf/ims/orchestra_ims.py +++ b/functest/opnfv_tests/vnf/ims/orchestra_ims.py @@ -245,7 +245,7 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): % (self.imagename, network_id, userdata)) instance = os_utils.create_instance_and_wait_for_active( - "m1.medium", + "orchestra", os_utils.get_image_id(glance_client, self.imagename), network_id, "orchestra-openbaton", @@ -308,12 +308,15 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): if self.ob_projectid == "": self.step_failure("Default project id was not found!") + creds = os_utils.get_credentials() + self.logger.info("PoP creds: %s" % creds) + vim_json = { "name": "vim-instance", - "authUrl": os_utils.get_credentials().get("auth_url"), - "tenant": os_utils.get_credentials().get("tenant_name"), - "username": os_utils.get_credentials().get("username"), - "password": os_utils.get_credentials().get("password"), + "authUrl": creds.get("auth_url"), + "tenant": os.environ.get("OS_PROJECT_ID"), + "username": creds.get("username"), + "password": creds.get("password"), "securityGroups": [ "default", "orchestra-sec-group" diff --git a/functest/opnfv_tests/vnf/ims/orchestra_ims.yaml b/functest/opnfv_tests/vnf/ims/orchestra_ims.yaml index 86d6e604..5923a775 100644 --- a/functest/opnfv_tests/vnf/ims/orchestra_ims.yaml +++ b/functest/opnfv_tests/vnf/ims/orchestra_ims.yaml @@ -2,8 +2,8 @@ tenant_images: ubuntu_14.04: http://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-amd64-disk1.img openims: http://marketplace.openbaton.org:8082/api/v1/images/52e2ccc0-1dce-4663-894d-28aab49323aa/img openbaton: - bootstrap_link: http://get.openbaton.org/bootstrap - bootstrap_config_link: http://get.openbaton.org/bootstrap-config-file + bootstrap_link: http://get.openbaton.org/bootstraps/bootstrap_3.2.0_opnfv/bootstrap + bootstrap_config_link: http://get.openbaton.org/bootstraps/bootstrap_3.2.0_opnfv/bootstrap-config-file marketplace_link: http://marketplace.openbaton.org:8082/api/v1/nsds/fokus/OpenImsCore/3.2.0/json imagename: ubuntu_14.04 vIMS: diff --git a/functest/opnfv_tests/vnf/router/__init__.py b/functest/opnfv_tests/vnf/router/__init__.py index e69de29b..e69de29b 100755..100644 --- a/functest/opnfv_tests/vnf/router/__init__.py +++ b/functest/opnfv_tests/vnf/router/__init__.py diff --git a/functest/opnfv_tests/vnf/router/vyos_vrouter.py b/functest/opnfv_tests/vnf/router/vyos_vrouter.py index 94a3ecfd..94a3ecfd 100755..100644 --- a/functest/opnfv_tests/vnf/router/vyos_vrouter.py +++ b/functest/opnfv_tests/vnf/router/vyos_vrouter.py diff --git a/functest/tests/unit/ci/test_generate_report.py b/functest/tests/unit/ci/test_generate_report.py new file mode 100644 index 00000000..2225586f --- /dev/null +++ b/functest/tests/unit/ci/test_generate_report.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python + +# 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 logging +import unittest +import urllib2 + +import mock + +from functest.ci import generate_report as gen_report +from functest.tests.unit import test_utils +from functest.utils import functest_utils as ft_utils +from functest.utils.constants import CONST + + +class GenerateReportTesting(unittest.TestCase): + + logging.disable(logging.CRITICAL) + + def test_init(self): + test_array = gen_report.init() + self.assertEqual(test_array, []) + + @mock.patch('functest.ci.generate_report.urllib2.urlopen', + side_effect=urllib2.URLError('no host given')) + def test_get_results_from_db_fail(self, mock_method): + url = "%s/results?build_tag=%s" % (ft_utils.get_db_url(), + CONST.BUILD_TAG) + self.assertIsNone(gen_report.get_results_from_db()) + mock_method.assert_called_once_with(url) + + @mock.patch('functest.ci.generate_report.urllib2.urlopen', + return_value={'results': []}) + def test_get_results_from_db_success(self, mock_method): + url = "%s/results?build_tag=%s" % (ft_utils.get_db_url(), + CONST.BUILD_TAG) + self.assertEqual(gen_report.get_results_from_db(), None) + mock_method.assert_called_once_with(url) + + def test_get_data(self): + self.assertIsInstance(gen_report.get_data({'result': ''}, ''), dict) + + def test_print_line_with_ci_run(self): + CONST.IS_CI_RUN = True + w1 = 'test_print_line' + test_str = ("| %s| %s| %s| %s| %s|\n" + % (w1.ljust(gen_report.COL_1_LEN - 1), + ''.ljust(gen_report.COL_2_LEN - 1), + ''.ljust(gen_report.COL_3_LEN - 1), + ''.ljust(gen_report.COL_4_LEN - 1), + ''.ljust(gen_report.COL_5_LEN - 1))) + self.assertEqual(gen_report.print_line(w1), test_str) + + def test_print_line_without_ci_run(self): + CONST.IS_CI_RUN = False + w1 = 'test_print_line' + test_str = ("| %s| %s| %s| %s|\n" + % (w1.ljust(gen_report.COL_1_LEN - 1), + ''.ljust(gen_report.COL_2_LEN - 1), + ''.ljust(gen_report.COL_3_LEN - 1), + ''.ljust(gen_report.COL_4_LEN - 1))) + self.assertEqual(gen_report.print_line(w1), test_str) + + def test_print_line_no_column_with_ci_run(self): + CONST.IS_CI_RUN = True + TOTAL_LEN = gen_report.COL_1_LEN + gen_report.COL_2_LEN + TOTAL_LEN += gen_report.COL_3_LEN + gen_report.COL_4_LEN + 2 + TOTAL_LEN += gen_report.COL_5_LEN + 1 + test_str = ("| %s|\n" % 'test'.ljust(TOTAL_LEN)) + self.assertEqual(gen_report.print_line_no_columns('test'), test_str) + + def test_print_line_no_column_without_ci_run(self): + CONST.IS_CI_RUN = False + TOTAL_LEN = gen_report.COL_1_LEN + gen_report.COL_2_LEN + TOTAL_LEN += gen_report.COL_3_LEN + gen_report.COL_4_LEN + 2 + test_str = ("| %s|\n" % 'test'.ljust(TOTAL_LEN)) + self.assertEqual(gen_report.print_line_no_columns('test'), test_str) + + def test_print_separator_with_ci_run(self): + CONST.IS_CI_RUN = True + test_str = ("+" + "=" * gen_report.COL_1_LEN + + "+" + "=" * gen_report.COL_2_LEN + + "+" + "=" * gen_report.COL_3_LEN + + "+" + "=" * gen_report.COL_4_LEN + + "+" + "=" * gen_report.COL_5_LEN) + test_str += '+\n' + self.assertEqual(gen_report.print_separator(), test_str) + + def test_print_separator_without_ci_run(self): + CONST.IS_CI_RUN = False + test_str = ("+" + "=" * gen_report.COL_1_LEN + + "+" + "=" * gen_report.COL_2_LEN + + "+" + "=" * gen_report.COL_3_LEN + + "+" + "=" * gen_report.COL_4_LEN) + test_str += "+\n" + self.assertEqual(gen_report.print_separator(), test_str) + + @mock.patch('functest.ci.generate_report.logger.info') + def test_main_with_ci_run(self, mock_method): + CONST.IS_CI_RUN = True + gen_report.main() + mock_method.assert_called_once_with(test_utils.SubstrMatch('URL')) + + @mock.patch('functest.ci.generate_report.logger.info') + def test_main_with_ci_loop(self, mock_method): + CONST.CI_LOOP = 'daily' + gen_report.main() + mock_method.assert_called_once_with(test_utils.SubstrMatch('CI LOOP')) + + @mock.patch('functest.ci.generate_report.logger.info') + def test_main_with_scenario(self, mock_method): + CONST.DEPLOY_SCENARIO = 'test_scenario' + gen_report.main() + mock_method.assert_called_once_with(test_utils.SubstrMatch('SCENARIO')) + + @mock.patch('functest.ci.generate_report.logger.info') + def test_main_with_build_tag(self, mock_method): + CONST.BUILD_TAG = 'test_build_tag' + gen_report.main() + mock_method.assert_called_once_with(test_utils. + SubstrMatch('BUILD TAG')) + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/functest/tests/unit/ci/test_run_tests.py b/functest/tests/unit/ci/test_run_tests.py new file mode 100644 index 00000000..02140610 --- /dev/null +++ b/functest/tests/unit/ci/test_run_tests.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python + +# 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 unittest +import logging + +import mock + +from functest.ci import run_tests +from functest.utils.constants import CONST + + +class RunTestsTesting(unittest.TestCase): + + logging.disable(logging.CRITICAL) + + def setUp(self): + self.sep = 'test_sep' + self.creds = {'OS_AUTH_URL': 'http://test_ip:test_port/v2.0', + 'OS_USERNAME': 'test_os_username', + 'OS_TENANT_NAME': 'test_tenant', + 'OS_PASSWORD': 'test_password'} + self.test = {'test_name': 'test_name'} + self.tier = mock.Mock() + attrs = {'get_name.return_value': 'test_tier', + 'get_tests.return_value': ['test1', 'test2'], + 'get_ci_loop.return_value': 'test_ci_loop', + 'get_test_names.return_value': ['test1', 'test2']} + self.tier.configure_mock(**attrs) + + self.tiers = mock.Mock() + attrs = {'get_tiers.return_value': [self.tier]} + self.tiers.configure_mock(**attrs) + + @mock.patch('functest.ci.run_tests.logger.info') + def test_print_separator(self, mock_logger_info): + run_tests.print_separator(self.sep) + mock_logger_info.assert_called_once_with(self.sep * 44) + + @mock.patch('functest.ci.run_tests.logger.error') + def test_source_rc_file_missing_file(self, mock_logger_error): + with mock.patch('functest.ci.run_tests.os.path.isfile', + return_value=False), \ + self.assertRaises(Exception): + run_tests.source_rc_file() + + @mock.patch('functest.ci.run_tests.logger.debug') + def test_source_rc_file_default(self, mock_logger_debug): + with mock.patch('functest.ci.run_tests.os.path.isfile', + return_value=True), \ + mock.patch('functest.ci.run_tests.os_utils.source_credentials', + return_value=self.creds): + run_tests.source_rc_file() + + @mock.patch('functest.ci.run_tests.os_snapshot.main') + def test_generate_os_snapshot(self, mock_os_snap): + run_tests.generate_os_snapshot() + self.assertTrue(mock_os_snap.called) + + @mock.patch('functest.ci.run_tests.os_clean.main') + def test_cleanup(self, mock_os_clean): + run_tests.cleanup() + self.assertTrue(mock_os_clean.called) + + def test_update_test_info(self): + run_tests.GlobalVariables.EXECUTED_TEST_CASES = [self.test] + run_tests.update_test_info('test_name', + 'test_result', + 'test_duration') + exp = self.test + exp.update({"result": 'test_result', + "duration": 'test_duration'}) + self.assertEqual(run_tests.GlobalVariables.EXECUTED_TEST_CASES, + [exp]) + + def test_get_run_dict_if_defined_default(self): + mock_obj = mock.Mock() + with mock.patch('functest.ci.run_tests.' + 'ft_utils.get_dict_by_test', + return_value={'run': mock_obj}): + self.assertEqual(run_tests.get_run_dict('test_name'), + mock_obj) + + @mock.patch('functest.ci.run_tests.logger.error') + def test_get_run_dict_if_defined_missing_config_option(self, + mock_logger_error): + with mock.patch('functest.ci.run_tests.' + 'ft_utils.get_dict_by_test', + return_value=None): + testname = 'test_name' + self.assertEqual(run_tests.get_run_dict(testname), + None) + mock_logger_error.assert_called_once_with("Cannot get {}'s config " + "options" + .format(testname)) + + with mock.patch('functest.ci.run_tests.' + 'ft_utils.get_dict_by_test', + return_value={}): + testname = 'test_name' + self.assertEqual(run_tests.get_run_dict(testname), + None) + + @mock.patch('functest.ci.run_tests.logger.exception') + def test_get_run_dict_if_defined_exception(self, + mock_logger_except): + with mock.patch('functest.ci.run_tests.' + 'ft_utils.get_dict_by_test', + side_effect=Exception): + testname = 'test_name' + self.assertEqual(run_tests.get_run_dict(testname), + None) + mock_logger_except.assert_called_once_with("Cannot get {}'s config" + " options" + .format(testname)) + + def test_run_tests_import_test_class_exception(self): + mock_test = mock.Mock() + args = {'get_name': 'test_name', + 'needs_clean': False} + mock_test.configure_mock(**args) + with mock.patch('functest.ci.run_tests.print_separator'),\ + mock.patch('functest.ci.run_tests.source_rc_file'), \ + mock.patch('functest.ci.run_tests.get_run_dict', + return_value=None), \ + self.assertRaises(Exception) as context: + run_tests.run_test(mock_test, 'tier_name') + msg = "Cannot import the class for the test case." + self.assertTrue(msg in context) + + @mock.patch('functest.ci.run_tests.logger.info') + def test_run_tier_default(self, mock_logger_info): + with mock.patch('functest.ci.run_tests.print_separator'), \ + mock.patch('functest.ci.run_tests.run_test') as mock_method: + run_tests.run_tier(self.tier) + mock_method.assert_any_call('test1', 'test_tier') + mock_method.assert_any_call('test2', 'test_tier') + self.assertTrue(mock_logger_info.called) + + @mock.patch('functest.ci.run_tests.logger.info') + def test_run_tier_missing_test(self, mock_logger_info): + with mock.patch('functest.ci.run_tests.print_separator'): + self.tier.get_tests.return_value = None + self.assertEqual(run_tests.run_tier(self.tier), 0) + self.assertTrue(mock_logger_info.called) + + @mock.patch('functest.ci.run_tests.logger.info') + def test_run_all_default(self, mock_logger_info): + with mock.patch('functest.ci.run_tests.run_tier') as mock_method, \ + mock.patch('functest.ci.run_tests.generate_report.init'), \ + mock.patch('functest.ci.run_tests.generate_report.main'): + CONST.CI_LOOP = 'test_ci_loop' + run_tests.run_all(self.tiers) + mock_method.assert_any_call(self.tier) + self.assertTrue(mock_logger_info.called) + + @mock.patch('functest.ci.run_tests.logger.info') + def test_run_all__missing_tier(self, mock_logger_info): + with mock.patch('functest.ci.run_tests.generate_report.init'), \ + mock.patch('functest.ci.run_tests.generate_report.main'): + CONST.CI_LOOP = 'loop_re_not_available' + run_tests.run_all(self.tiers) + self.assertTrue(mock_logger_info.called) + + def test_main_failed(self): + kwargs = {'test': 'test_name', 'noclean': True, 'report': True} + mock_obj = mock.Mock() + args = {'get_tier.return_value': False, + 'get_test.return_value': False} + mock_obj.configure_mock(**args) + + with mock.patch('functest.ci.run_tests.tb.TierBuilder'), \ + mock.patch('functest.ci.run_tests.source_rc_file', + side_effect=Exception): + self.assertEqual(run_tests.main(**kwargs), + run_tests.Result.EX_ERROR) + + with mock.patch('functest.ci.run_tests.tb.TierBuilder', + return_value=mock_obj), \ + mock.patch('functest.ci.run_tests.source_rc_file', + side_effect=Exception): + self.assertEqual(run_tests.main(**kwargs), + run_tests.Result.EX_ERROR) + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/functest/tests/unit/ci/test_tier_builder.py b/functest/tests/unit/ci/test_tier_builder.py new file mode 100644 index 00000000..48c94a57 --- /dev/null +++ b/functest/tests/unit/ci/test_tier_builder.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python + +# 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 logging +import unittest + +import mock + +from functest.ci import tier_builder + + +class TierBuilderTesting(unittest.TestCase): + + logging.disable(logging.CRITICAL) + + def setUp(self): + self.dependency = {'installer': 'test_installer', + 'scenario': 'test_scenario'} + + self.testcase = {'dependencies': self.dependency, + 'name': 'test_name', + 'criteria': 'test_criteria', + 'blocking': 'test_blocking', + 'clean_flag': 'test_clean_flag', + 'description': 'test_desc'} + + self.dic_tier = {'name': 'test_tier', + 'order': 'test_order', + 'ci_loop': 'test_ci_loop', + 'description': 'test_desc', + 'testcases': [self.testcase]} + + self.mock_yaml = mock.Mock() + attrs = {'get.return_value': [self.dic_tier]} + self.mock_yaml.configure_mock(**attrs) + + with mock.patch('functest.ci.tier_builder.yaml.safe_load', + return_value=self.mock_yaml), \ + mock.patch('__builtin__.open', mock.mock_open()): + self.tierbuilder = tier_builder.TierBuilder('test_installer', + 'test_scenario', + 'testcases_file') + self.tier_obj = self.tierbuilder.tier_objects[0] + + def test_get_tiers(self): + self.assertEqual(self.tierbuilder.get_tiers(), + [self.tier_obj]) + + def test_get_tier_names(self): + self.assertEqual(self.tierbuilder.get_tier_names(), + ['test_tier']) + + def test_get_tier_present_tier(self): + self.assertEqual(self.tierbuilder.get_tier('test_tier'), + self.tier_obj) + + def test_get_tier_missing_tier(self): + self.assertEqual(self.tierbuilder.get_tier('test_tier2'), + None) + + def test_get_test_present_test(self): + self.assertEqual(self.tierbuilder.get_test('test_name'), + self.tier_obj.get_test('test_name')) + + def test_get_test_missing_test(self): + self.assertEqual(self.tierbuilder.get_test('test_name2'), + None) + + def test_get_tests_present_tier(self): + self.assertEqual(self.tierbuilder.get_tests('test_tier'), + self.tier_obj.tests_array) + + def test_get_tests_missing_tier(self): + self.assertEqual(self.tierbuilder.get_tests('test_tier2'), + None) + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/functest/tests/unit/ci/test_tier_handler.py b/functest/tests/unit/ci/test_tier_handler.py new file mode 100644 index 00000000..01d99d7e --- /dev/null +++ b/functest/tests/unit/ci/test_tier_handler.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python + +# 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 logging +import unittest + +import mock + +from functest.ci import tier_handler + + +class TierHandlerTesting(unittest.TestCase): + + logging.disable(logging.CRITICAL) + + def setUp(self): + self.test = mock.Mock() + attrs = {'get_name.return_value': 'test_name'} + self.test.configure_mock(**attrs) + + self.mock_depend = mock.Mock() + attrs = {'get_scenario.return_value': 'test_scenario', + 'get_installer.return_value': 'test_installer'} + self.mock_depend.configure_mock(**attrs) + + self.tier = tier_handler.Tier('test_tier', + 'test_order', + 'test_ci_loop', + description='test_desc') + self.testcase = tier_handler.TestCase('test_name', + self.mock_depend, + 'test_criteria', + 'test_blocking', + 'test_clean_flag', + description='test_desc') + + self.dependency = tier_handler.Dependency('test_installer', + 'test_scenario') + + def test_add_test(self): + self.tier.add_test(self.test) + self.assertEqual(self.tier.tests_array, + [self.test]) + + def test_get_tests(self): + self.tier.tests_array = [self.test] + self.assertEqual(self.tier.get_tests(), + [self.test]) + + def test_get_test_names(self): + self.tier.tests_array = [self.test] + self.assertEqual(self.tier.get_test_names(), + ['test_name']) + + def test_get_test(self): + self.tier.tests_array = [self.test] + with mock.patch.object(self.tier, 'is_test', + return_value=True): + self.assertEqual(self.tier.get_test('test_name'), + self.test) + + def test_get_test_missing_test(self): + self.tier.tests_array = [self.test] + with mock.patch.object(self.tier, 'is_test', + return_value=False): + self.assertEqual(self.tier.get_test('test_name'), + None) + + def test_get_name(self): + self.assertEqual(self.tier.get_name(), + 'test_tier') + + def test_get_order(self): + self.assertEqual(self.tier.get_order(), + 'test_order') + + def test_get_ci_loop(self): + self.assertEqual(self.tier.get_ci_loop(), + 'test_ci_loop') + + def test_testcase_is_none_present_item(self): + self.assertEqual(tier_handler.TestCase.is_none("item"), + False) + + def test_testcase_is_none_missing_item(self): + self.assertEqual(tier_handler.TestCase.is_none(None), + True) + + def test_testcase_is_compatible(self): + self.assertEqual(self.testcase.is_compatible('test_installer', + 'test_scenario'), + True) + + def test_testcase_is_compatible_missing_installer_scenario(self): + self.assertEqual(self.testcase.is_compatible('missing_installer', + 'test_scenario'), + False) + self.assertEqual(self.testcase.is_compatible('test_installer', + 'missing_scenario'), + False) + + def test_testcase_get_name(self): + self.assertEqual(self.tier.get_name(), + 'test_tier') + + def test_testcase_get_criteria(self): + self.assertEqual(self.tier.get_order(), + 'test_order') + + def test_testcase_is_blocking(self): + self.assertEqual(self.tier.get_ci_loop(), + 'test_ci_loop') + + def test_dependency_get_installer(self): + self.assertEqual(self.dependency.get_installer(), + 'test_installer') + + def test_dependency_get_scenario(self): + self.assertEqual(self.dependency.get_scenario(), + 'test_scenario') + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/functest/tests/unit/core/test_vnf_base.py b/functest/tests/unit/core/test_vnf_base.py index e27f2164..1680f03f 100644 --- a/functest/tests/unit/core/test_vnf_base.py +++ b/functest/tests/unit/core/test_vnf_base.py @@ -48,5 +48,6 @@ class VnfBaseTesting(unittest.TestCase): def test_parse_results(self): self.assertNotEqual(self.test.parse_results(), 0) + if __name__ == "__main__": unittest.main(verbosity=2) diff --git a/functest/tests/unit/odl/test_odl.py b/functest/tests/unit/odl/test_odl.py index 8f2a5d7e..5961940f 100644 --- a/functest/tests/unit/odl/test_odl.py +++ b/functest/tests/unit/odl/test_odl.py @@ -30,6 +30,7 @@ class ODLTesting(unittest.TestCase): _keystone_ip = "127.0.0.1" _neutron_ip = "127.0.0.2" _sdn_controller_ip = "127.0.0.3" + _os_auth_url = "http://{}:5000/v2.0".format(_keystone_ip) _os_tenantname = "admin" _os_username = "admin" _os_password = "admin" @@ -42,14 +43,15 @@ class ODLTesting(unittest.TestCase): for var in ("INSTALLER_TYPE", "SDN_CONTROLLER", "SDN_CONTROLLER_IP"): if var in os.environ: del os.environ[var] + os.environ["OS_AUTH_URL"] = self._os_auth_url os.environ["OS_USERNAME"] = self._os_username os.environ["OS_PASSWORD"] = self._os_password os.environ["OS_TENANT_NAME"] = self._os_tenantname self.test = odl.ODLTests() self.defaultargs = {'odlusername': self._odl_username, 'odlpassword': self._odl_password, - 'keystoneip': self._keystone_ip, 'neutronip': self._keystone_ip, + 'osauthurl': self._os_auth_url, 'osusername': self._os_username, 'ostenantname': self._os_tenantname, 'ospassword': self._os_password, @@ -157,8 +159,8 @@ class ODLTesting(unittest.TestCase): def _get_main_kwargs(self, key=None): kwargs = {'odlusername': self._odl_username, 'odlpassword': self._odl_password, - 'keystoneip': self._keystone_ip, 'neutronip': self._neutron_ip, + 'osauthurl': self._os_auth_url, 'osusername': self._os_username, 'ostenantname': self._os_tenantname, 'ospassword': self._os_password, @@ -178,6 +180,7 @@ class ODLTesting(unittest.TestCase): if len(args) > 1: variable = ['KEYSTONE:{}'.format(self._keystone_ip), 'NEUTRON:{}'.format(self._neutron_ip), + 'OS_AUTH_URL:"{}"'.format(self._os_auth_url), 'OSUSERNAME:"{}"'.format(self._os_username), 'OSTENANTNAME:"{}"'.format(self._os_tenantname), 'OSPASSWORD:"{}"'.format(self._os_password), @@ -207,12 +210,12 @@ class ODLTesting(unittest.TestCase): def test_main_missing_odlpassword(self): self._test_main_missing_keyword('odlpassword') - def test_main_missing_keystoneip(self): - self._test_main_missing_keyword('keystoneip') - def test_main_missing_neutronip(self): self._test_main_missing_keyword('neutronip') + def test_main_missing_osauthurl(self): + self._test_main_missing_keyword('osauthurl') + def test_main_missing_osusername(self): self._test_main_missing_keyword('osusername') @@ -347,10 +350,11 @@ class ODLTesting(unittest.TestCase): self.assertEqual(self.test.run(), status) self.test.main.assert_called_once_with( odl.ODLTests.default_suites, - keystoneip=self._keystone_ip, neutronip=self._neutron_ip, + neutronip=self._neutron_ip, odlip=odlip, odlpassword=self._odl_password, odlrestconfport=odlrestconfport, odlusername=self._odl_username, odlwebport=odlwebport, + osauthurl=self._os_auth_url, ospassword=self._os_password, ostenantname=self._os_tenantname, osusername=self._os_username) @@ -368,10 +372,11 @@ class ODLTesting(unittest.TestCase): self.assertEqual(self.test.run(suites=suites), status) self.test.main.assert_called_once_with( suites, - keystoneip=self._keystone_ip, neutronip=self._neutron_ip, + neutronip=self._neutron_ip, odlip=odlip, odlpassword=self._odl_password, odlrestconfport=odlrestconfport, odlusername=self._odl_username, odlwebport=odlwebport, + osauthurl=self._os_auth_url, ospassword=self._os_password, ostenantname=self._os_tenantname, osusername=self._os_username) @@ -381,6 +386,9 @@ class ODLTesting(unittest.TestCase): self.assertEqual(self.test.run(), testcase_base.TestcaseBase.EX_RUN_ERROR) + def test_run_missing_os_auth_url(self): + self._test_run_missing_env_var("OS_AUTH_URL") + def test_run_missing_os_username(self): self._test_run_missing_env_var("OS_USERNAME") @@ -507,8 +515,8 @@ class ODLTesting(unittest.TestCase): def test_argparser_odlpassword(self): self._test_argparser('odlpassword', 'foo') - def test_argparser_keystoneip(self): - self._test_argparser('keystoneip', '127.0.0.4') + def test_argparser_osauthurl(self): + self._test_argparser('osauthurl', 'http://127.0.0.4:5000/v2') def test_argparser_neutronip(self): self._test_argparser('neutronip', '127.0.0.4') diff --git a/functest/tests/unit/opnfv_tests/openstack/refstack_client/__init__.py b/functest/tests/unit/opnfv_tests/openstack/refstack_client/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/functest/tests/unit/opnfv_tests/openstack/refstack_client/__init__.py diff --git a/functest/tests/unit/opnfv_tests/openstack/refstack_client/test_refstack_client.py b/functest/tests/unit/opnfv_tests/openstack/refstack_client/test_refstack_client.py new file mode 100644 index 00000000..4e83f6bf --- /dev/null +++ b/functest/tests/unit/opnfv_tests/openstack/refstack_client/test_refstack_client.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python + +# 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 logging +import mock +import os +import unittest + +from functest.core import testcase_base +from functest.opnfv_tests.openstack.refstack_client import refstack_client +from functest.utils.constants import CONST + + +class OSRefstackClientTesting(unittest.TestCase): + + logging.disable(logging.CRITICAL) + _config = \ + os.path.join(CONST.dir_functest_test, CONST.refstack_tempest_conf_path) + _testlist = \ + os.path.join(CONST.dir_functest_test, CONST.refstack_defcore_list) + + def setUp(self): + self.defaultargs = {'config': self._config, + 'testlist': self._testlist} + self.refstackclient = refstack_client.RefstackClient() + + def test_source_venv(self): + CONST.dir_refstack_client = 'test_repo_dir' + with mock.patch('functest.opnfv_tests.openstack.refstack_client.' + 'refstack_client.ft_utils.execute_command') as m: + cmd = ("cd {0};" + ". .venv/bin/activate;" + "cd -;".format(CONST.dir_refstack_client)) + self.refstackclient.source_venv() + m.assert_any_call(cmd) + + def test_run_defcore(self): + config = 'tempest.conf' + testlist = 'testlist' + with mock.patch('functest.opnfv_tests.openstack.refstack_client.' + 'refstack_client.ft_utils.execute_command') as m: + cmd = ("cd {0};" + "./refstack-client test -c {1} -v --test-list {2};" + "cd -;".format(CONST.dir_refstack_client, + config, + testlist)) + self.refstackclient.run_defcore(config, testlist) + m.assert_any_call(cmd) + + def _get_main_kwargs(self, key=None): + kwargs = {'config': self._config, + 'testlist': self._testlist} + if key: + del kwargs[key] + return kwargs + + def _test_main(self, status, *args): + kwargs = self._get_main_kwargs() + self.assertEqual(self.refstackclient.main(**kwargs), status) + if len(args) > 0: + args[0].assert_called_once_with( + refstack_client.RefstackClient.result_dir) + if len(args) > 1: + args + + def _test_main_missing_keyword(self, key): + kwargs = self._get_main_kwargs(key) + self.assertEqual(self.refstackclient.main(**kwargs), + testcase_base.TestcaseBase.EX_RUN_ERROR) + + def test_main_missing_conf(self): + self._test_main_missing_keyword('config') + + def test_main_missing_testlist(self): + self._test_main_missing_keyword('testlist') + + def _test_argparser(self, arg, value): + self.defaultargs[arg] = value + parser = refstack_client.RefstackClientParser() + self.assertEqual(parser.parse_args(["--{}={}".format(arg, value)]), + self.defaultargs) + + def test_argparser_conf(self): + self._test_argparser('config', self._config) + + def test_argparser_testlist(self): + self._test_argparser('testlist', self._testlist) + + def test_argparser_multiple_args(self): + self.defaultargs['config'] = self._config + self.defaultargs['testlist'] = self._testlist + parser = refstack_client.RefstackClientParser() + self.assertEqual(parser.parse_args( + ["--config={}".format(self._config), + "--testlist={}".format(self._testlist) + ]), self.defaultargs) + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/functest/tests/unit/opnfv_tests/openstack/tempest/__init__.py b/functest/tests/unit/opnfv_tests/openstack/tempest/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/functest/tests/unit/opnfv_tests/openstack/tempest/__init__.py diff --git a/functest/tests/unit/opnfv_tests/openstack/tempest/test_conf_utils.py b/functest/tests/unit/opnfv_tests/openstack/tempest/test_conf_utils.py new file mode 100644 index 00000000..caf21925 --- /dev/null +++ b/functest/tests/unit/opnfv_tests/openstack/tempest/test_conf_utils.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python + +# 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 logging +import unittest + +import mock + +from functest.opnfv_tests.openstack.tempest import conf_utils +from functest.utils.constants import CONST + + +class OSTempestConfUtilsTesting(unittest.TestCase): + + logging.disable(logging.CRITICAL) + + def test_create_tempest_resources_missing_network_dic(self): + with mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.get_keystone_client', + return_value=mock.Mock()), \ + mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.create_tenant', + return_value='test_tenant_id'), \ + mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.create_user', + return_value='test_user_id'), \ + mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.create_shared_network_full', + return_value=None), \ + self.assertRaises(Exception) as context: + conf_utils.create_tempest_resources() + msg = 'Failed to create private network' + self.assertTrue(msg in context) + + def test_create_tempest_resources_missing_image(self): + CONST.tempest_use_custom_images = 'test_image' + with mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.get_keystone_client', + return_value=mock.Mock()), \ + mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.create_tenant', + return_value='test_tenant_id'), \ + mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.create_user', + return_value='test_user_id'), \ + mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.create_shared_network_full', + return_value=mock.Mock()), \ + mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.get_or_create_image', + return_value=(mock.Mock(), None)), \ + self.assertRaises(Exception) as context: + conf_utils.create_tempest_resources() + msg = 'Failed to create image' + self.assertTrue(msg in context) + + def test_create_tempest_resources_missing_flavor(self): + CONST.tempest_use_custom_images = 'test_image' + CONST.tempest_use_custom_flavors = 'test_flavour' + with mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.get_keystone_client', + return_value=mock.Mock()), \ + mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.create_tenant', + return_value='test_tenant_id'), \ + mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.create_user', + return_value='test_user_id'), \ + mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.create_shared_network_full', + return_value=mock.Mock()), \ + mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.get_or_create_image', + return_value=(mock.Mock(), 'image_id')), \ + mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' + 'os_utils.get_or_create_flavor', + return_value=(mock.Mock(), None)), \ + self.assertRaises(Exception) as context: + conf_utils.create_tempest_resources() + msg = 'Failed to create flavor' + self.assertTrue(msg in context) + + def test_get_verifier_id_missing_verifier(self): + CONST.tempest_deployment_name = 'test_deploy_name' + with mock.patch('functest.opnfv_tests.openstack.tempest.' + 'conf_utils.subprocess.Popen') as mock_popen, \ + self.assertRaises(Exception): + mock_stdout = mock.Mock() + attrs = {'stdout.readline.return_value': ''} + mock_stdout.configure_mock(**attrs) + mock_popen.return_value = mock_stdout + conf_utils.get_verifier_id(), + + def test_get_verifier_id_default(self): + CONST.tempest_deployment_name = 'test_deploy_name' + with mock.patch('functest.opnfv_tests.openstack.tempest.' + 'conf_utils.subprocess.Popen') as mock_popen: + mock_stdout = mock.Mock() + attrs = {'stdout.readline.return_value': 'test_deploy_id'} + mock_stdout.configure_mock(**attrs) + mock_popen.return_value = mock_stdout + + self.assertEqual(conf_utils.get_verifier_id(), + 'test_deploy_id') + + def test_get_verifier_deployment_id_missing_rally(self): + CONST.rally_deployment_name = 'test_rally_deploy_name' + with mock.patch('functest.opnfv_tests.openstack.tempest.' + 'conf_utils.subprocess.Popen') as mock_popen, \ + self.assertRaises(Exception): + mock_stdout = mock.Mock() + attrs = {'stdout.readline.return_value': ''} + mock_stdout.configure_mock(**attrs) + mock_popen.return_value = mock_stdout + conf_utils.get_verifier_deployment_id(), + + def test_get_verifier_deployment_id_default(self): + CONST.rally_deployment_name = 'test_rally_deploy_name' + with mock.patch('functest.opnfv_tests.openstack.tempest.' + 'conf_utils.subprocess.Popen') as mock_popen: + mock_stdout = mock.Mock() + attrs = {'stdout.readline.return_value': 'test_deploy_id'} + mock_stdout.configure_mock(**attrs) + mock_popen.return_value = mock_stdout + + self.assertEqual(conf_utils.get_verifier_deployment_id(), + 'test_deploy_id') + + def test_get_verifier_repo_dir_default(self): + with mock.patch('functest.opnfv_tests.openstack.tempest.' + 'conf_utils.os.path.join', + return_value='test_verifier_repo_dir'), \ + mock.patch('functest.opnfv_tests.openstack.tempest.' + 'conf_utils.get_verifier_id') as m: + self.assertEqual(conf_utils.get_verifier_repo_dir(''), + 'test_verifier_repo_dir') + self.assertTrue(m.called) + + def test_get_verifier_deployment_dir_default(self): + with mock.patch('functest.opnfv_tests.openstack.tempest.' + 'conf_utils.os.path.join', + return_value='test_verifier_repo_dir'), \ + mock.patch('functest.opnfv_tests.openstack.tempest.' + 'conf_utils.get_verifier_id') as m1, \ + mock.patch('functest.opnfv_tests.openstack.tempest.' + 'conf_utils.get_verifier_deployment_id') as m2: + self.assertEqual(conf_utils.get_verifier_deployment_dir('', ''), + 'test_verifier_repo_dir') + self.assertTrue(m1.called) + self.assertTrue(m2.called) + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/functest/tests/unit/opnfv_tests/openstack/tempest/test_tempest.py b/functest/tests/unit/opnfv_tests/openstack/tempest/test_tempest.py new file mode 100644 index 00000000..856cd143 --- /dev/null +++ b/functest/tests/unit/opnfv_tests/openstack/tempest/test_tempest.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python + +# 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 logging +import unittest + +import mock + +from functest.core import testcase_base +from functest.opnfv_tests.openstack.tempest import tempest +from functest.opnfv_tests.openstack.tempest import conf_utils + + +class OSTempestTesting(unittest.TestCase): + + logging.disable(logging.CRITICAL) + + def setUp(self): + with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'conf_utils.get_verifier_id', + return_value='test_deploy_id'), \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'conf_utils.get_verifier_deployment_id', + return_value='test_deploy_id'), \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'conf_utils.get_verifier_repo_dir', + return_value='test_verifier_repo_dir'), \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'conf_utils.get_verifier_deployment_dir', + return_value='test_verifier_deploy_dir'): + self.tempestcommon = tempest.TempestCommon() + + @mock.patch('functest.opnfv_tests.openstack.tempest.tempest.logger.debug') + def test_generate_test_list_defcore_mode(self, mock_logger_debug): + self.tempestcommon.MODE = 'defcore' + with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'shutil.copyfile') as m: + self.tempestcommon.generate_test_list('test_verifier_repo_dir') + self.assertTrue(m.called) + + @mock.patch('functest.opnfv_tests.openstack.tempest.tempest.logger.error') + @mock.patch('functest.opnfv_tests.openstack.tempest.tempest.logger.debug') + def test_generate_test_list_custom_mode_missing_file(self, + mock_logger_debug, + mock_logger_error): + self.tempestcommon.MODE = 'custom' + with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'os.path.isfile', return_value=False), \ + self.assertRaises(Exception) as context: + msg = "Tempest test list file %s NOT found." + self.tempestcommon.generate_test_list('test_verifier_repo_dir') + self.assertTrue((msg % conf_utils.TEMPEST_CUSTOM) in context) + + def test_generate_test_list_custom_mode_default(self): + self.tempestcommon.MODE = 'custom' + with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'shutil.copyfile') as m, \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'os.path.isfile', return_value=True): + self.tempestcommon.generate_test_list('test_verifier_repo_dir') + self.assertTrue(m.called) + + def _test_generate_test_list_mode_default(self, mode): + self.tempestcommon.MODE = mode + if self.tempestcommon.MODE == 'smoke': + testr_mode = "smoke" + elif self.tempestcommon.MODE == 'feature_multisite': + testr_mode = "'[Kk]ingbird'" + elif self.tempestcommon.MODE == 'full': + testr_mode = "" + else: + testr_mode = 'tempest.api.' + self.tempestcommon.MODE + conf_utils.TEMPEST_RAW_LIST = 'raw_list' + verifier_repo_dir = 'test_verifier_repo_dir' + with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'ft_utils.execute_command') as m: + cmd = ("cd {0};" + "testr list-tests {1} > {2};" + "cd -;".format(verifier_repo_dir, + testr_mode, + conf_utils.TEMPEST_RAW_LIST)) + self.tempestcommon.generate_test_list('test_verifier_repo_dir') + m.assert_any_call(cmd) + + def test_generate_test_list_smoke_mode(self): + self._test_generate_test_list_mode_default('smoke') + + def test_generate_test_list_feature_multisite_mode(self): + self._test_generate_test_list_mode_default('feature_multisite') + + def test_generate_test_list_full_mode(self): + self._test_generate_test_list_mode_default('full') + + def test_parse_verifier_result_missing_verification_uuid(self): + self.tempestcommon.VERIFICATION_ID = '' + with self.assertRaises(Exception): + self.tempestcommon.parse_verifier_result() + + @mock.patch('functest.opnfv_tests.openstack.tempest.tempest.logger.info') + def test_parse_verifier_result_default(self, mock_logger_info): + self.tempestcommon.VERIFICATION_ID = 'test_uuid' + self.tempestcommon.case_name = 'test_case_name' + stdout = ['Testscount||2', 'Success||2', 'Skipped||0', 'Failures||0'] + with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'subprocess.Popen') as mock_popen, \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'ft_utils.check_success_rate') as mock_method, \ + mock.patch('__builtin__.open', mock.mock_open()): + mock_stdout = mock.Mock() + attrs = {'stdout': stdout} + mock_stdout.configure_mock(**attrs) + mock_popen.return_value = mock_stdout + + self.tempestcommon.parse_verifier_result() + mock_method.assert_any_call('test_case_name', 100) + + def test_run_missing_create_tempest_dir(self): + ret = testcase_base.TestcaseBase.EX_RUN_ERROR + with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'os.path.exists', return_value=False), \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'os.makedirs') as mock_os_makedirs, \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'conf_utils.create_tempest_resources', + return_value="image_and_flavor"): + self.assertEqual(self.tempestcommon.run(), + ret) + self.assertTrue(mock_os_makedirs.called) + + def test_run_missing_configure_tempest(self): + ret = testcase_base.TestcaseBase.EX_RUN_ERROR + ret_ok = testcase_base.TestcaseBase.EX_OK + with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'os.path.exists', return_value=False), \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'os.makedirs') as mock_os_makedirs, \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'conf_utils.create_tempest_resources', + return_value=ret_ok), \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'conf_utils.configure_tempest', + return_value=ret): + self.assertEqual(self.tempestcommon.run(), + ret) + self.assertTrue(mock_os_makedirs.called) + + def test_run_missing_generate_test_list(self): + ret = testcase_base.TestcaseBase.EX_RUN_ERROR + ret_ok = testcase_base.TestcaseBase.EX_OK + with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'os.path.exists', return_value=False), \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'os.makedirs') as mock_os_makedirs, \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'conf_utils.create_tempest_resources', + return_value=ret_ok), \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'conf_utils.configure_tempest', + return_value=ret_ok), \ + mock.patch.object(self.tempestcommon, 'generate_test_list', + return_value=ret): + self.assertEqual(self.tempestcommon.run(), + ret) + self.assertTrue(mock_os_makedirs.called) + + def test_run_missing_apply_tempest_blacklist(self): + ret = testcase_base.TestcaseBase.EX_RUN_ERROR + ret_ok = testcase_base.TestcaseBase.EX_OK + with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'os.path.exists', return_value=False), \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'os.makedirs') as mock_os_makedirs, \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'conf_utils.create_tempest_resources', + return_value=ret_ok), \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'conf_utils.configure_tempest', + return_value=ret_ok), \ + mock.patch.object(self.tempestcommon, 'generate_test_list', + return_value=ret_ok), \ + mock.patch.object(self.tempestcommon, 'apply_tempest_blacklist', + return_value=ret): + self.assertEqual(self.tempestcommon.run(), + ret) + self.assertTrue(mock_os_makedirs.called) + + def test_run_missing_parse_verifier_result(self): + ret = testcase_base.TestcaseBase.EX_RUN_ERROR + ret_ok = testcase_base.TestcaseBase.EX_OK + with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'os.path.exists', return_value=False), \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'os.makedirs') as mock_os_makedirs, \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'conf_utils.create_tempest_resources', + return_value=ret_ok), \ + mock.patch('functest.opnfv_tests.openstack.tempest.tempest.' + 'conf_utils.configure_tempest', + return_value=ret_ok), \ + mock.patch.object(self.tempestcommon, 'generate_test_list', + return_value=ret_ok), \ + mock.patch.object(self.tempestcommon, 'apply_tempest_blacklist', + return_value=ret_ok), \ + mock.patch.object(self.tempestcommon, 'run_verifier_tests', + return_value=ret_ok), \ + mock.patch.object(self.tempestcommon, 'parse_verifier_result', + return_value=ret): + self.assertEqual(self.tempestcommon.run(), + ret) + self.assertTrue(mock_os_makedirs.called) + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/functest/tests/unit/utils/test_functest_utils.py b/functest/tests/unit/utils/test_functest_utils.py index bb836011..eb241e5d 100644 --- a/functest/tests/unit/utils/test_functest_utils.py +++ b/functest/tests/unit/utils/test_functest_utils.py @@ -33,6 +33,7 @@ class FunctestUtilsTesting(unittest.TestCase): self.installer = 'test_installer' self.scenario = 'test_scenario' self.build_tag = 'jenkins-functest-fuel-opnfv-jump-2-daily-master-190' + self.build_tag_week = 'jenkins-functest-fuel-baremetal-weekly-master-8' self.version = 'master' self.node_name = 'test_node_name' self.project = 'test_project' @@ -56,6 +57,7 @@ class FunctestUtilsTesting(unittest.TestCase): self.testcase_dict = {'name': 'testname', 'criteria': self.criteria} self.parameter = 'general.openstack.image_name' self.config_yaml = 'test_config_yaml-' + self.db_url_env = 'http://foo/testdb' self.file_yaml = {'general': {'openstack': {'image_name': 'test_image_name'}}} @@ -151,11 +153,21 @@ class FunctestUtilsTesting(unittest.TestCase): self.scenario) @mock.patch('functest.utils.functest_utils.get_build_tag') - def test_get_version_default(self, mock_get_build_tag): + def test_get_version_daily_job(self, mock_get_build_tag): mock_get_build_tag.return_value = self.build_tag self.assertEqual(functest_utils.get_version(), self.version) @mock.patch('functest.utils.functest_utils.get_build_tag') + def test_get_version_weekly_job(self, mock_get_build_tag): + mock_get_build_tag.return_value = self.build_tag_week + self.assertEqual(functest_utils.get_version(), self.version) + + @mock.patch('functest.utils.functest_utils.get_build_tag') + def test_get_version_with_dummy_build_tag(self, mock_get_build_tag): + mock_get_build_tag.return_value = 'whatever' + self.assertEqual(functest_utils.get_version(), 'unknown') + + @mock.patch('functest.utils.functest_utils.get_build_tag') def test_get_version_unknown(self, mock_get_build_tag): mock_get_build_tag.return_value = "unknown_build_tag" self.assertEqual(functest_utils.get_version(), "unknown") @@ -196,8 +208,17 @@ class FunctestUtilsTesting(unittest.TestCase): self.assertEqual(functest_utils.get_build_tag(), self.build_tag) + def test_get_db_url_env_var(self): + with mock.patch.dict(os.environ, + {'TEST_DB_URL': self.db_url_env, + 'CONFIG_FUNCTEST_YAML': + "./functest/ci/config_functest.yaml"}, + clear=True): + self.assertEqual(functest_utils.get_db_url(), + self.db_url_env) + @mock.patch('functest.utils.functest_utils.get_functest_config') - def test_get_db_url(self, mock_get_functest_config): + def test_get_db_url_default(self, mock_get_functest_config): mock_get_functest_config.return_value = self.db_url self.assertEqual(functest_utils.get_db_url(), self.db_url) mock_get_functest_config.assert_called_once_with('results.test_db_url') @@ -274,25 +295,6 @@ class FunctestUtilsTesting(unittest.TestCase): def test_push_results_to_db_missing_buildtag(self): self._test_push_results_to_db_missing_env('BUILD_TAG') - def test_push_results_to_db_incorrect_buildtag(self): - dic = self._get_env_dict(None) - dic['BUILD_TAG'] = 'incorrect_build_tag' - with mock.patch('functest.utils.functest_utils.get_db_url', - return_value=self.db_url), \ - mock.patch.dict(os.environ, - dic, - clear=True), \ - mock.patch('functest.utils.functest_utils.logger.error') \ - as mock_logger_error: - self.assertFalse(functest_utils. - push_results_to_db(self.project, self.case_name, - self.start_date, - self.stop_date, - self.criteria, self.details)) - mock_logger_error.assert_called_once_with("Please fix BUILD_TAG" - " env var: incorrect_" - "build_tag") - def test_push_results_to_db_request_post_failed(self): dic = self._get_env_dict(None) with mock.patch('functest.utils.functest_utils.get_db_url', diff --git a/functest/tests/unit/utils/test_openstack_clean.py b/functest/tests/unit/utils/test_openstack_clean.py index 28eab4f8..15669538 100644 --- a/functest/tests/unit/utils/test_openstack_clean.py +++ b/functest/tests/unit/utils/test_openstack_clean.py @@ -20,13 +20,41 @@ class OSCleanTesting(unittest.TestCase): def _get_instance(self, key): mock_obj = mock.Mock() attrs = {'id': 'id' + str(key), 'name': 'name' + str(key), - 'ip': 'ip' + str(key)} + 'ip': 'ip' + str(key), 'status': 'ACTIVE', + 'OS-EXT-STS:task_state': '-'} + mock_obj.configure_mock(**attrs) + return mock_obj + + def _get_instance_deleted(self, key): + mock_obj = mock.Mock() + attrs = {'id': 'id' + str(key), 'name': 'name' + str(key), + 'ip': 'ip' + str(key), 'status': 'DELETED', + 'OS-EXT-STS:task_state': '-'} + mock_obj.configure_mock(**attrs) + return mock_obj + + def _get_instance_deleting(self, key): + mock_obj = mock.Mock() + attrs = {'id': 'id' + str(key), 'name': 'name' + str(key), + 'ip': 'ip' + str(key), 'status': 'BUILD', + 'OS-EXT-STS:task_state': 'deleting'} + mock_obj.configure_mock(**attrs) + return mock_obj + + def _get_instance_other(self, key): + mock_obj = mock.Mock() + attrs = {'id': 'id' + str(key), 'name': 'name' + str(key), + 'ip': 'ip' + str(key), 'status': 'BUILD', + 'OS-EXT-STS:task_state': 'networking'} mock_obj.configure_mock(**attrs) return mock_obj def setUp(self): self.client = mock.Mock() self.test_list = [self._get_instance(1), self._get_instance(2)] + self.deleted_list = [self._get_instance_deleted(5), + self._get_instance_deleting(6)] + self.other_list = [self._get_instance_other(7)] self.update_list = {'id1': 'name1', 'id2': 'name2'} self.remove_list = {'id3': 'name3', 'id4': 'name4'} self.test_dict_list = [{'id': 'id1', 'name': 'name1', 'ip': 'ip1', @@ -77,6 +105,33 @@ class OSCleanTesting(unittest.TestCase): " '\s*\S+'" " ...")) + @mock.patch('functest.utils.openstack_clean.logger.debug') + def test_remove_instances_pending_delete_success(self, mock_logger_debug): + with mock.patch('functest.utils.openstack_clean.os_utils' + '.get_instances', return_value=self.deleted_list), \ + mock.patch('functest.utils.openstack_clean.os_utils' + '.delete_instance', return_value=True): + openstack_clean.remove_instances(self.client, self.remove_list) + mock_logger_debug.assert_any_call("Removing Nova instances...") + mock_logger_debug.test_utils.RegexMatch("Removing" + " instance" + " '\s*\S+'" + " ...").assert_not_called() + + @mock.patch('functest.utils.openstack_clean.logger.debug') + def test_remove_instances_other_delete_success(self, mock_logger_debug): + with mock.patch('functest.utils.openstack_clean.os_utils' + '.get_instances', return_value=self.other_list), \ + mock.patch('functest.utils.openstack_clean.os_utils' + '.delete_instance', return_value=True): + openstack_clean.remove_instances(self.client, self.remove_list) + mock_logger_debug.assert_any_call("Removing Nova instances...") + mock_logger_debug.assert_any_call(" > Request sent.") + mock_logger_debug.assert_any_call(test_utils.RegexMatch("Removing" + " instance" + " '\s*\S+'" + " ...")) + @mock.patch('functest.utils.openstack_clean.logger.error') @mock.patch('functest.utils.openstack_clean.logger.debug') def test_remove_instances_delete_failed(self, mock_logger_debug, diff --git a/functest/utils/functest_logger.py b/functest/utils/functest_logger.py index 022211cb..022211cb 100755..100644 --- a/functest/utils/functest_logger.py +++ b/functest/utils/functest_logger.py diff --git a/functest/utils/functest_utils.py b/functest/utils/functest_utils.py index dbed811a..7cc5029d 100644 --- a/functest/utils/functest_utils.py +++ b/functest/utils/functest_utils.py @@ -111,12 +111,13 @@ def get_version(): # if launched through CI the build tag has the following format # jenkins-<project>-<installer>-<pod>-<job>-<branch>-<id> # e.g. jenkins-functest-fuel-opnfv-jump-2-daily-master-190 + # jenkins-functest-fuel-baremetal-weekly-master-8 # use regex to match branch info - rule = "daily-(.+?)-[0-9]*" + rule = "(dai|week)ly-(.+?)-[0-9]*" build_tag = get_build_tag() m = re.search(rule, build_tag) if m: - return m.group(1) + return m.group(2) else: return "unknown" @@ -151,7 +152,13 @@ def get_db_url(): """ Returns DB URL """ - return get_functest_config('results.test_db_url') + # TODO use CONST mechanism + try: + # if TEST_DB_URL declared in env variable, use it! + db_url = os.environ['TEST_DB_URL'] + except KeyError: + db_url = get_functest_config('results.test_db_url') + return db_url def logger_test_results(project, case_name, status, details): @@ -200,13 +207,7 @@ def push_results_to_db(project, case_name, except KeyError as e: logger.error("Please set env var: " + str(e)) return False - rule = "daily-(.+?)-[0-9]*" - m = re.search(rule, build_tag) - if m: - version = m.group(1) - else: - logger.error("Please fix BUILD_TAG env var: " + build_tag) - return False + version = get_version() test_start = dt.fromtimestamp(start_date).strftime('%Y-%m-%d %H:%M:%S') test_stop = dt.fromtimestamp(stop_date).strftime('%Y-%m-%d %H:%M:%S') diff --git a/functest/utils/openstack_clean.py b/functest/utils/openstack_clean.py index 15a8f33d..ce61fcac 100755 --- a/functest/utils/openstack_clean.py +++ b/functest/utils/openstack_clean.py @@ -49,9 +49,14 @@ def remove_instances(nova_client, default_instances): for instance in instances: instance_name = getattr(instance, 'name') instance_id = getattr(instance, 'id') + instance_status = getattr(instance, 'status') + instance_state = getattr(instance, 'OS-EXT-STS:task_state') + logger.debug("'%s', ID=%s " % (instance_name, instance_id)) if (instance_id not in default_instances and - instance_name not in default_instances.values()): + instance_name not in default_instances.values() and + instance_status != 'DELETED' and + (instance_status != 'BUILD' or instance_state != 'deleting')): logger.debug("Removing instance '%s' ..." % instance_id) if os_utils.delete_instance(nova_client, instance_id): logger.debug(" > Request sent.") diff --git a/functest/utils/openstack_utils.py b/functest/utils/openstack_utils.py index ffc870f6..ffc870f6 100755..100644 --- a/functest/utils/openstack_utils.py +++ b/functest/utils/openstack_utils.py diff --git a/run_unit_tests.sh b/run_unit_tests.sh index e0660910..32076dab 100755 --- a/run_unit_tests.sh +++ b/run_unit_tests.sh @@ -25,12 +25,10 @@ pip install -r $WORKSPACE/test-requirements.txt pip install $WORKSPACE #install releng -cd $WORKSPACE/../ rm -rf releng-unittests -git clone https://gerrit.opnfv.org/gerrit/releng releng-unittests +git clone --depth 1 https://gerrit.opnfv.org/gerrit/releng releng-unittests pip install releng-unittests/modules/ rm -fr releng-unittests -cd $WORKSPACE export CONFIG_FUNCTEST_YAML=$(pwd)/functest/ci/config_functest.yaml # unit tests @@ -46,7 +44,7 @@ nosetests --with-xunit \ --cover-package=functest.opnfv_tests.sdn.odl.odl \ --cover-package=functest.opnfv_tests.vnf.ims \ --cover-package=functest.utils \ - --cover-package=functest.opnfv_tests.openstack.rally \ + --cover-package=functest.opnfv_tests.openstack \ --cover-xml \ --cover-html \ --log-config=$(pwd)/functest/tests/unit/test_logging.ini \ |