diff --git a/.gitmodules b/.gitmodules index 07da7c2..c02091b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -11,3 +11,7 @@ [submodule "repositories/python/manila"] path = repositories/python/manila url = https://github.com/openstack/manila.git +[submodule "plugin_test/fuel-qa"] + path = plugin_test/fuel-qa + url = https://github.com/openstack/fuel-qa.git + bransh = stable/mitaka diff --git a/plugin_test/__init__.py b/plugin_test/__init__.py new file mode 100644 index 0000000..b5ff96e --- /dev/null +++ b/plugin_test/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2015 Mirantis, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. diff --git a/plugin_test/fuel-qa b/plugin_test/fuel-qa new file mode 160000 index 0000000..3e8f4de --- /dev/null +++ b/plugin_test/fuel-qa @@ -0,0 +1 @@ +Subproject commit 3e8f4dec153a8df434ff91324d7f71f6e8f0c7a5 diff --git a/plugin_test/helpers/__init__.py b/plugin_test/helpers/__init__.py new file mode 100644 index 0000000..f50a10a --- /dev/null +++ b/plugin_test/helpers/__init__.py @@ -0,0 +1,14 @@ +"""Copyright 2016 Mirantis, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); you may +not use this file except in compliance with the License. You may obtain +copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations +under the License. +""" diff --git a/plugin_test/helpers/plugin.py b/plugin_test/helpers/plugin.py new file mode 100644 index 0000000..475cc40 --- /dev/null +++ b/plugin_test/helpers/plugin.py @@ -0,0 +1,57 @@ +"""Copyright 2016 Mirantis, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); you may +not use this file except in compliance with the License. You may obtain +copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations +under the License. +""" + +import os + +from fuelweb_test.helpers import utils + +from proboscis.asserts import assert_true + +from settings import MANILA_PLUGIN_PATH +from settings import plugin_name + + +# constant +msg = "Plugin couldn't be enabled. Check plugin version. Test aborted" + + +def install_manila_plugin(master_node_ip): + """Install plugin packages to the master node.""" + utils.upload_tarball( + master_node_ip, + MANILA_PLUGIN_PATH, "/var") + utils.install_plugin_check_code( + master_node_ip, + os.path.basename(MANILA_PLUGIN_PATH)) + + +def enable_plugin_manila(cluster_id, fuel_web_client): + """Enable Manila plugin on cluster.""" + assert_true( + fuel_web_client.check_plugin_exists( + cluster_id, plugin_name), + msg) + options = {'metadata/enabled': True} + fuel_web_client.update_plugin_data(cluster_id, plugin_name, options) + + +def disable_plugin_manila(cluster_id, fuel_web_client): + """Disable Manila plugin on cluster.""" + assert_true( + fuel_web_client.check_plugin_exists( + cluster_id, plugin_name), + msg) + options = {'metadata/enabled': False} + fuel_web_client.update_plugin_data(cluster_id, plugin_name, options) diff --git a/plugin_test/helpers/settings.py b/plugin_test/helpers/settings.py new file mode 100644 index 0000000..bb751d5 --- /dev/null +++ b/plugin_test/helpers/settings.py @@ -0,0 +1,20 @@ +"""Copyright 2016 Mirantis, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); you may +not use this file except in compliance with the License. You may obtain +copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations +under the License. +""" + + +import os +MANILA_PLUGIN_VERSION = os.environ.get('MANILA_PLUGIN_VERSION') +MANILA_PLUGIN_PATH = os.environ.get('MANILA_PLUGIN_PATH') +plugin_name = 'fuel-plugin-manila' diff --git a/plugin_test/run_tests.py b/plugin_test/run_tests.py new file mode 100644 index 0000000..5f14645 --- /dev/null +++ b/plugin_test/run_tests.py @@ -0,0 +1,76 @@ +"""Copyright 2015 Mirantis, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); you may +not use this file except in compliance with the License. You may obtain +copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations +under the License. +""" + +import sys +import os +import re +from nose.plugins import Plugin +from paramiko.transport import _join_lingering_threads + + +class CloseSSHConnectionsPlugin(Plugin): + """Closes all paramiko's ssh connections after each test case. + + Plugin fixes proboscis disability to run cleanup of any kind. + 'afterTest' calls _join_lingering_threads function from paramiko, + which stops all threads (set the state to inactive and joins for 10s) + """ + + name = 'closesshconnections' + + def options(self, parser, env=os.environ): + """Options.""" + super(CloseSSHConnectionsPlugin, self).options(parser, env=env) + + def configure(self, options, conf): + """Configure env.""" + super(CloseSSHConnectionsPlugin, self).configure(options, conf) + self.enabled = True + + def afterTest(self, *args, **kwargs): + """After_Test. + + After_Test calls _join_lingering_threads function from paramiko, + which stops all threads (set the state to inactive and joins for 10s). + """ + _join_lingering_threads() + + +def import_tests(): + """Import test suite of project.""" + from tests import test_smoke_bvt # noqa + + +def run_tests(): + """Run test cases.""" + from proboscis import TestProgram # noqa + import_tests() + + # Run Proboscis and exit. + TestProgram( + addplugins=[CloseSSHConnectionsPlugin()] + ).run_and_exit() + + +if __name__ == '__main__': + sys.path.append(sys.path[0] + "/fuel-qa") + import_tests() + from fuelweb_test.helpers.patching import map_test + if any(re.search(r'--group=patching_master_tests', arg) + for arg in sys.argv): + map_test('master') + elif any(re.search(r'--group=patching.*', arg) for arg in sys.argv): + map_test('environment') + run_tests() diff --git a/plugin_test/tests/__init__.py b/plugin_test/tests/__init__.py new file mode 100644 index 0000000..f50a10a --- /dev/null +++ b/plugin_test/tests/__init__.py @@ -0,0 +1,14 @@ +"""Copyright 2016 Mirantis, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); you may +not use this file except in compliance with the License. You may obtain +copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations +under the License. +""" diff --git a/plugin_test/tests/test_smoke_bvt.py b/plugin_test/tests/test_smoke_bvt.py new file mode 100644 index 0000000..48dd509 --- /dev/null +++ b/plugin_test/tests/test_smoke_bvt.py @@ -0,0 +1,269 @@ +"""Copyright 2016 Mirantis, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); you may +not use this file except in compliance with the License. You may obtain +copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations +under the License. +""" + +from proboscis import test +from proboscis.asserts import assert_true + +from fuelweb_test.helpers.decorators import log_snapshot_after_test +from fuelweb_test.tests.base_test_case import TestBasic +from fuelweb_test.tests.base_test_case import SetupEnvironment +from fuelweb_test.settings import DEPLOYMENT_MODE +from fuelweb_test.settings import NEUTRON_SEGMENT_TYPE + +from helpers import plugin +from helpers import settings + + +@test(groups=['manila_plugin', 'manila_bvt_smoke']) +class TestManilaSmoke(TestBasic): + """Smoke test suite. + + The goal of smoke testing is to ensure that the most critical features + of Fuel Manila plugin work after new build delivery. Smoke tests + will be used by QA to accept software builds from Development team. + + """ + + @test(depends_on=[SetupEnvironment.prepare_slaves_1], + groups=["manila_install"]) + @log_snapshot_after_test + def manila_install(self): + """Check that plugin can be installed. + + Scenario: + 1. Upload plugins to the master node + 2. Install plugin. + 3. Ensure that plugin is installed successfully using cli, + run command 'fuel plugins list'. Check name, version of plugin. + 4.Create a new environment with following parameters: + * Compute: hypervisor QEMU-KVM + * Networking: Neutron with VLAN segmentation + * Storage: default + * Additional services: default + 5. Enable Manila plugin for new environment. + 6. Attempt to remove enabled plugin. + Verify that plugin cannot be removed when it already enabled, + run command 'fuel plugins'. + 7.Disable plugin + 8.Remove Plugin Manila + Verify that plugin is removed, run command 'fuel plugins'. + Duration: 20 min + + """ + self.env.revert_snapshot("ready_with_1_slaves") + + self.show_step(1) + self.show_step(2) + plugin.install_manila_plugin(self.ssh_manager.admin_ip) + + cmd = 'fuel plugins list' + output = self.ssh_manager.execute_on_remote( + ip=self.ssh_manager.admin_ip, + cmd=cmd)['stdout'].pop().split(' ') + self.show_step(3) + # check name + assert_true( + settings.MANILA_PLUGIN_VERSION in output, + "Plugin version '{0}' not found.".format( + settings.MANILA_PLUGIN_VERSION) + ) + # check version + assert_true( + settings.plugin_name in output, + "Plugin '{0}' is not installed.".format(settings.plugin_name) + ) + + self.show_step(4) + # Configure new cluster + cluster_id = self.fuel_web.create_cluster( + name=self.__class__.__name__, + mode=DEPLOYMENT_MODE, + settings={ + "net_provider": 'neutron', + "net_segment_type": NEUTRON_SEGMENT_TYPE + } + ) + + self.show_step(5) + plugin.enable_plugin_manila( + cluster_id, self.fuel_web) + + self.show_step(6) + cmd = 'fuel plugins --remove {0}=={1}'.format( + settings.plugin_name, settings.MANILA_PLUGIN_VERSION) + output = self.ssh_manager.execute_on_remote( + ip=self.ssh_manager.admin_ip, + cmd=cmd, + assert_ec_equal=[1])['stderr'].pop() + # check for error message + msg = "delete plugin which is enabled for some environment" + + assert_true( + msg in output, + "Expected error message did not found in output" + ) + + self.show_step(7) + plugin.disable_plugin_manila( + cluster_id, self.fuel_web) + + self.show_step(8) + + cmd = 'fuel plugins --remove {0}=={1}'.format( + settings.plugin_name, settings.MANILA_PLUGIN_VERSION) + output = self.ssh_manager.execute_on_remote( + ip=self.ssh_manager.admin_ip, + cmd=cmd)['stdout'].pop().split(' ') + + assert_true( + plugin.plugin_name not in output, + "Plugin '{0}' is not removed".format(settings.plugin_name) + ) + + @test(depends_on=[SetupEnvironment.prepare_slaves_3], + groups=["manila_smoke"]) + @log_snapshot_after_test + def manila_smoke(self): + """Check deployment with Manila plugin and one controller. + + Scenario: + 1. Upload plugins to the master node + 2. Install plugin. + 3. Create a new environment with following parameters: + * Compute: KVM/QEMU + * Networking: Neutron with VLAN segmentation + * Storage: Cepth + * Additional services: default + 4. Add nodes with following roles: + * Controller + * Compute + * Cinder + 5. Configure interfaces on nodes. + 6. Configure network settings. + 7. Enable and configure Manila plugin. + 8. Verify networks. + 9. Deploy the cluster. + Duration: 1.8 hour + + """ + self.env.revert_snapshot("ready_with_3_slaves") + self.show_step(1) + self.show_step(2) + plugin.install_manila_plugin(self.ssh_manager.admin_ip) + + self.show_step(3) + # Configure new cluster + cluster_id = self.fuel_web.create_cluster( + name=self.__class__.__name__, + mode=DEPLOYMENT_MODE, + settings={ + "net_provider": 'neutron', + "net_segment_type": NEUTRON_SEGMENT_TYPE + } + ) + self.show_step(4) + # Assign role to node + self.fuel_web.update_nodes( + cluster_id, + {'slave-01': ['controller'], + 'slave-02': ['compute'], + 'slave-03': ['cinder'] + } + ) + + self.show_step(5) + self.show_step(6) + self.show_step(7) + plugin.enable_plugin_manila( + cluster_id, self.fuel_web) + + self.show_step(8) + self.fuel_web.verify_network(cluster_id) + + self.show_step(9) + self.fuel_web.deploy_cluster_wait(cluster_id) + + @test(depends_on=[SetupEnvironment.prepare_slaves_5], + groups=["manila_bvt"]) + @log_snapshot_after_test + def manila_bvt(self): + """Check deployment with Manila plugin and one controller. + + Scenario: + 1. Upload plugins to the master node + 2. Install plugin. + 3. Create a new environment HA with following parameters: + * Compute: KVM/QEMU + * Networking: Neutron with VLAN segmentation + * Storage: Cepth + * Additional services: default + 4. Add nodes with following roles: + * Controller + Cinder + * Controller + Cinder + * Controller + Cinder + * Compute + * Compute + 5. Configure interfaces on nodes. + 6. Configure network settings. + 7. Enable and configure Manila plugin. + 8. Verify networks. + 9. Deploy the cluster. + 10. Run OSTF. + Duration: 2.2 hour + + """ + self.env.revert_snapshot("ready_with_5_slaves") + + self.show_step(1) + self.show_step(2) + plugin.install_manila_plugin(self.ssh_manager.admin_ip) + + self.show_step(3) + # Configure new cluster + cluster_id = self.fuel_web.create_cluster( + name=self.__class__.__name__, + mode=DEPLOYMENT_MODE, + settings={ + "net_provider": 'neutron', + "net_segment_type": NEUTRON_SEGMENT_TYPE + } + ) + self.show_step(4) + # Assign role to node + self.fuel_web.update_nodes( + cluster_id, + {'slave-01': ['controller', 'cinder'], + 'slave-02': ['controller', 'cinder'], + 'slave-03': ['controller', 'cinder'], + 'slave-04': ['compute'], + 'slave-05': ['compute'] + } + ) + + self.show_step(5) + self.show_step(6) + self.show_step(7) + plugin.enable_plugin_manila( + cluster_id, self.fuel_web) + + self.show_step(8) + self.fuel_web.verify_network(cluster_id) + + self.show_step(9) + self.fuel_web.deploy_cluster_wait(cluster_id) + + self.show_step(10) + self.fuel_web.run_ostf( + cluster_id=cluster_id, test_sets=['smoke', 'sanity', 'ha']) diff --git a/plugin_test/utils/jenkins/system_tests.sh b/plugin_test/utils/jenkins/system_tests.sh new file mode 100755 index 0000000..1042f09 --- /dev/null +++ b/plugin_test/utils/jenkins/system_tests.sh @@ -0,0 +1,496 @@ +#!/bin/sh +PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + +# functions + +INVALIDOPTS_ERR=100 +NOJOBNAME_ERR=101 +NOISOPATH_ERR=102 +NOTASKNAME_ERR=103 +NOWORKSPACE_ERR=104 +DEEPCLEAN_ERR=105 +MAKEISO_ERR=106 +NOISOFOUND_ERR=107 +COPYISO_ERR=108 +SYMLINKISO_ERR=109 +CDWORKSPACE_ERR=110 +ISODOWNLOAD_ERR=111 +INVALIDTASK_ERR=112 + +# Defaults + +export REBOOT_TIMEOUT=${REBOOT_TIMEOUT:-5000} +export ALWAYS_CREATE_DIAGNOSTIC_SNAPSHOT=${ALWAYS_CREATE_DIAGNOSTIC_SNAPSHOT:-true} + +# Export specified settings +if [ -z "$NODE_VOLUME_SIZE" ]; then export NODE_VOLUME_SIZE=350; fi +if [ -z "$OPENSTACK_RELEASE" ]; then export OPENSTACK_RELEASE=Ubuntu; fi +if [ -z "$ENV_NAME" ]; then export ENV_NAME="manila"; fi +if [ -z "$ADMIN_NODE_MEMORY" ]; then export ADMIN_NODE_MEMORY=4096; fi +if [ -z "$ADMIN_NODE_CPU" ]; then export ADMIN_NODE_CPU=4; fi +if [ -z "$SLAVE_NODE_MEMORY" ]; then export SLAVE_NODE_MEMORY=4096; fi +if [ -z "$SLAVE_NODE_CPU" ]; then export SLAVE_NODE_CPU=4; fi + +# Init and update submodule +git submodule update --init --recursive --remote + +sudo /sbin/iptables -F +sudo /sbin/iptables -t nat -F +sudo /sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE + + +ShowHelp() { +cat << EOF +System Tests Script + +It can perform several actions depending on Jenkins JOB_NAME it's ran from +or it can take names from exported environment variables or command line options +if you do need to override them. + +-w (dir) - Path to workspace where fuelweb git repository was checked out. + Uses Jenkins' WORKSPACE if not set +-e (name) - Directly specify environment name used in tests + Uses ENV_NAME variable is set. +-j (name) - Name of this job. Determines ISO name, Task name and used by tests. + Uses Jenkins' JOB_NAME if not set +-v - Do not use virtual environment +-V (dir) - Path to python virtual environment +-i (file) - Full path to ISO file to build or use for tests. + Made from iso dir and name if not set. +-t (name) - Name of task this script should perform. Should be one of defined ones. + Taken from Jenkins' job's suffix if not set. +-o (str) - Allows you any extra command line option to run test job if you + want to use some parameters. +-a (str) - Allows you to path NOSE_ATTR to the test job if you want + to use some parameters. +-A (str) - Allows you to path NOSE_EVAL_ATTR if you want to enter attributes + as python expressions. +-m (name) - Use this mirror to build ISO from. + Uses 'srt' if not set. +-U - ISO URL for tests. + Null by default. +-r (yes/no) - Should built ISO file be places with build number tag and + symlinked to the last build or just copied over the last file. +-b (num) - Allows you to override Jenkins' build number if you need to. +-l (dir) - Path to logs directory. Can be set by LOGS_DIR evironment variable. + Uses WORKSPACE/logs if not set. +-d - Dry run mode. Only show what would be done and do nothing. + Useful for debugging. +-k - Keep previously created test environment before tests run +-K - Keep test environment after tests are finished +-h - Show this help page + +Most variables uses guesing from Jenkins' job name but can be overriden +by exported variable before script is run or by one of command line options. + +You can override following variables using export VARNAME="value" before running this script +WORKSPACE - path to directory where Fuelweb repository was checked out by Jenkins or manually +JOB_NAME - name of Jenkins job that determines which task should be done and ISO file name. + +If task name is "iso" it will make iso file +Other defined names will run Nose tests using previously built ISO file. + +ISO file name is taken from job name prefix +Task name is taken from job name suffix +Separator is one dot '.' + +For example if JOB_NAME is: +mytest.somestring.iso +ISO name: mytest.iso +Task name: iso +If ran with such JOB_NAME iso file with name mytest.iso will be created + +If JOB_NAME is: +mytest.somestring.node +ISO name: mytest.iso +Task name: node +If script was run with this JOB_NAME node tests will be using ISO file mytest.iso. + +First you should run mytest.somestring.iso job to create mytest.iso. +Then you can ran mytest.somestring.node job to start tests using mytest.iso and other tests too. +EOF +} + +GlobalVariables() { + # where built iso's should be placed + # use hardcoded default if not set before by export + #ISO_DIR="${ISO_DIR:=/var/www/fuelweb-iso}" + ISO_DIR="/storage/downloads" + # name of iso file + # taken from jenkins job prefix + # if not set before by variable export + #if [ -z "${ISO_NAME}" ]; then + # ISO_NAME="${JOB_NAME%.*}.iso" + #fi + ISO_NAME="MirantisOpenStack-9.0.iso" + # full path where iso file should be placed + # make from iso name and path to iso shared directory + # if was not overriden by options or export + if [ -z "${ISO_PATH}" ]; then + ISO_PATH="${ISO_DIR}/${ISO_NAME}" + fi + + # what task should be ran + # it's taken from jenkins job name suffix if not set by options + if [ -z "${TASK_NAME}" ]; then + TASK_NAME="${JOB_NAME##*.}" + fi + + # do we want to keep iso's for each build or just copy over single file + ROTATE_ISO="${ROTATE_ISO:=yes}" + + # choose mirror to build iso from. Default is 'srt' for Saratov's mirror + # you can change mirror by exporting USE_MIRROR variable before running this script + USE_MIRROR="${USE_MIRROR:=srt}" + + # only show what commands would be executed but do nothing + # this feature is usefull if you want to debug this script's behaviour + DRY_RUN="${DRY_RUN:=no}" + + VENV="${VENV:=yes}" +} + +GetoptsVariables() { + while getopts ":w:j:i:t:o:a:A:m:U:r:b:V:l:dkKe:v:h" opt; do + case $opt in + w) + WORKSPACE="${OPTARG}" + ;; + j) + JOB_NAME="${OPTARG}" + ;; + i) + ISO_PATH="${OPTARG}" + ;; + t) + TASK_NAME="${OPTARG}" + ;; + o) + TEST_OPTIONS="${TEST_OPTIONS} ${OPTARG}" + ;; + a) + NOSE_ATTR="${OPTARG}" + ;; + A) + NOSE_EVAL_ATTR="${OPTARG}" + ;; + m) + USE_MIRROR="${OPTARG}" + ;; + U) + ISO_URL="${OPTARG}" + ;; + r) + ROTATE_ISO="${OPTARG}" + ;; + b) + BUILD_NUMBER="${OPTARG}" + ;; + V) + VENV_PATH="${OPTARG}" + ;; + l) + LOGS_DIR="${OPTARG}" + ;; + k) + KEEP_BEFORE="yes" + ;; + K) + KEEP_AFTER="yes" + ;; + e) + ENV_NAME="${OPTARG}" + ;; + d) + DRY_RUN="yes" + ;; + v) + VENV="no" + ;; + h) + ShowHelp + exit 0 + ;; + \?) + echo "Invalid option: -$OPTARG" + ShowHelp + exit $INVALIDOPTS_ERR + ;; + :) + echo "Option -$OPTARG requires an argument." + ShowHelp + exit $INVALIDOPTS_ERR + ;; + esac + done +} + +CheckVariables() { + + if [ -z "${JOB_NAME}" ]; then + echo "Error! JOB_NAME is not set!" + exit $NOJOBNAME_ERR + fi + + if [ -z "${ISO_PATH}" ]; then + echo "Error! ISO_PATH is not set!" + exit $NOISOPATH_ERR + fi + + if [ -z "${TASK_NAME}" ]; then + echo "Error! TASK_NAME is not set!" + exit $NOTASKNAME_ERR + fi + + if [ -z "${WORKSPACE}" ]; then + echo "Error! WORKSPACE is not set!" + exit $NOWORKSPACE_ERR + fi +} + +MakeISO() { + # Create iso file to be used in tests + + # clean previous garbage + if [ "${DRY_RUN}" = "yes" ]; then + echo make deep_clean + else + make deep_clean + fi + ec="${?}" + + if [ "${ec}" -gt "0" ]; then + echo "Error! Deep clean failed!" + exit $DEEPCLEAN_ERR + fi + + # create ISO file + export USE_MIRROR + if [ "${DRY_RUN}" = "yes" ]; then + echo make iso + else + make iso + fi + ec=$? + + if [ "${ec}" -gt "0" ]; then + echo "Error making ISO!" + exit $MAKEISO_ERR + fi + + if [ "${DRY_RUN}" = "yes" ]; then + ISO="${WORKSPACE}/build/iso/fuel.iso" + else + ISO="$(find "${WORKSPACE}/build/iso/"*".iso" | head -n 1)" + # check that ISO file exists + if [ ! -f "${ISO}" ]; then + echo "Error! ISO file not found!" + exit $NOISOFOUND_ERR + fi + fi + + # copy ISO file to storage dir + # if rotation is enabled and build number is aviable + # save iso to tagged file and symlink to the last build + # if rotation is not enabled just copy iso to iso_dir + + if [ "${ROTATE_ISO}" = "yes" -a "${BUILD_NUMBER}" != "" ]; then + # copy iso file to shared dir with revision tagged name + NEW_BUILD_ISO_PATH="${ISO_PATH#.iso}_${BUILD_NUMBER}.iso" + if [ "${DRY_RUN}" = "yes" ]; then + echo cp "${ISO}" "${NEW_BUILD_ISO_PATH}" + else + cp "${ISO}" "${NEW_BUILD_ISO_PATH}" + fi + ec=$? + + if [ "${ec}" -gt "0" ]; then + echo "Error! Copy ${ISO} to ${NEW_BUILD_ISO_PATH} failed!" + exit $COPYISO_ERR + fi + + # create symlink to the last built ISO file + if [ "${DRY_RUN}" = "yes" ]; then + echo ln -sf "${NEW_BUILD_ISO_PATH}" "${ISO_PATH}" + else + ln -sf "${NEW_BUILD_ISO_PATH}" "${ISO_PATH}" + fi + ec=$? + + if [ "${ec}" -gt "0" ]; then + echo "Error! Create symlink from ${NEW_BUILD_ISO_PATH} to ${ISO_PATH} failed!" + exit $SYMLINKISO_ERR + fi + else + # just copy file to shared dir + if [ "${DRY_RUN}" = "yes" ]; then + echo cp "${ISO}" "${ISO_PATH}" + else + cp "${ISO}" "${ISO_PATH}" + fi + ec=$? + + if [ "${ec}" -gt "0" ]; then + echo "Error! Copy ${ISO} to ${ISO_PATH} failed!" + exit $COPYISO_ERR + fi + fi + + if [ "${ec}" -gt "0" ]; then + echo "Error! Copy ISO from ${ISO} to ${ISO_PATH} failed!" + exit $COPYISO_ERR + fi + echo "Finished building ISO: ${ISO_PATH}" + exit 0 +} + +CdWorkSpace() { + # chdir into workspace or fail if could not + if [ "${DRY_RUN}" != "yes" ]; then + cd "${WORKSPACE}" + ec=$? + + if [ "${ec}" -gt "0" ]; then + echo "Error! Cannot cd to WORKSPACE!" + exit $CDWORKSPACE_ERR + fi + else + echo cd "${WORKSPACE}" + fi +} + +RunTest() { + # Run test selected by task name + + # check if iso file exists + if [ ! -f "${ISO_PATH}" ]; then + if [ -z "${ISO_URL}" -a "${DRY_RUN}" != "yes" ]; then + echo "Error! File ${ISO_PATH} not found and no ISO_URL (-U key) for downloading!" + exit $NOISOFOUND_ERR + else + if [ "${DRY_RUN}" = "yes" ]; then + echo wget -c "${ISO_URL}" -O "${ISO_PATH}" + else + echo "No ${ISO_PATH} found. Trying to download file." + wget -c "${ISO_URL}" -O "${ISO_PATH}" + rc=$? + if [ $rc -ne 0 ]; then + echo "Failed to fetch ISO from ${ISO_URL}" + exit $ISODOWNLOAD_ERR + fi + fi + fi + fi + + if [ -z "${VENV_PATH}" ]; then + VENV_PATH="/home/jenkins/venv-nailgun-tests" + fi + + # run python virtualenv + if [ "${VENV}" = "yes" ]; then + if [ "${DRY_RUN}" = "yes" ]; then + echo . $VENV_PATH/bin/activate + else + . $VENV_PATH/bin/activate + fi + fi + + if [ "${ENV_NAME}" = "" ]; then + ENV_NAME="${JOB_NAME}_system_test" + fi + + if [ "${LOGS_DIR}" = "" ]; then + LOGS_DIR="${WORKSPACE}/logs" + fi + + if [ ! -f "$LOGS_DIR" ]; then + mkdir -p "$LOGS_DIR" + fi + + export ENV_NAME + export LOGS_DIR + export ISO_PATH + + if [ "${KEEP_BEFORE}" != "yes" ]; then + # remove previous environment + if [ "${DRY_RUN}" = "yes" ]; then + echo dos.py erase "${ENV_NAME}" + else + if dos.py list | grep "^${ENV_NAME}\$"; then + dos.py erase "${ENV_NAME}" + fi + fi + fi + + # gather additional option for this nose test run + OPTS="" + if [ -n "${NOSE_ATTR}" ]; then + OPTS="${OPTS} -a ${NOSE_ATTR}" + fi + if [ -n "${NOSE_EVAL_ATTR}" ]; then + OPTS="${OPTS} -A ${NOSE_EVAL_ATTR}" + fi + if [ -n "${TEST_OPTIONS}" ]; then + OPTS="${OPTS} ${TEST_OPTIONS}" + fi + + # run python test set to create environments, deploy and test product + if [ "${DRY_RUN}" = "yes" ]; then + echo export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}${WORKSPACE}" + echo python plugin_test/run_tests.py -q --nologcapture --with-xunit ${OPTS} + else + export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}${WORKSPACE}" + echo "${PYTHONPATH}" + python plugin_test/run_tests.py -q --nologcapture --with-xunit ${OPTS} + + fi + ec=$? + + if [ "${KEEP_AFTER}" != "yes" ]; then + # remove environment after tests + if [ "${DRY_RUN}" = "yes" ]; then + echo dos.py destroy "${ENV_NAME}" + else + dos.py destroy "${ENV_NAME}" + fi + fi + + exit "${ec}" +} + +RouteTasks() { + # this selector defines task names that are recognised by this script + # and runs corresponding jobs for them + # running any jobs should exit this script + + case "${TASK_NAME}" in + test) + RunTest + ;; + iso) + MakeISO + ;; + *) + echo "Unknown task: ${TASK_NAME}!" + exit $INVALIDTASK_ERR + ;; + esac + exit 0 +} + +# MAIN + +# first we want to get variable from command line options +GetoptsVariables "${@}" + +# then we define global variables and there defaults when needed +GlobalVariables + +# check do we have all critical variables set +CheckVariables + +# first we chdir into our working directory unless we dry run +CdWorkSpace + +# finally we can choose what to do according to TASK_NAME +RouteTasks