Neutron/FunctionalGateSetup
目录
设置功能门
此wiki包含有关如何为仓库设置功能测试门的说明。以neutron-vpnaas仓库为例。
准备工作
克隆project-config仓库,以便可以形成一个提交来支持该仓库。
git clone https://github.com/openstack-infra/project-config
设置非投票实验性测试运行
在openstack-infra project-config仓库中,修改此项目的zuul/ayout.yaml。首先,应该在‘projects:’下创建一个项目条目。在VPNaaS中,已经存在条目
projects:
...
- name: openstack/neutron-vpnaas
template:
- name: check-requirements
- name: integrated-gate-neutron
- name: merge-check
- name: python-jobs
- name: openstack-server-release-jobs
有了这个项目,只有模板,没有check、gate、post或experimental部分。现在,我们将添加一个新的测试,在experimental部分下,这样只有当用户在Gerrit评论中添加“check experimental”时才会运行该测试
experimental:
- check-neutron-vpnaas-dsvm-functional
在“jobs:”部分,我们需要将此测试标记为非投票:用于检查队列
jobs:
...
- name: check-neutron-vpnaas-dsvm-functional
voting: false
接下来,必须在jenkins/jobs/中为VPNaaS仓库创建一个作业。为了加快速度,并且因为需求相似,将neutron-functional.yaml复制到neutron-vpnaas-functional.yaml。更改是针对文件顶部的名称进行的
- job-template:
name: '{pipeline}-neutron-vpnaas-dsvm-functional{branch-designator}'
并将gate_hook.sh和post_test_hook.sh的路径从neutron/neutron/更改为neutron-vpnaas/neutron_vpnaas/。由于VPN仓库只有master分支,而没有不同路径的钩子的旧分支,因此也删除了钩子脚本的条件逻辑。整个文件如下所示(如果您无法访问Neutron YAML文件):
- job-template:
name: '{pipeline}-neutron-vpnaas-dsvm-functional{branch-designator}'
node: '{node}'
wrappers:
- build-timeout:
timeout: 125
- timestamps
builders:
- link-logs
- net-info
- devstack-checkout
- shell: |
#!/bin/bash -xe
export PYTHONUNBUFFERED=true
export DEVSTACK_GATE_UNSTACK=1
export DEVSTACK_GATE_TIMEOUT=120
export DEVSTACK_GATE_TEMPEST=0
export DEVSTACK_GATE_EXERCISES=0
export DEVSTACK_GATE_NEUTRON=1
export DEVSTACK_GATE_INSTALL_TESTONLY=1
export BRANCH_OVERRIDE={branch-override}
if [ "$BRANCH_OVERRIDE" != "default" ] ; then
export OVERRIDE_ZUUL_BRANCH=$BRANCH_OVERRIDE
fi
function gate_hook {
bash -xe $BASE/new/neutron-vpnaas/neutron_vpnaas/tests/contrib/gate_hook.sh dsvm-functional
}
export -f gate_hook
function post_test_hook {
bash -xe $BASE/new/neutron-vpnaas/neutron_vpnaas/tests/contrib/post_test_hook.sh dsvm-functional
}
export -f post_test_hook
cp devstack-gate/devstack-vm-gate-wrap.sh ./safe-devstack-vm-gate-wrap.sh
./safe-devstack-vm-gate-wrap.sh
publishers:
- test-results
- devstack-logs
- console-log
在openstack-infra/devstack-gate/features.yaml中进行快速检查,以确保为neutron启动了q-vpn服务。是这样,那里不需要任何东西。
要检查作业定义,可以运行 tox -e zuul,它将显示运行的作业以及任何条件(分支、排除等)。
提交以供审查(最好将提交消息的标题设置为“为<您的项目名称>创建实验性作业”,以便审阅者了解实验性质)。收到了gate-project-config-layout测试失败。日志被截断,所以不知道错误是什么,不得不询问infra人员。他们指向控制台日志以查看错误(可以访问https://jenkins06.openstack.org/job/gate-project-config-laylout/。没有定义check-neutron-vpnaas-dsvm-functional。需要在jenkins/jobs/中的project.yaml中添加。
- project:
name: neutron-vpnaas
node: 'bare-precise || bare-trusty'
tarball-site: tarballs.openstack.org
doc-publisher-site: docs.openstack.org
jobs:
- python-jobs
- openstack-publish-jobs
- '{pipeline}-neutron-vpnaas-dsvm-functional{branch-designator}':
pipeline: gate
node: 'devstack-precise || devstack-trusty'
branch-designator:
branch-override: default
- '{pipeline}-neutron-vpnaas-dsvm-functional{branch-designator}':
pipeline: check
node: 'devstack-precise || devstack-trusty'
branch-designator:
branch-override: default
确保Jenkins通过审查,并获得infra人员和neutron基础设施联络人的批准(https://wiki.openstack.org/wiki/CrossProjectLiaisons#Infra)。这在openstack-infra审查之下。
更新
如果您有多个类似的作业(就像最终添加到neutron-vpnaas的作业一样),您可以创建一个共享的模板。在此示例中,定义了neutron-vpnaas-dsvm-functional和neutron-vpnaas-dsvm-functioanl-sswan作业。修改后的模板如下所示
- job-template:
name: '{pipeline}-neutron-vpnaas-dsvm-{vpnaastest}{job-suffix}'
node: '{node}'
wrappers:
- build-timeout:
timeout: 125
- timestamps
builders:
- print-template-name:
template-name: "{template-name}"
- link-logs
- net-info
- devstack-checkout
- shell: |
#!/bin/bash -xe
export PYTHONUNBUFFERED=true
export DEVSTACK_GATE_UNSTACK=1
export DEVSTACK_GATE_TIMEOUT=120
export DEVSTACK_GATE_TEMPEST=0
export DEVSTACK_GATE_EXERCISES=0
export DEVSTACK_GATE_NEUTRON=1
export DEVSTACK_GATE_INSTALL_TESTONLY=1
export BRANCH_OVERRIDE={branch-override}
if [ "$BRANCH_OVERRIDE" != "default" ] ; then
export OVERRIDE_ZUUL_BRANCH=$BRANCH_OVERRIDE
fi
function gate_hook {
bash -xe $BASE/new/neutron-vpnaas/neutron_vpnaas/tests/contrib/gate_hook.sh dsvm-{vpnaastest}
}
export -f gate_hook
function post_test_hook {
bash -xe $BASE/new/neutron-vpnaas/neutron_vpnaas/tests/contrib/post_test_hook.sh dsvm-{vpnaastest}
}
export -f post_test_hook
cp devstack-gate/devstack-vm-gate-wrap.sh ./safe-devstack-vm-gate-wrap.sh
./safe-devstack-vm-gate-wrap.sh
publishers:
- test-results
- devstack-logs
- console-log
如您所见,vpnaastest已添加到模板名称中,并作为参数传递到钩子脚本中。钩子脚本将获得dsvm-functional或dsvm-functional-sswan,并可以根据该参数为这两个作业执行操作。
除了这些更改(以及将作业添加到实验队列),还需要对jenkins/jobs/projects.yaml进行以下更改
- project:
name: neutron-vpnaas
node: bare-trusty
tarball-site: tarballs.openstack.org
doc-publisher-site: docs.openstack.org
jobs:
- python-jobs
- translation-jobs
- python-constraints-jobs
- python-kilo-bitrot-jobs
- python-liberty-bitrot-jobs
- openstack-publish-jobs
- openstack-releasenotes-jobs
- '{pipeline}-neutron-vpnaas-dsvm-{vpnaastest}{job-suffix}':
pipeline: gate
node: devstack-trusty
vpnaastest: functional
job-suffix:
branch-override: default
- '{pipeline}-neutron-vpnaas-dsvm-{vpnaastest}{job-suffix}':
pipeline: gate
node: devstack-trusty
vpnaastest: functional-sswan
job-suffix:
branch-override: default
这定义了模板中每个作业使用的vpnaastest参数。
在本地主机上快速测试(可选)
在neutron-vpnaas视图中,确保已设置tox开发环境(例如“tox -r -e py27 —notest”)。然后,可以在/etc/neutron/rootwrap.d/中添加一个functional.filter,权限为644,内容如下
# neutron-rootwrap command filters to support functional testing. It # is NOT intended to be used outside of a test environment. # # This file should be owned by (and only-writeable by) the root user [Filters] # '$BASE_PATH' is intended to be replaced with the expected tox path # (e.g. /opt/stack/new/neutron/.tox/dsvm-functional) by the neutron # functional jenkins job. This ensures that tests can kill the # processes that they launch with their containing tox environment's # python. kill_tox_python: KillFilter, root, /opt/stack/neutron-vpnaas/.tox/dsvm-functional/bin/python, -9 # enable ping from namespace ping_filter: CommandFilter, ping, root # enable curl from namespace curl_filter: CommandFilter, curl, root
在添加了功能测试的仓库上运行‘tox -e dsvm-functional’。这有效,但是收到一个警告,关于找到了测试命令,但未安装在testenv中。
当project-config更改用于审查时,会对更改运行多个测试,并且应检查Jenkins结果是否有任何失败。
添加钩子并测试
这里最简单的方法是,将文件从neutron/neutron/tests/contrib复制到仓库(neutron-vpnaas/neutron_vpnaas/tests/contrib),并进行调整(是的,剪切和粘贴:)。不应使用Neutron的devstack-vm-gate.sh和functions.sh。gate_hook.sh应在openstack-infra/devstack-gate/项目区域中运行devstack-vm-gate.sh。
对于neutron-vpnaas仓库,对文件进行了以下更改(注意:Neutron和VPN仓库都已简化,并显示了更新的VPN代码)
- 在README中指示neutron-vpnaas仓库
- 在gate-hook.sh中设置项目名称为neutron-vpnaas
- 以相同的方式在gate_hook.sh和post_test_hook.sh中处理dsvm-functional和dsvm-functional-sswan作业。
- 在gate_hook.sh中添加NEUTRON_VPN_PATH,以便可以指向Neutron和VPN仓库区域。
- 引用configure_for_vpn_func_testing.sh脚本,该脚本反过来使用Neutron的configure_for_func_testing.sh脚本。
- 在post_test_hook.sh中使用NEUTRON_VPN_PATH设置文件所有权。
这是gate_hook.sh(有关最新信息,请参阅仓库)
#!/usr/bin/env bash
set -ex
VENV=${1:-"dsvm-functional"}
case $VENV in
dsvm-functional | dsvm-functional-sswan)
# The following need to be set before sourcing
# configure_for_func_testing.
GATE_DEST=$BASE/new
GATE_STACK_USER=stack
NEUTRON_PATH=$GATE_DEST/neutron
PROJECT_NAME=neutron-vpnaas
NEUTRON_VPN_PATH=$GATE_DEST/$PROJECT_NAME
DEVSTACK_PATH=$GATE_DEST/devstack
IS_GATE=True
source $NEUTRON_VPN_PATH/tools/configure_for_vpn_func_testing.sh
# Make the workspace owned by the stack user
sudo chown -R $STACK_USER:$STACK_USER $BASE
configure_host_for_vpn_func_testing
;;
api) $BASE/new/devstack-gate/devstack-vm-gate.sh ;;
esac
这是VPN的tools/configure_for_vpn_func_testing.sh
#!/usr/bin/env bash # 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 # # https://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. set -e IS_GATE=${IS_GATE:-False} PROJECT_NAME=${PROJECT_NAME:-neutron-vpnaas} REPO_BASE=${GATE_DEST:-$(cd $(dirname "$BASH_SOURCE")/../.. && pwd)} source $REPO_BASE/neutron/tools/configure_for_func_testing.sh function _install_vpn_package { if [ "$VENV" == "dsvm-functional-sswan" ] then IPSEC_PACKAGE=strongswan else IPSEC_PACKAGE=openswan fi echo_summary "Installing $IPSEC_PACKAGE" neutron_vpn_install_agent_packages } function _configure_vpn_ini_file { echo_summary "Configuring VPN ini file" local temp_ini=$(mktemp) cp $REPO_BASE/$PROJECT_NAME/etc/vpn_agent.ini $temp_ini if [ "$IPSEC_PACKAGE" == "strongswan" ]; then iniset_multiline $temp_ini vpnagent vpn_device_driver neutron_vpnaas.services.vpn.device_drivers.strongswan_ipsec.StrongSwanDriver if is_fedora; then iniset $temp_ini strongswan default_config_area /usr/share/strongswan/templates/config/strongswan.d fi else iniset_multiline $temp_ini vpnagent vpn_device_driver neutron_vpnaas.services.vpn.device_drivers.ipsec.OpenSwanDriver fi sudo install -d -o $STACK_USER /etc/neutron/ sudo mv $temp_ini $Q_VPN_CONF_FILE } function configure_host_for_vpn_func_testing { echo_summary "Configuring for VPN functional testing" if [ "$IS_GATE" == "True" ]; then configure_host_for_func_testing fi _install_vpn_package _configure_vpn_ini_file } if [ "$IS_GATE" != "True" ]; then configure_host_for_vpn_func_testing fi
它基本上为VPN执行额外的设置,然后执行Neutron的configure_host_for_func_testing()方法。
对于post_test_hook.sh脚本,VPN将Neutron脚本更改为如下所示
#!/usr/bin/env bash
set -xe
NEUTRON_VPNAAS_DIR="$BASE/new/neutron-vpnaas"
TEMPEST_DIR="$BASE/new/tempest"
SCRIPTS_DIR="/usr/local/jenkins/slave_scripts"
VENV=${1:-"dsvm-functional"}
function generate_testr_results {
# Give job user rights to access tox logs
sudo -H -u $owner chmod o+rw .
sudo -H -u $owner chmod o+rw -R .testrepository
if [ -f ".testrepository/0" ] ; then
.tox/$VENV/bin/subunit-1to2 < .testrepository/0 > ./testrepository.subunit
.tox/$VENV/bin/python $SCRIPTS_DIR/subunit2html.py ./testrepository.subunit testr_results.html
gzip -9 ./testrepository.subunit
gzip -9 ./testr_results.html
sudo mv ./*.gz /opt/stack/logs/
fi
}
case $VENV in
dsvm-functional | dsvm-functional-sswan)
owner=stack
sudo_env=
;;
api)
owner=tempest
# Configure the api tests to use the tempest.conf set by devstack.
sudo_env="TEMPEST_CONFIG_DIR=$TEMPEST_DIR/etc"
;;
esac
# Set owner permissions according to job's requirements.
cd $NEUTRON_VPNAAS_DIR
sudo chown -R $owner:stack $NEUTRON_VPNAAS_DIR
# Run tests
echo "Running neutron $VENV test suite"
set +e
sudo -H -u $owner $sudo_env tox -e $VENV
testr_exit_code=$?
set -e
# Collect and parse results
generate_testr_results
exit $testr_exit_code
除了钩子支持之外,在tests/functional中创建一个虚拟功能测试。提交以供审查,并从Gerrit中输入带有“check experimental”的评论,以从实验性管道运行功能测试。
移动到检查队列
一旦实验队列运行成功,并且合并了钩子提交,可以将check-neutron-vpnaas-dsvm-functional作业移动到检查队列(仍然是非投票的)。现在它将在所有提交上运行。
这很简单,只需将zuul/layout.yaml中的experimental条目更改为check即可
diff --git a/zuul/layout.yaml b/zuul/layout.yaml
index d587a43..684c035 100755
--- a/zuul/layout.yaml
+++ b/zuul/layout.yaml
@@ -1350,7 +1350,7 @@ projects:
- name: merge-check
- name: python-jobs
- name: openstack-server-release-jobs
- experimental:
+ check:
- check-neutron-vpnaas-dsvm-functional
- name: openstack/nova
现在,该测试将针对仓库的每个补丁进行审查,但测试将不进行投票。再次确保neutron基础设施联络人审查提交(Infra将保留+A,直到联络人审查)。
添加到门和检查队列,并进行投票
一旦一切看起来都很好,就可以使check-neutron-vpnaas-dsvm-functional作业进行投票,并在门管道中添加gate-neutron-vpnaas-dsvm-functional作业。
为此,再次修改zulu/layout.yaml以删除使检查非投票的行,并为项目添加gate条目。
diff --git a/zuul/layout.yaml b/zuul/layout.yaml
index d8ca382..578dd32 100755
--- a/zuul/layout.yaml
+++ b/zuul/layout.yaml
@@ -666,8 +666,6 @@ jobs:
branch: ^(?!stable/icehouse).*$
- name: gate-designate-dsvm-bind9
branch: ^(?!stable/(?:icehouse|juno)).*$
- - name: check-neutron-vpnaas-dsvm-functional
- voting: false
- name: ^(gate|check)-tempest-dsvm-networking-odl
branch: ^(?!stable)
voting: false
@@ -1431,6 +1429,7 @@ projects:
- check-neutron-vpnaas-dsvm-functional
gate:
- gate-neutron-vpnaas-pylint
+ - gate-neutron-vpnaas-dsvm-functional
- name: openstack/nova
template:
与之前一样,获得neutron联络人的审查,以便infra可以+A审查。
其他事项
在创建作业(功能和非功能)时,还有一些其他事项需要考虑。本节将重点介绍它们。
提高性能
可以提高性能的一件事是,根据更改集跳过运行作业。一个常见的例子是,当更改仅为文档文件时,跳过运行某些作业。例如(zuul/layout.yaml)
# Skip non-doc jobs for doc-only neutron-vpnaas changes. The dsvm
# tests area already skipped by another check.
- name: ^.*neutron-vpnaas-python(27|34)(-constraints)?$
skip-if:
- project: ^openstack/neutron-vpnaas$
all-files-match-any:
- ^.*\.rst$
- ^doc/.*$
- ^releasenotes/.*$
如果更改仅为.rst文件或doc或releasenotes区域中的文件,这将跳过python27和python34约束和非约束作业。可以通过运行tox -e zuul并检查输出来确认此过滤器。
旧版本
在添加新作业时,您可能希望从旧版本中排除运行它们,因为作业可能不受支持,可能没有钩子支持,或者可能没有在tox.ini中实现的targets。要从发布中排除作业,可以添加以下内容(zuul/layout.yaml)
# Don't run python34 on Kilo
- name: ^gate-neutron-vpnaas-python34$
branch: ^(?!stable/kilo).*$
同样,如果您用另一个作业替换现有作业,则可能不想用当前版本运行旧作业,因此可以指定它仅与特定版本一起运行,如下所示(zuul/layout.yaml)
# Run the non-constraints coverage on Kilo
- name: neutron-vpnaas-coverage
branch: ^(?:stable/kilo).*$
您可以指定多个版本。例如,要仅在不是Kilo和不是Liberty版本时才运行作业,您将指定
branch: ^(?!stable/(?:kilo|liberty)).*$
使用作业模板
有预定义的作业模板可以应用于项目。这将定义将在check、gate和/或post队列中运行的多个作业。这是一个常见的模板(zuul/layout.yaml)
project-templates:
- name: python-jobs
check:
- 'gate-{name}-pep8'
- 'gate-{name}-docs'
- 'gate-{name}-python27'
gate:
- 'gate-{name}-docs'
- 'gate-{name}-pep8'
- 'gate-{name}-python27'
post:
- '{name}-branch-tarball'
这定义了check和gate队列的pep8、docs和python27作业,以及post队列的tarball。name将在使用时替换为项目名称。例如(zuul/layout.yaml)
projects:
....
- name: openstack/neutron-vpnaas
template:
...
- name: python-jobs
- name: python3-jobs
对于neutron-vpnaas项目,正在使用该模板。这意味着对于check队列,将调用gate-neutron-vpnaas-pep8、gate-neutron-vpnaas-docs和gate-neutron-vpnaas-python27作业。对模板中定义的其他队列进行类似的替换。该模板将减小项目作业定义的大小,并为每个作业引入一致性。仅举例说明,这是用于python27作业的模板(jenkins/jobs/python-jobs.yaml)
- job-template:
name: 'gate-{name}-python27'
wrappers:
- build-timeout:
timeout: 50
- timestamps
builders:
- print-template-name:
template-name: "{template-name}"
- revoke-sudo
- gerrit-git-prep
- python27
- assert-no-extra-files
publishers:
- test-results
- console-log
- zuul-swift-test-results-with-console
node: '{node}'