git review -v
-Follow the link to gerrit https://gerrit.opnfv.org/gerrit/51 in a few moments
+Follow the link given in the stdoutput to gerrit eg: https://gerrit.opnfv.org/gerrit/"Your_Change_ID"
the verify job will have completed and you will see Verified +1 jenkins-ci in
the gerrit ui.
status, use **recheck-experimental** in commit message to trigger both
verify and experimental jobs.
-You can add below persons as reviewers to your patch in order to get it
+You can look in the releng/INFO file for a list of current committers to add as reviewers to your patch in order to get it
reviewed and submitted.
-* fatih.degirmenci@ericsson.com
-* agardner@linuxfoundation.org
-* trozet@redhat.com
-* morgan.richomme@orange.com
-* vlaza@cloudbasesolutions.com
-* matthew.lijun@huawei.com
-* meimei@huawei.com
-* jose.lausuch@ericsson.com
-* koffirodrigue@gmail.com
-* r-mibu@cq.jp.nec.com
-* tbramwell@linuxfoundation.org
-
Or Add the group releng-contributors
-Or just email a request for submission to opnfv-helpdesk@rt.linuxfoundation.org
+Or just email a request for review to helpdesk@opnfv.org
The Current merge and verify jobs for jenkins job builder can be found
in `releng-jobs.yaml`_.
DEPLOY_SCENARIO={scenario}
same-node: true
block: true
- - trigger-builds:
- - project: 'functest-{installer}-{pod}-arm-daily-{stream}'
- current-parameters: false
- predefined-parameters:
- DEPLOY_SCENARIO={scenario}
- block: true
- same-node: true
- block-thresholds:
- build-step-failure-threshold: 'never'
- failure-threshold: 'never'
- unstable-threshold: 'FAILURE'
- - trigger-builds:
- - project: 'yardstick-{installer}-{pod}-daily-{stream}'
- current-parameters: false
- predefined-parameters:
- DEPLOY_SCENARIO={scenario}
- block: true
- same-node: true
- block-thresholds:
- build-step-failure-threshold: 'never'
- failure-threshold: 'never'
- unstable-threshold: 'FAILURE'
+ - conditional-step:
+ condition-kind: not
+ condition-operand:
+ condition-kind: regex-match
+ regex: 'danube'
+ label: '{stream}'
+ steps:
+ - trigger-builds:
+ - project: 'functest-{installer}-{pod}-arm-daily-{stream}'
+ current-parameters: false
+ predefined-parameters:
+ DEPLOY_SCENARIO={scenario}
+ block: true
+ same-node: true
+ block-thresholds:
+ build-step-failure-threshold: 'never'
+ failure-threshold: 'never'
+ unstable-threshold: 'FAILURE'
+ - conditional-step:
+ condition-kind: not
+ condition-operand:
+ condition-kind: regex-match
+ regex: 'danube'
+ label: '{stream}'
+ steps:
+ - trigger-builds:
+ - project: 'yardstick-{installer}-{pod}-daily-{stream}'
+ current-parameters: false
+ predefined-parameters:
+ DEPLOY_SCENARIO={scenario}
+ block: true
+ same-node: true
+ block-thresholds:
+ build-step-failure-threshold: 'never'
+ failure-threshold: 'never'
+ unstable-threshold: 'FAILURE'
# 1.dovetail only master, based on D release
# 2.here the stream means the SUT stream,
# dovetail stream is defined in its own job
# only to debug the dovetail tool bugs with arm pods
# 5.only run against scenario os-(nosdn|odl)-(nofeature-bgpvpn)-ha
- conditional-step:
- condition-kind: regex-match
- regex: os-(nosdn|odl)-(nofeature|bgpvpn)-ha
- label: '{scenario}'
+ condition-kind: and
+ condition-operands:
+ - condition-kind: regex-match
+ regex: os-(nosdn|odl)-(nofeature|bgpvpn)-ha
+ label: '{scenario}'
+ - condition-kind: regex-match
+ regex: 'danube'
+ label: '{stream}'
steps:
- trigger-builds:
- project: 'dovetail-{installer}-{pod}-proposed_tests-master'
failure-threshold: 'never'
unstable-threshold: 'FAILURE'
# Armband uses Fuel's log collection project job, no need to duplicate
- - trigger-builds:
- - project: 'fuel-collect-logs-{deploy-type}-daily-{stream}'
- current-parameters: false
- block: true
- same-node: true
- block-thresholds:
- build-step-failure-threshold: 'never'
- failure-threshold: 'never'
- unstable-threshold: 'FAILURE'
+ - conditional-step:
+ condition-kind: not
+ condition-operand:
+ condition-kind: regex-match
+ regex: 'danube'
+ label: '{stream}'
+ steps:
+ - trigger-builds:
+ - project: 'fuel-collect-logs-{deploy-type}-daily-{stream}'
+ current-parameters: false
+ predefined-parameters:
+ DEPLOY_SCENARIO={scenario}
+ block: true
+ same-node: true
+ block-thresholds:
+ build-step-failure-threshold: 'never'
+ failure-threshold: 'never'
+ unstable-threshold: 'FAILURE'
- job-template:
name: '{installer}-deploy-{pod}-daily-{stream}'
use-build-blocker: true
blocking-jobs:
- 'fuel-os-.*?-virtual-daily-.*'
+ - 'armband-verify-.*'
block-level: 'NODE'
scm:
# Preparing OpenStack RC and Cacert files
echo "BOTTLENECKS INFO: fetching os credentials from $INSTALLER_TYPE"
if [[ $INSTALLER_TYPE == 'compass' ]]; then
- if [[ ${BRANCH} == 'master' ]]; then
- ${RELENG_REPO}/utils/fetch_os_creds.sh -d ${OPENRC} -i ${INSTALLER_TYPE} -a ${INSTALLER_IP} -o ${OS_CACERT} >${redirect}
- if [[ -f ${OS_CACERT} ]]; then
- echo "BOTTLENECKS INFO: successfully fetching os_cacert for openstack: ${OS_CACERT}"
- else
- echo "BOTTLENECKS ERROR: couldn't find os_cacert file: ${OS_CACERT}, please check if the it's been properly provided."
- exit 1
- fi
+ ${RELENG_REPO}/utils/fetch_os_creds.sh -d ${OPENRC} -i ${INSTALLER_TYPE} -a ${INSTALLER_IP} -o ${OS_CACERT} >${redirect}
+ if [[ -f ${OS_CACERT} ]]; then
+ echo "BOTTLENECKS INFO: successfully fetching os_cacert for openstack: ${OS_CACERT}"
else
- ${RELENG_REPO}/utils/fetch_os_creds.sh -d ${OPENRC} -i ${INSTALLER_TYPE} -a ${INSTALLER_IP} >${redirect}
+ echo "BOTTLENECKS ERROR: couldn't find os_cacert file: ${OS_CACERT}, please check if the it's been properly provided."
+ exit 1
fi
fi
if [[ -f ${OPENRC} ]]; then
echo "BOTTLENECKS INFO: openstack credentials path is ${OPENRC}"
- if [[ $INSTALLER_TYPE == 'compass' && ${BRANCH} == 'master' ]]; then
+ if [[ $INSTALLER_TYPE == 'compass' ]]; then
echo "BOTTLENECKS INFO: writing ${OS_CACERT} to ${OPENRC}"
echo "export OS_CACERT=${OS_CACERT}" >> ${OPENRC}
fi
- trigger:
name: 'compass-k8-nosdn-nofeature-ha-virtual-master-trigger'
triggers:
- - timed: '0 12 * * *'
+ - timed: '5 2 * * *'
- trigger:
name: 'compass-os-odl-sfc-ha-virtual-master-trigger'
triggers:
- trigger:
name: 'compass-k8-nosdn-nofeature-ha-virtual-euphrates-trigger'
triggers:
- - timed: '0 13 * * *'
+ - timed: '5 1 * * *'
# -------------------
# noha-virtual-euphrates
- trigger:
name: 'compass-os-nosdn-nofeature-ha-baremetal-weekly-danube-trigger'
triggers:
- - timed: 'H H * * 0'
+ - timed: '' # 'H H * * 0'
- trigger:
name: 'dovetail-weekly-trigger'
triggers:
- - timed: 'H H * * 0'
+ - timed: '' # 'H H * * 0'
jobs:
- 'container4nfv-verify-{stream}'
+ - 'container4nfv-daily-{stream}'
stream:
- master:
- project-parameter:
project: '{project}'
branch: '{branch}'
+ # yamllint disable rule:line-length
+ - string:
+ name: GIT_BASE
+ default: https://gerrit.opnfv.org/gerrit/$PROJECT
+ description: "Used for overriding the GIT URL coming from Global Jenkins configuration in case if the stuff is done on none-LF HW."
+ # yamllint enable rule:line-length
- 'opnfv-build-ubuntu-defaults'
scm:
builders:
- shell: |
- echo "Nothing to verify!"
+ cd $WORKSPACE/ci
+ ./build.sh
+
+
+- job-template:
+ name: 'container4nfv-daily-{stream}'
+
+ project-type: freestyle
+
+ disabled: '{obj:disabled}'
+
+ concurrent: false
+
+ properties:
+ - logrotate-default
+
+ parameters:
+ - project-parameter:
+ project: '{project}'
+ branch: '{branch}'
+ # yamllint disable rule:line-length
+ - string:
+ name: GIT_BASE
+ default: https://gerrit.opnfv.org/gerrit/$PROJECT
+ description: "Used for overriding the GIT URL coming from Global Jenkins configuration in case if the stuff is done on none-LF HW."
+ # yamllint enable rule:line-length
+ - node:
+ name: SLAVE_NAME
+ description: 'Slave name on Jenkins'
+ allowed-slaves:
+ - huawei-virtual6
+ default-slaves:
+ - huawei-virtual6
+
+ scm:
+ - git-scm
+
+ triggers:
+ - timed: '@midnight'
+
+ builders:
+ - shell:
+ cd $WORKSPACE/ci
+ ./deploy.sh
build-step-failure-threshold: 'never'
failure-threshold: 'never'
unstable-threshold: 'FAILURE'
+ - conditional-step:
+ condition-kind: and
+ condition-operands:
+ - condition-kind: regex-match
+ regex: 'baremetal'
+ label: '{pod}'
+ - condition-kind: regex-match
+ regex: 'master'
+ label: '{stream}'
+ steps:
+ - trigger-builds:
+ - project: 'yardstick-daisy-{pod}-daily-{stream}'
+ current-parameters: false
+ predefined-parameters:
+ DEPLOY_SCENARIO={scenario}
+ block: true
+ same-node: true
+ block-thresholds:
+ build-step-failure-threshold: 'never'
+ failure-threshold: 'never'
+ unstable-threshold: 'FAILURE'
- job-template:
name: '{project}-deploy-{pod}-daily-{stream}'
- trigger:
name: 'daisy-os-nosdn-nofeature-ha-baremetal-daily-master-trigger'
triggers:
- - timed: '0 16 * * *'
+ - timed: '0 18 * * *'
# Basic NOHA Scenarios
- trigger:
name: 'daisy-os-nosdn-nofeature-noha-baremetal-daily-master-trigger'
branch: 'stable/{stream}'
dovetail-branch: master
gs-pathname: '/{stream}'
- docker-tag: 'cvp.0.7.0'
+ docker-tag: 'cvp.0.8.0'
# ----------------------------------
# POD, PLATFORM, AND BRANCH MAPPING
DEPLOY_SCENARIO={scenario}
same-node: true
block: true
- - trigger-builds:
- - project: 'functest-fuel-{pod}-daily-{stream}'
- current-parameters: false
- predefined-parameters:
- DEPLOY_SCENARIO={scenario}
- same-node: true
- block: true
- block-thresholds:
- build-step-failure-threshold: 'never'
- failure-threshold: 'never'
- unstable-threshold: 'FAILURE'
- - trigger-builds:
- - project: 'yardstick-fuel-{pod}-daily-{stream}'
- current-parameters: false
- predefined-parameters:
- DEPLOY_SCENARIO={scenario}
- block: true
- same-node: true
- block-thresholds:
- build-step-failure-threshold: 'never'
- failure-threshold: 'never'
- unstable-threshold: 'FAILURE'
+ - conditional-step:
+ condition-kind: not
+ condition-operand:
+ condition-kind: regex-match
+ regex: 'danube'
+ label: '{stream}'
+ steps:
+ - trigger-builds:
+ - project: 'functest-fuel-{pod}-daily-{stream}'
+ current-parameters: false
+ predefined-parameters:
+ DEPLOY_SCENARIO={scenario}
+ same-node: true
+ block: true
+ block-thresholds:
+ build-step-failure-threshold: 'never'
+ failure-threshold: 'never'
+ unstable-threshold: 'FAILURE'
+ - conditional-step:
+ condition-kind: not
+ condition-operand:
+ condition-kind: regex-match
+ regex: 'danube'
+ label: '{stream}'
+ steps:
+ - trigger-builds:
+ - project: 'yardstick-fuel-{pod}-daily-{stream}'
+ current-parameters: false
+ predefined-parameters:
+ DEPLOY_SCENARIO={scenario}
+ block: true
+ same-node: true
+ block-thresholds:
+ build-step-failure-threshold: 'never'
+ failure-threshold: 'never'
+ unstable-threshold: 'FAILURE'
# 1.dovetail only has master, based on D release
# 2.here the stream means the SUT stream, dovetail stream is defined in its own job
# 3.only debug testsuite here(refstack, ha, ipv6, bgpvpn)
# 5.only run against scenario os-odl-bgpvpn-ha(regex used here, can extend to more scenarios future)
# 6.ZTE pod1, os-nosdn-nofeature-ha and os-odl-bgpvpn-ha, run against danube
- conditional-step:
- condition-kind: regex-match
- regex: os-(nosdn-nofeature|odl_l2-bgpvpn)-ha
- label: '{scenario}'
+ condition-kind: and
+ condition-operands:
+ - condition-kind: regex-match
+ regex: os-(nosdn-nofeature|odl_l2-bgpvpn)-ha
+ label: '{scenario}'
+ - condition-kind: regex-match
+ regex: 'danube'
+ label: '{stream}'
steps:
- trigger-builds:
- project: 'dovetail-fuel-{pod}-proposed_tests-master'
use-build-blocker: true
blocking-jobs:
- 'fuel-os-.*?-virtual-daily-.*'
+ - 'fuel-verify-.*'
block-level: 'NODE'
scm:
FUNCTEST_IMAGE=opnfv/functest-${tier}:${DOCKER_TAG}
echo "Functest: Pulling Functest Docker image ${FUNCTEST_IMAGE} ..."
docker pull ${FUNCTEST_IMAGE}>/dev/null
- cmd="docker run --privileged=true ${envs} ${volumes} ${FUNCTEST_IMAGE} /bin/bash -c '${cmd_opt}'"
+ cmd="docker run --privileged=true ${envs} ${volumes} ${TESTCASE_OPTIONS} ${FUNCTEST_IMAGE} /bin/bash -c '${cmd_opt}'"
echo "Running Functest tier '${tier}'. CMD: ${cmd}"
eval ${cmd}
ret_value=$?
run_test() {
test_name=$1
- cmd_opt="prepare_env start && run_tests -r -t ${test_name}"
+ cmd_opt="prepare_env start && run_tests -t ${test_name}"
[[ $BUILD_TAG =~ "suite" ]] && cmd_opt="prepare_env start && run_tests -t ${test_name}"
ret_val_file="${HOME}/opnfv/functest/results/${BRANCH##*/}/return_value"
echo 0 > ${ret_val_file}
esac
echo "Functest: Pulling Functest Docker image ${FUNCTEST_IMAGE} ..."
docker pull ${FUNCTEST_IMAGE}>/dev/null
- cmd="docker run --privileged=true ${envs} ${volumes} ${FUNCTEST_IMAGE} /bin/bash -c '${cmd_opt}'"
+ cmd="docker run --privileged=true ${envs} ${volumes} ${TESTCASE_OPTIONS} ${FUNCTEST_IMAGE} /bin/bash -c '${cmd_opt}'"
echo "Running Functest test case '${test_name}'. CMD: ${cmd}"
eval ${cmd}
ret_value=$?
# <<: *master
# -------------------------------
- alpine-pod:
- - ericsson-virtual-pod1bl01:
- slave-label: '{alpine-pod}'
- installer: fuel
- <<: *master
- - huawei-virtual5:
- slave-label: '{alpine-pod}'
- installer: compass
- <<: *master
-
testsuite:
- 'suite':
job-timeout: 60
jobs:
- 'functest-{installer}-{pod}-{testsuite}-{stream}'
- - 'functest-alpine-{installer}-{alpine-pod}-{testsuite}-{stream}'
################################
# job template
description: "Built on $NODE_NAME"
- 'functest-{testsuite}-builder'
-- job-template:
- name: 'functest-alpine-{installer}-{alpine-pod}-{testsuite}-{stream}'
-
- concurrent: true
-
- properties:
- - logrotate-default
- - throttle:
- enabled: true
- max-per-node: 1
- option: 'project'
-
- wrappers:
- - build-name:
- name: '$BUILD_NUMBER Suite: $FUNCTEST_SUITE_NAME Scenario: $DEPLOY_SCENARIO'
- - timeout:
- timeout: '{job-timeout}'
- abort: true
-
- parameters:
- - project-parameter:
- project: '{project}'
- branch: '{branch}'
- - '{installer}-defaults'
- - '{slave-label}-defaults'
- - 'functest-{testsuite}-parameter'
- - string:
- name: DEPLOY_SCENARIO
- default: 'os-nosdn-nofeature-noha'
- - functest-parameter:
- gs-pathname: '{gs-pathname}'
-
- scm:
- - git-scm
-
- builders:
- - description-setter:
- description: "Built on $NODE_NAME"
- - 'functest-alpine-daily-builder'
########################
# parameter macros
name: functest-arm-daily-builder
builders:
- 'functest-cleanup'
- - 'set-functest-env'
- 'functest-arm-daily'
- 'functest-store-results'
- 'functest-exit'
name: functest-suite-builder
builders:
- 'functest-cleanup'
- - 'set-functest-env-alpine'
- - 'functest-suite'
- - 'functest-store-results'
- - 'functest-exit'
-
-- builder:
- name: functest-alpine-daily-builder
- builders:
- - 'functest-cleanup'
- - 'set-functest-env-alpine'
- 'functest-daily'
- 'functest-store-results'
- 'functest-exit'
# yamllint enable rule:indentation
- builder:
name: functest-arm-daily
- builders:
- - shell:
- !include-raw: ./functest-loop.sh
-
-- builder:
- name: functest-suite
- builders:
- # yamllint disable rule:indentation
- - shell:
- !include-raw:
- - ./functest-alpine.sh
-
-# yamllint enable rule:indentation
-- builder:
- name: set-functest-env
builders:
# yamllint disable rule:indentation
- shell:
- ./functest-env-presetup.sh
- ../../utils/fetch_os_creds.sh
- ./set-functest-env.sh
-
-# yamllint enable rule:indentation
-- builder:
- name: set-functest-env-alpine
- builders:
- # yamllint disable rule:indentation
- - shell:
- !include-raw:
- - ./functest-env-presetup.sh
- - ../../utils/fetch_os_creds.sh
+ - ./functest-loop.sh
# yamllint enable rule:indentation
- builder:
name: GS_URL
default: '$GS_BASE{gs-pathname}'
description: "URL to Google Storage."
+ - string:
+ name: CI_DEBUG
+ default: 'false'
+ description: "Show debug output information"
- parameter:
name: 'joid-defaults'
name: BRIDGE
default: 'br7'
description: 'pxe bridge for booting of Daisy master'
+ - string:
+ name: EXTERNAL_NETWORK
+ default: 'admin_external'
+ description: 'external network for test'
- parameter:
name: 'infra-defaults'
- compare-type: 'ANT'
pattern: '{files}'
+- trigger:
+ name: gerrit-trigger-tag-created
+ triggers:
+ - gerrit:
+ server-name: 'gerrit.opnfv.org'
+ trigger-on:
+ - ref-updated
+ projects:
+ - project-compare-type: 'ANT'
+ project-pattern: '{project}'
+ branches:
+ - branch-compare-type: 'ANT'
+ branch-pattern: 'refs/tags/**'
+
- trigger:
name: 'experimental'
triggers:
#!/bin/bash
sudo chown -R $USER:$USER $WORKSPACE || exit 1
-- builder:
- name: build-html-and-pdf-docs-output
- builders:
- - shell: |
- #!/bin/bash
- set -o errexit
- set -o xtrace
- export PATH=$PATH:/usr/local/bin/
- git clone ssh://gerrit.opnfv.org:29418/opnfvdocs docs_build/_opnfvdocs
- GERRIT_COMMENT=gerrit_comment.txt ./docs_build/_opnfvdocs/scripts/docs-build.sh
-
- builder:
name: upload-under-review-docs-to-opnfv-artifacts
builders:
export PATH=$PATH:/usr/local/bin/
[[ $GERRIT_CHANGE_NUMBER =~ .+ ]]
- [[ -d docs_output ]] || exit 0
+ [[ -d docs/_build/ ]] || exit 0
echo
echo "###########################"
local_path="upload/$GERRIT_CHANGE_NUMBER"
mkdir -p upload
- mv docs_output "$local_path"
+ mv docs/_build/html/ "$local_path"
gsutil -m cp -r "$local_path" "gs://$gs_base"
gsutil -m setmeta \
find "$local_path" | grep -e 'index.html$' -e 'pdf$' | \
sed -e "s|^$local_path| http://$gs_path|" >> gerrit_comment.txt
-- builder:
- name: upload-generated-docs-to-opnfv-artifacts
- builders:
- - shell: |
- #!/bin/bash
- set -o errexit
- set -o pipefail
- set -o xtrace
- export PATH=$PATH:/usr/local/bin/
-
- [[ -d docs_output ]] || exit 0
-
- echo
- echo "########################"
- echo "UPLOADING GENERATED DOCS"
- echo "########################"
- echo
-
- echo "gs_path="$GS_URL/docs""
- echo "local_path="upload/docs""
-
- gs_path="$GS_URL/docs"
- local_path="upload/docs"
-
- mkdir -p upload
- mv docs_output "$local_path"
- ls "$local_path"
-
- echo "gsutil -m cp -r "$local_path"/* "gs://$gs_path""
- gsutil -m cp -r "$local_path"/* "gs://$gs_path"
-
- gsutil -m setmeta \
- -h "Content-Type:text/html" \
- -h "Cache-Control:private, max-age=0, no-transform" \
- "gs://$gs_path"/**.html > /dev/null 2>&1
-
- echo "Document link(s):" >> gerrit_comment.txt
- find "$local_path" | grep -e 'index.html$' -e 'pdf$' | \
- sed -e "s|^$local_path| http://$gs_path|" >> gerrit_comment.txt
-
# To take advantage of this macro, have your build write
# out the file 'gerrit_comment.txt' with information to post
# back to gerrit and include this macro in the list of builders.
- builder:
name: upload-review-docs
builders:
- - build-html-and-pdf-docs-output
- upload-under-review-docs-to-opnfv-artifacts
- report-build-result-to-gerrit
-- builder:
- name: upload-merged-docs
- builders:
- - build-html-and-pdf-docs-output
- - upload-generated-docs-to-opnfv-artifacts
- - report-build-result-to-gerrit
- - remove-old-docs-from-opnfv-artifacts
-
- builder:
name: check-bash-syntax
builders:
description: 'pxe bridge for booting of Daisy master'
- parameter:
- name: zte-pod4-defaults
+ name: zte-virtual5-defaults
parameters:
- node:
name: SLAVE_NAME
description: 'Slave name on Jenkins'
allowed-slaves:
- - zte-pod4
+ - zte-virtual5
default-slaves:
- - zte-pod4
+ - zte-virtual5
- string:
name: GIT_BASE
default: https://gerrit.opnfv.org/gerrit/$PROJECT
- master:
branch: '{stream}'
gs-pathname: ''
- disabled: false
+ disabled: true
- euphrates:
branch: 'stable/{stream}'
gs-pathname: '/{stream}'
- master:
branch: '{stream}'
gs-pathname: ''
+ disabled: true
- euphrates:
branch: 'stable/{stream}'
gs-pathname: '/{stream}'
+ disabled: true
- job-template:
name: 'moon-verify-{stream}'
- shell: |
#!/bin/bash
echo "launch Moon unit tests"
- nosetest $WORKSPACE/keystone-moon/keystone/tests/moon/unit
+ #nosetest $WORKSPACE/keystone-moon/keystone/tests/moon/unit
builders:
- shell: |
- echo "pass"
+ cd $WORKSPACE && tox
branch: 'master'
- danube:
branch: 'stable/{stream}'
+ - euphrates:
+ branch: 'stable/{stream}'
project: 'opnfvdocs'
rtdproject: 'opnfv'
files: 'docs/**/*.*'
builders:
+ - 'remove-old-docs-from-opnfv-artifacts'
- shell: |
if [ $GERRIT_BRANCH == "master" ]; then
RTD_BUILD_VERSION=latest
project: '**'
branch: '{branch}'
files: 'docs/**/*.*'
- - timed: 'H H * * *'
builders:
- shell: |
pip install --upgrade pip
pip freeze
pip install tox
+ sed -i s,\-b\ html,\-b\ singlehtml,g tox.ini
tox -edocs
+ - 'upload-review-docs'
jobs:
- 'opnfvdocs-verify-shellcheck-{stream}'
- 'opnfvdocs-merge-shellcheck-{stream}'
- - 'opnfvdocs-daily-{stream}'
stream:
- master:
builders:
- check-bash-syntax
-
-- job-template:
- name: 'opnfvdocs-daily-{stream}'
-
- disabled: true
-
- parameters:
- - project-parameter:
- project: '{project}'
- branch: '{branch}'
- - string:
- name: GS_URL
- default: '$GS_BASE{gs-pathname}'
- description: "Directory where the build artifact will be located upon the completion of the build."
- - string:
- name: GIT_CLONE_BASE
- default: ssh://gerrit.opnfv.org:29418
- description: "Used for overriding the GIT URL coming from parameters macro."
-
- scm:
- - git-scm
-
- triggers:
- - timed: '0 H/6 * * *'
-
- builders:
- - build-html-and-pdf-docs-output
-# - upload-generated-docs-to-opnfv-artifacts
- job-template:
name: 'ovsnfv-daily-{stream}'
- disabled: '{obj:disabled}'
+ disabled: 'true'
parameters:
- project-parameter:
- project:
name: pharos
- project: '{name}'
+ project:
+ - '{name}'
+ - '{name}-tools'
jobs:
- - 'pharos-verify-{stream}'
+ - '{project}-verify-{stream}'
stream:
- master:
disabled: false
- job-template:
- name: 'pharos-verify-{stream}'
+ name: '{project}-verify-{stream}'
disabled: '{obj:disabled}'
branch: '{branch}'
# Pin the tests on zte-pod4 with apex deployment
- apex-defaults
- - zte-pod4-defaults
+ - zte-virtual5-defaults
scm:
- git-scm-gerrit
qpi:
- compute:
installer: apex
- pod: zte-pod4
+ pod: zte-virtual5
<<: *master
- storage:
installer: apex
- pod: zte-pod4
+ pod: zte-virtual5
<<: *master
- compute:
installer: apex
- pod: zte-pod4
+ pod: zte-virtual5
<<: *euphrates
- storage:
installer: apex
- pod: zte-pod4
+ pod: zte-virtual5
<<: *euphrates
# -------------------------------
--- /dev/null
+---
+##############################################
+# job configuration for docker build and push
+##############################################
+- project:
+
+ name: functest-docker
+
+ project: functest
+
+ stream:
+ - master:
+ branch: '{stream}'
+ disabled: false
+ - euphrates:
+ branch: 'stable/{stream}'
+ disabled: false
+
+ arch_tag:
+ - 'amd64':
+ slave_label: 'opnfv-build-ubuntu'
+ - 'arm64':
+ slave_label: 'opnfv-build-ubuntu-arm'
+
+ # yamllint disable rule:key-duplicates
+ image:
+ - 'core'
+ - 'healthcheck'
+ - 'features'
+ - 'components'
+ - 'parser'
+ - 'smoke'
+ - 'vnf'
+ - 'restapi'
+
+ # settings for jobs run in multijob phases
+ build-job-settings: &build-job-settings
+ current-parameters: false
+ git-revision: true
+ node-parameters: true
+ predefined-parameters: |
+ PUSH_IMAGE=$PUSH_IMAGE
+ COMMIT_ID=$COMMIT_ID
+ RELEASE_VERSION=$RELEASE_VERSION
+ DOCKERFILE=$DOCKERFILE
+ ARCH_TAG=$ARCH_TAG
+ kill-phase-on: FAILURE
+ abort-all-jobs: false
+
+ manifest-job-settings: &manifest-job-settings
+ current-parameters: false
+ git-revision: true
+ node-parameters: true
+ predefined-parameters: |
+ RELEASE_VERSION=$RELEASE_VERSION
+ ARCH_TAG=$ARCH_TAG
+ kill-phase-on: FAILURE
+ abort-all-jobs: false
+
+ # yamllint enable rule:key-duplicates
+ jobs:
+ - "functest-docker-build-push-{arch_tag}-{stream}"
+ - "functest-{image}-build-push-{arch_tag}-{stream}"
+ - "functest-{image}-create-manifest-{arch_tag}-{stream}"
+########################
+# job templates
+########################
+- job-template:
+ name: 'functest-docker-build-push-{arch_tag}-{stream}'
+
+ project-type: multijob
+
+ disabled: '{obj:disabled}'
+
+ parameters:
+ - job-parameters:
+ project: '{project}'
+ branch: '{branch}'
+ slave_label: '{slave_label}'
+ arch_tag: '{arch_tag}'
+ - string:
+ name: ARCH_TAG
+ default: "{arch_tag}"
+ description: "If set, this value will be added to the docker image tag as a prefix"
+
+ properties:
+ - throttle:
+ max-per-node: 1
+ option: 'project'
+
+ scm:
+ - git-scm
+
+ triggers:
+ - pollscm:
+ cron: "*/30 * * * *"
+
+ builders:
+ - multijob:
+ name: 'build-base-img-create-manifest'
+ execution-type: SEQUENTIAL
+ projects:
+ - name: 'functest-core-build-push-{stream}'
+ <<: *build-job-settings
+ - name: 'functest-core-create-manifest-{stream}'
+ <<: *manifest-job-settings
+ - multijob:
+ name: 'build-child-img'
+ condition: SUCCESSFUL
+ execution-type: PARALLEL
+ projects:
+ - name: 'functest-healthcheck-build-push-{stream}'
+ <<: *build-job-settings
+ - name: 'functest-features-build-push-{stream}'
+ <<: *build-job-settings
+ - name: 'functest-components-build-push-{stream}'
+ <<: *build-job-settings
+ - name: 'functest-parser-build-push-{stream}'
+ <<: *build-job-settings
+ - name: 'functest-smoke-build-push-{stream}'
+ <<: *build-job-settings
+ - name: 'functest-vnf-build-push-{stream}'
+ <<: *build-job-settings
+ - name: 'functest-restapi-build-push-{stream}'
+ <<: *build-job-settings
+ - multijob:
+ name: 'create-img-manifest'
+ condition: SUCCESSFUL
+ execution-type: PARALLEL
+ projects:
+ - name: 'functest-healthcheck-create-manifest-{stream}'
+ <<: *manifest-job-settings
+ - name: 'functest-features-create-manifest-{stream}'
+ <<: *manifest-job-settings
+ - name: 'functest-components-create-manifest-{stream}'
+ <<: *manifest-job-settings
+ - name: 'functest-parser-create-manifest-{stream}'
+ <<: *manifest-job-settings
+ - name: 'functest-smoke-create-manifest-{stream}'
+ <<: *manifest-job-settings
+ - name: 'functest-vnf-create-manifest-{stream}'
+ <<: *manifest-job-settings
+ - name: 'functest-restapi-create-manifest-{stream}'
+ <<: *manifest-job-settings
+
+ publishers:
+ - 'functest-{arch_tag}-recipients'
+
+- job-template:
+
+ name: 'functest-{image}-build-push-{arch_tag}-{stream}'
+
+ disabled: '{obj:disabled}'
+
+ parameters:
+ - job-parameters:
+ project: '{project}'
+ branch: '{branch}'
+ slave_label: '{slave_label}'
+ arch_tag: '{arch_tag}'
+ - string:
+ name: DOCKER_REPO_NAME
+ default: "opnfv/functest-{image}"
+ description: "Dockerhub repo to be pushed to."
+ - string:
+ name: DOCKER_DIR
+ default: "docker/{image}"
+ description: "Directory containing files needed by the Dockerfile"
+
+ builders:
+ - shell:
+ !include-raw-escape: ./opnfv-docker.sh
+
+- job-template:
+
+ name: 'functest-{image}-create-manifest-{arch_tag}-{stream}'
+
+ disabled: '{obj:disabled}'
+
+ parameters:
+ - job-parameters:
+ project: '{project}'
+ branch: '{branch}'
+ slave_label: '{slave_label}'
+ arch_tag: '{arch_tag}'
+ - string:
+ name: DOCKER_REPO_NAME
+ default: "opnfv/functest-{image}"
+ description: "Dockerhub repo to be pushed to."
+ - string:
+ name: DOCKER_DIR
+ default: "docker/{image}"
+ description: "Directory containing files needed by the Dockerfile"
+
+ builders:
+ - shell:
+ !include-raw-escape: ./opnfv-manifest.sh
+
+# parameter macro
+- parameter:
+ name: job-parameters
+ parameters:
+ - project-parameter:
+ project: '{project}'
+ branch: '{branch}'
+ - label:
+ name: SLAVE_LABEL
+ default: '{slave_label}'
+ description: 'Slave label on Jenkins'
+ - string:
+ name: GIT_BASE
+ default: https://gerrit.opnfv.org/gerrit/$PROJECT
+ description: 'Git URL to use on this Jenkins Slave'
+ - string:
+ name: PUSH_IMAGE
+ default: "true"
+ description: "To enable/disable pushing the image to Dockerhub."
+ - string:
+ name: COMMIT_ID
+ default: ""
+ description: "commit id to make a snapshot docker image"
+ - string:
+ name: RELEASE_VERSION
+ default: ""
+ description: "Docker tag to be built, e.g. 5.0.0, opnfv-5.0.0, 5.0.RC1"
+ - string:
+ name: DOCKERFILE
+ default: "Dockerfile"
+ description: "Dockerfile to use for creating the image."
+ - string:
+ name: ARCH_TAG
+ default: "{arch_tag}"
+ description: "If set, this value will be added to the docker image tag as a prefix"
+ - string:
+ name: PROJECT
+ default: "{project}"
+ description: "Project name used to enable job conditions"
+
+# publisher macros
+- publisher:
+ name: 'functest-arm64-recipients'
+ publishers:
+ - email:
+ recipients: >
+ cristina.pauna@enea.com
+ alexandru.avadanii@enea.com
+ delia.popescu@enea.com
+
+- publisher:
+ name: 'functest-amd64-recipients'
+ publishers:
+ - email:
+ recipients: >
+ jalausuch@suse.com morgan.richomme@orange.com
+ cedric.ollivier@orange.com feng.xiaowei@zte.com.cn
+ juha.kosonen@nokia.com wangwulin@huawei.com
if [[ "$BRANCH" == "master" ]]; then
DOCKER_TAG="latest"
elif [[ -n "${RELEASE_VERSION-}" ]]; then
- DOCKER_TAG=${BRANCH##*/}.${RELEASE_VERSION}
- # e.g. danube.1.0, danube.2.0, danube.3.0
+ DOCKER_TAG=${RELEASE_VERSION}
+ if git checkout ${RELEASE_VERSION}; then
+ echo "Successfully checked out the git tag ${RELEASE_VERSION}"
+ else
+ echo "The tag ${RELEASE_VERSION} doesn't exist in the repository. Existing tags are:"
+ git tag
+ exit 1
+ fi
else
DOCKER_TAG="stable"
fi
- string:
name: RELEASE_VERSION
default: ""
- description: "Release version, e.g. 1.0, 2.0, 3.0"
+ description: "Docker tag to be built, e.g. 5.0.0, opnfv-5.0.0, 5.0.RC1"
- string:
name: DOCKERFILE
default: "{dockerfile}"
+++ /dev/null
----
-########################
-# Job configuration for opnfv-docs
-########################
-- project:
-
- name: opnfv-docs
-
- project: opnfv-docs
-
- jobs:
- - 'opnfv-docs-verify-{stream}'
- - 'opnfv-docs-merge-{stream}'
-
- stream:
- - master:
- branch: '{stream}'
- doc-version: ''
- gs-pathname: ''
- disabled: false
- - euphrates:
- branch: 'stable/{stream}'
- doc-version: '5.0.0'
- gs-pathname: '/{stream}/{doc-version}'
- disabled: false
-
-########################
-# job templates
-########################
-
-- job-template:
- name: 'opnfv-docs-verify-{stream}'
-
- disabled: '{obj:disabled}'
-
- parameters:
- - project-parameter:
- project: $GERRIT_PROJECT
- branch: '{branch}'
-
- scm:
- - git-scm-gerrit
-
- triggers:
- - gerrit:
- server-name: 'gerrit.opnfv.org'
- trigger-on:
- - patchset-created-event:
- exclude-drafts: 'false'
- exclude-trivial-rebase: 'false'
- exclude-no-code-change: 'false'
- - draft-published-event
- - comment-added-contains-event:
- comment-contains-value: 'recheck'
- - comment-added-contains-event:
- comment-contains-value: 'reverify'
- projects:
- - project-compare-type: 'ANT'
- project-pattern: '*'
- branches:
- - branch-compare-type: 'ANT'
- branch-pattern: '**/{branch}'
- file-paths:
- - compare-type: ANT
- pattern: docs/**
- - compare-type: ANT
- pattern: yardstick/**
-
- builders:
- - upload-review-docs
-
-- job-template:
- name: 'opnfv-docs-merge-{stream}'
-
- disabled: '{obj:disabled}'
-
- parameters:
- - project-parameter:
- project: $GERRIT_PROJECT
- branch: '{branch}'
- - string:
- name: GS_URL
- default: '$GS_BASE{gs-pathname}'
- description: "Directory where the build artifact will be located upon the completion of the build."
- - string:
- name: GERRIT_REFSPEC
- default: 'refs/heads/{branch}'
- description: "JJB configured GERRIT_REFSPEC parameter"
-
- scm:
- - git-scm
-
- triggers:
- - gerrit:
- server-name: 'gerrit.opnfv.org'
- trigger-on:
- - change-merged-event
- - comment-added-contains-event:
- comment-contains-value: 'remerge'
- - comment-added-contains-event:
- comment-contains-value: 'rebuild docs'
- projects:
- - project-compare-type: 'ANT'
- project-pattern: '*'
- branches:
- - branch-compare-type: 'ANT'
- branch-pattern: '**/{branch}'
- file-paths:
- - compare-type: ANT
- pattern: docs/**
- - compare-type: ANT
- pattern: yardstick/**
-
- builders:
- - upload-merged-docs
--- /dev/null
+#!/bin/bash
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# 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
+##############################################################################
+
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+# Starting creating manifest image for $DOCKER_REPO_NAME
+
+ARCH=(amd64 arm64)
+DOCKER_REPO_NAME=${DOCKER_REPO_NAME-}
+RELEASE_VERSION=${RELEASE_VERSION-}
+BRANCH=${BRANCH-}
+ARCH_TAG=${ARCH_TAG-}
+
+# Before script install manifest-tool:
+# cd .. && git clone https://github.com/estesp/manifest-tool
+# cd ../manifest-tool && sudo -E make && sudo -E make install
+
+if [[ "$BRANCH" == "master" ]]; then
+ DOCKER_TAG="latest"
+elif [[ "$BRANCH" == "euphrates" ]]; then
+ DOCKER_TAG="euphrates"
+elif [[ -n "${RELEASE_VERSION}" ]]; then
+ DOCKER_TAG="${RELEASE_VERSION}"
+else
+ DOCKER_TAG="stable"
+fi
+if [[ "${ARCH_TAG}" =~ "arm64" || "${ARCH_TAG}" =~ "amd64" ]]; then
+ sudo manifest-tool push from-args --platforms linux/amd64,linux/arm64 \
+ --template "${DOCKER_REPO_NAME}":"${ARCH[0]}"-"${DOCKER_TAG}" \
+ --template "${DOCKER_REPO_NAME}":"${ARCH[1]}"-"${DOCKER_TAG}" \
+ --target "${DOCKER_REPO_NAME}":"${DOCKER_TAG}"
+fi
+
branch: '{stream}'
gs-pathname: ''
disabled: false
- slave-label: 'opnfv-build-ubuntu'
- euphrates:
branch: 'stable/{stream}'
gs-pathname: '/{stream}'
disabled: false
- slave-label: 'opnfv-build-ubuntu'
- job-template:
- project-parameter:
project: '{project}'
branch: '{branch}'
- - '{slave-label}-defaults'
+ - string:
+ name: GIT_BASE
+ default: https://gerrit.opnfv.org/gerrit/$PROJECT
+ description: 'Git URL to use on this Jenkins Slave'
+ - node:
+ name: SLAVE_NAME
+ description: 'Slave name on Jenkins'
+ allowed-slaves:
+ - ericsson-build4
+ default-slaves:
+ - ericsson-build4
scm:
- git-scm-gerrit
- project-parameter:
project: '{project}'
branch: '{branch}'
- - '{slave-label}-defaults'
+ - string:
+ name: GIT_BASE
+ default: https://gerrit.opnfv.org/gerrit/$PROJECT
+ description: 'Git URL to use on this Jenkins Slave'
+ - node:
+ name: SLAVE_NAME
+ description: 'Slave name on Jenkins'
+ allowed-slaves:
+ - ericsson-build4
+ default-slaves:
+ - ericsson-build4
scm:
- git-scm
# -------------------------------
distro:
- 'xenial':
- disabled: true
+ disabled: false
dib-os-release: 'xenial'
dib-os-element: 'ubuntu-minimal'
dib-os-packages: 'vlan,vim,less,bridge-utils,language-pack-en,iputils-ping,rsyslog,curl'
extra-dib-elements: 'openssh-server'
- 'centos7':
- disabled: true
+ disabled: false
dib-os-release: '7'
dib-os-element: 'centos-minimal'
dib-os-packages: 'vim,less,bridge-utils,iputils,rsyslog,curl'
extra-dib-elements: 'openssh-server'
- - 'suse':
- disabled: true
+ - 'opensuse423':
+ disabled: false
dib-os-release: '42.3'
dib-os-element: 'opensuse-minimal'
dib-os-packages: 'vim,less,bridge-utils,iputils,rsyslog,curl'
cat > bifrost_test.sh<<EOF
cd ~/bifrost
# provision 3 VMs; xcimaster, controller, and compute
-cd $WORKSPACE/bifrost
./scripts/bifrost-provision.sh
# list the provisioned VMs
-cd $WORKSPACE/bifrost
source env-vars
ironic node-list
sudo -H -E virsh list
EOF
chmod a+x bifrost_test.sh
-./xci/scripts/vm/start-new-vm.sh $DISTRO
+# Fix up distros
+case ${DISTRO} in
+ xenial) VM_DISTRO=ubuntu ;;
+ centos7) VM_DISTRO=centos ;;
+ *suse*) VM_DISTRO=opensuse ;;
+esac
-rsync -a $WORKSPACE/bifrost ${DISTRO,,}_xci_vm:~/bifrost
+./xci/scripts/vm/start-new-vm.sh $VM_DISTRO
-ssh ${DISTRO,,}_xci_vm "cd ~/bifrost && ./bifrost_test.sh"
+rsync -a $WORKSPACE/releng-xci ${VM_DISTRO}_xci_vm:~/bifrost
+
+ssh -F $HOME/.ssh/xci-vm-config ${VM_DISTRO}_xci_vm "cd ~/bifrost && ./bifrost_test.sh"
installer: compass
auto-trigger-name: 'daily-trigger-disabled'
<<: *euphrates
+ # daisy CI PODs
+ - baremetal:
+ slave-label: zte-pod3
+ installer: daisy
+ auto-trigger-name: 'daily-trigger-disabled'
+ <<: *master
+ - virtual:
+ slave-label: daisy-virtual
+ installer: daisy
+ auto-trigger-name: 'daily-trigger-disabled'
+ <<: *master
# -------------------------------
# None-CI PODs
# -------------------------------
<<: *euphrates
- zte-pod2:
slave-label: '{pod}'
- installer: fuel
+ installer: daisy
auto-trigger-name: 'daily-trigger-disabled'
<<: *master
- zte-pod3:
slave-label: '{pod}'
- installer: fuel
+ installer: daisy
auto-trigger-name: 'daily-trigger-disabled'
<<: *master
- - zte-pod3:
- slave-label: '{pod}'
- installer: fuel
- auto-trigger-name: 'daily-trigger-disabled'
- <<: *euphrates
- orange-pod2:
slave-label: '{pod}'
installer: joid
- shell:
!include-raw: ./yardstick-daily.sh
-- builder:
- name: yardstick-vtcdaily
- builders:
- - shell:
- !include-raw: ./yardstick-vtcdaily.sh
-
- builder:
name: yardstick-fetch-os-creds
builders:
default: '-i 104.197.68.199:8086'
description: 'Arguments to use in order to choose the backend DB'
+- parameter:
+ name: 'yardstick-params-daisy-baremetal'
+ parameters:
+ - string:
+ name: YARDSTICK_DB_BACKEND
+ default: '-i 104.197.68.199:8086'
+ description: 'Arguments to use in order to choose the backend DB'
+
+- parameter:
+ name: 'yardstick-params-daisy-virtual'
+ parameters:
+ - string:
+ name: YARDSTICK_DB_BACKEND
+ default: '-i 104.197.68.199:8086'
+ description: 'Arguments to use in order to choose the backend DB'
+
- parameter:
name: 'yardstick-params-zte-pod1'
parameters:
+++ /dev/null
-#!/bin/bash
-set -e
-[[ $CI_DEBUG == true ]] && redirect="/dev/stdout" || redirect="/dev/null"
-
-cd $WORKSPACE
-./tests/ci/apexlake-verify
def ofctl_dump_flows(self, ssh_conn, br='br-int',
choose_table=None, timestamp=None):
try:
- cmd = 'ovs-ofctl -OOpenFlow13 dump-flows {0}'.format(br)
+ cmd = 'sudo ovs-ofctl -OOpenFlow13 dump-flows {0}'.format(br)
if choose_table is not None:
cmd = '{0} table={1}'.format(cmd, choose_table)
output = self.__remote_cmd(ssh_conn, cmd)
def vsctl_show(self, ssh_conn, timestamp=None):
try:
- cmd = 'ovs-vsctl show'
+ cmd = 'sudo ovs-vsctl show'
output = self.__remote_cmd(ssh_conn, cmd)
operation = 'vsctl_show'
host = self.__ssh_host(ssh_conn)
paramiko>=2.0 # LGPLv2.1+
mock>=2.0 # BSD
-requests!=2.12.2,>=2.10.0 # Apache-2.0
+requests>=2.14.2 # Apache-2.0
pass
setuptools.setup(
- setup_requires=['pbr>=1.8'],
+ setup_requires=['pbr>=2.0.0'],
pbr=True)
nose # LGPL
-coverage>=4.0 # Apache-2.0
+coverage!=4.4,>=4.0 # Apache-2.0
nb_test_runnable_for_this_scenario += 1
LOGGER.info(" Searching results for case %s ",
displayName)
- result = rp_utils.getResult(name, installer,
- s, version)
+ if "fuel" in installer:
+ result = rp_utils.getCaseScoreFromBuildTag(
+ name,
+ s_result)
+ else:
+ result = rp_utils.getCaseScore(name, installer,
+ s, version)
# if no result set the value to 0
if result < 0:
result = 0
project = test_case.getProject()
LOGGER.info(" Searching results for case %s ",
displayName)
- result = rp_utils.getResult(name, installer,
- s, version)
+ if "fuel" in installer:
+ result = rp_utils.getCaseScoreFromBuildTag(
+ name,
+ s_result)
+ else:
+ result = rp_utils.getCaseScore(name, installer,
+ s, version)
# at least 1 result for the test
if result > -1:
test_case.setCriteria(result)
# 2 iterations : max score = 20 (10x2)
# 3 iterations : max score = 20
# 4 or more iterations : max score = 30 (1x30)
+ LOGGER.info("Number of iterations for this scenario: %s",
+ len(s_result))
if len(s_result) > 3:
k_score = 3
elif len(s_result) < 2:
versions:
- master
- euphrates
- - danube
log:
log_file: reporting.log
blacklist:
- odl_netvirt
- juju_epc
+ - tempest_full_parallel
+ - rally_full
max_scenario_criteria: 50
test_conf: https://git.opnfv.org/cgit/functest/plain/functest/ci/testcases.yaml
log_level: ERROR
#
# http://www.apache.org/licenses/LICENSE-2.0
#
-from urllib2 import Request, urlopen, URLError
import logging
import json
import os
import pdfkit
import yaml
+from urllib2 import Request, urlopen, URLError
+
# ----------------------------------------------------------
#
"""
Get the list of Scenarios
"""
-
+ test_results = None
+ scenario_results = None
period = get_config('general.period')
url_base = get_config('testapi.url')
return nb_test_ok
-def getResult(testCase, installer, scenario, version):
+def getCaseScore(testCase, installer, scenario, version):
"""
Get Result for a given Functest Testcase
"""
return test_result_indicator
+def getCaseScoreFromBuildTag(testCase, s_results):
+ """
+ Get Results for a given Functest Testcase with arch filtering
+ """
+ url_base = get_config('testapi.url')
+ nb_tests = get_config('general.nb_iteration_tests_success_criteria')
+ test_result_indicator = 0
+ # architecture is not a result field...so we cannot use getResult as it is
+ res_matrix = []
+ try:
+ for s_result in s_results:
+ build_tag = s_result['build_tag']
+ d = s_result['start_date']
+ res_matrix.append({'date': d,
+ 'build_tag': build_tag})
+ # sort res_matrix
+ filter_res_matrix = sorted(res_matrix, key=lambda k: k['date'],
+ reverse=True)[:nb_tests]
+ for my_res in filter_res_matrix:
+ url = ("http://" + url_base + "?case=" + testCase +
+ "&build_tag=" + my_res['build_tag'])
+ request = Request(url)
+ response = urlopen(request)
+ k = response.read()
+ results = json.loads(k)
+ if "PASS" in results['results'][0]['criteria']:
+ test_result_indicator += 1
+ except:
+ print "No results found for this case"
+ if test_result_indicator > 2:
+ test_result_indicator = test_result_indicator - 1
+
+ return test_result_indicator
+
+
def getJenkinsUrl(build_tag):
"""
Get Jenkins url_base corespoding to the last test CI run
*.egg-info
3rd_party/static/static
*.pyc
+.cache
+.eggs
+.tox
+.ven
+docs/_build
--- /dev/null
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+SPHINXPROJ = OPNFVTestAPI
+SOURCEDIR = .
+BUILDDIR = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file
--- /dev/null
+# -*- coding: utf-8 -*-
+#
+# OPNFV TestAPI documentation build configuration file, created by
+# sphinx-quickstart on Thu Oct 26 10:23:57 2017.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+# source_suffix = ['.rst', '.md']
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'OPNFV TestAPI'
+copyright = u'2017, SerenaFeng'
+author = u'SerenaFeng'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = u'v1.0'
+# The full version, including alpha/beta/rc tags.
+release = u'v1.0'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This patterns also effect to html_static_path and html_extra_path
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'alabaster'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#
+# html_theme_options = {}
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+# html_static_path = ['_static']
+
+# Custom sidebar templates, must be a dictionary that maps document names
+# to template names.
+#
+# This is required for the alabaster theme
+# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
+html_sidebars = {
+ '**': [
+ 'relations.html', # needs 'show_related': True theme option to display
+ 'searchbox.html',
+ ]
+}
+
+
+# -- Options for HTMLHelp output ------------------------------------------
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'OPNFVTestAPIdoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+ # The paper size ('letterpaper' or 'a4paper').
+ #
+ # 'papersize': 'letterpaper',
+
+ # The font size ('10pt', '11pt' or '12pt').
+ #
+ # 'pointsize': '10pt',
+
+ # Additional stuff for the LaTeX preamble.
+ #
+ # 'preamble': '',
+
+ # Latex figure (float) alignment
+ #
+ # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ (master_doc, 'OPNFVTestAPI.tex', u'OPNFV TestAPI Documentation',
+ u'SerenaFeng', 'manual'),
+]
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ (master_doc, 'opnfvtestapi', u'OPNFV TestAPI Documentation',
+ [author], 1)
+]
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ (master_doc, 'OPNFVTestAPI', u'OPNFV TestAPI Documentation',
+ author, 'OPNFVTestAPI', 'One line description of project.',
+ 'Miscellaneous'),
+]
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 ZTE Corp.
+
+============
+Restful APIs
+============
+
+.. toctree::
+ :maxdepth: 2
-=============
-opnfv-testapi
-=============
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 ZTE Corp.
+
+
+.. toctree::
+ :maxdepth: 2
+
+=========
+Framework
+=========
**Test Results Collector of OPNFV Test Projects**:
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 ZTE Corp.
+
+
+***********************
+TestAPI Developer Guide
+***********************
+
+.. toctree::
+ :maxdepth: 2
+
+ overview.rst
+ framework.rst
+ api.rst
+ swagger-ui.rst
+ web-portal.rst
+ testapi-client.rst
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 ZTE Corporation
+
+
+********
+Overview
+********
+
+TestAPI uses Python as primary programming language and build the framework from the following packages
+
+======== ===============================================================================================================
+Module Package
+======== ===============================================================================================================
+api `Tornado-Motor`_ - API applications using Motor with tornado
+swagger `tornado-swagger`_ - a wrapper for tornado which enables swagger-ui-v1.2 support
+web `angular`_ - a superheroic JavaScript MVW framework, the version is AngularJS v1.3.15
+docs `sphinx`_ - a tool that makes it easy to create intelligent and beautiful documentation
+testing `pytest`_ - a mature full-featured Python testing tool that helps you write better programs
+======== ===============================================================================================================
+
+
+Source Code
+===========
+
+The structure of repository is based on the recommended sample in `The Hitchhiker's Guide to Python`_
+
+========================== ====================================================================================================
+Path Content
+========================== ====================================================================================================
+``./3rd_party/`` third part included in TestAPI project
+``./docker/`` configuration for building Docker image for TestAPI deployment
+``./docs/`` user and developer documentation, design proposals
+``./etc/`` configuration files used to install opnfv-testapi
+``./opnfv_testapi/`` the actual package
+``./opnfv_testapi/tests/`` package functional and unit tests
+``./opts/`` optional components, e.g. one click deployment script
+========================== ====================================================================================================
+
+
+Coding Style
+============
+
+TestAPI follows `OpenStack Style Guidelines`_ for source code and commit message.
+
+Specially, it is recommended to link each patch set with a JIRA issue. Put::
+
+ JIRA: RELENG-n
+
+in commit message to create an automatic link.
+
+
+Testing
+=======
+
+All testing related code are stored in ``./opnfv_testapi/tests/``
+
+================== ====================================================================================================
+Path Content
+================== ====================================================================================================
+``./tests/unit/`` unit test for each module, follow the same layout as ./opnfv_testapi/
+``./conftest.py`` pytest configuration in project scope
+================== ====================================================================================================
+
+`tox`_ is used to automate the testing tasks
+
+.. code-block:: shell
+
+ cd <project_root>
+ pip install tox
+ tox
+
+The test cases are written in `pytest`_. You may run it selectively with
+
+.. code-block:: shell
+
+ pytest opnfv_testapi/tests/unit/common/test_config.py
+
+
+Branching
+=========
+
+Currently, no branching for TestAPI, only master branch
+
+
+Releasing
+=========
+
+Currently, TestAPI does not follow community's milestones and releases
+
+.. _Tornado-Motor: https://motor.readthedocs.io/en/stable/tutorial-tornado.html
+.. _tornado-swagger: https://github.com/SerenaFeng/tornado-swagger
+.. _angular: https://code.angularjs.org/1.3.15/docs/guide
+.. _sphinx: http://www.sphinx-doc.org/en/stable/
+.. _pytest: http://doc.pytest.org/
+.. _OpenStack Style Guidelines: http://docs.openstack.org/developer/hacking/
+.. _The Hitchhiker's Guide to Python: http://python-guide-pt-br.readthedocs.io/en/latest/writing/structure/
+.. _tox: https://tox.readthedocs.io/
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 ZTE Corp.
+
+============
+Swagger page
+============
+
+.. toctree::
+ :maxdepth: 2
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 ZTE Corp.
+
+==============
+TestAPI client
+==============
+
+.. toctree::
+ :maxdepth: 2
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 ZTE Corp.
+
+==========
+Web portal
+==========
+
+.. toctree::
+ :maxdepth: 2
--- /dev/null
+.. OPNFV TestAPI documentation master file, created by
+ sphinx-quickstart on Thu Oct 26 10:23:57 2017.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Welcome to OPNFV TestAPI's documentation!
+=========================================
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Contents:
+
+
+Developer Guide
+===============
+
+.. toctree::
+ :maxdepth: 2
+
+ developer/devguide/index.rst
# With debug_on set to true, error traces will be shown in HTTP responses
debug = True
-authenticate = False
+token_check = False
+authenticate = True
[ui]
url = http://localhost:8000
return swagger.Application(
url_mappings.mappings,
debug=CONF.api_debug,
- auth=CONF.api_authenticate,
+ auth=CONF.api_token_check,
cookie_secret='opnfv-testapi',
)
from opnfv_testapi.common import constants
from opnfv_testapi.common import message
from opnfv_testapi.common import raises
+from opnfv_testapi.common.config import CONF
from opnfv_testapi.db import api as dbapi
def is_authorized(method):
@functools.wraps(method)
def wrapper(self, *args, **kwargs):
- if self.table in ['pods']:
+ if CONF.api_authenticate and self.table in ['pods']:
testapi_id = self.get_secure_cookie(constants.TESTAPI_ID)
if not testapi_id:
raises.Unauthorized(message.not_login())
return wrap
+def values_check(xstep):
+ @functools.wraps(xstep)
+ def wrap(self, *args, **kwargs):
+ checks = kwargs.pop('values_check', {})
+ if checks:
+ for field, check, options in checks:
+ if not check(field, options):
+ raises.BadRequest(message.invalid_value(field, options))
+ ret = yield gen.coroutine(xstep)(self, *args, **kwargs)
+ raise gen.Return(ret)
+ return wrap
+
+
def new_not_exists(xstep):
@functools.wraps(xstep)
def wrap(self, *args, **kwargs):
def _parse_value(value):
try:
value = int(value)
- except:
+ except Exception:
if str(value).lower() == 'true':
value = True
elif str(value).lower() == 'false':
return '{} Missing'.format(name)
+def invalid_value(name, options):
+ return '{} must be in {}'.format(name, options)
+
+
def exist(key, value):
return '{} [{}] {}'.format(key, value, exist_base)
# feng.xiaowei@zte.com.cn remove DashboardHandler 5-30-2016
##############################################################################
-import json
from datetime import datetime
+import json
from tornado import gen
from tornado import web
from opnfv_testapi.common import message
from opnfv_testapi.common import raises
from opnfv_testapi.db import api as dbapi
-from opnfv_testapi.resources import models
+from opnfv_testapi.models import base_models
from opnfv_testapi.tornado_swagger import swagger
DEFAULT_REPRESENTATION = "application/json"
def _create_response(self, resource):
href = self.request.full_url() + '/' + str(resource)
- return models.CreateResponse(href=href).format()
+ return base_models.CreateResponse(href=href).format()
def format_data(self, data):
cls_data = self.table_cls.from_dict(data)
@check.valid_token
@check.no_body
@check.miss_fields
+ @check.values_check
@check.carriers_exist
@check.new_not_exists
def _create(self, **kwargs):
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-import handlers
-from opnfv_testapi.resources import pod_models
+from opnfv_testapi.handlers import base_handlers
+from opnfv_testapi.models import pod_models
from opnfv_testapi.tornado_swagger import swagger
-class GenericPodHandler(handlers.GenericApiHandler):
+class GenericPodHandler(base_handlers.GenericApiHandler):
def __init__(self, application, request, **kwargs):
super(GenericPodHandler, self).__init__(application, request, **kwargs)
self.table = 'pods'
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-from opnfv_testapi.resources import handlers
-from opnfv_testapi.resources import project_models
+from opnfv_testapi.handlers import base_handlers
+from opnfv_testapi.models import project_models
from opnfv_testapi.tornado_swagger import swagger
-class GenericProjectHandler(handlers.GenericApiHandler):
+class GenericProjectHandler(base_handlers.GenericApiHandler):
def __init__(self, application, request, **kwargs):
super(GenericProjectHandler, self).__init__(application,
request,
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
+from datetime import datetime
+from datetime import timedelta
import json
import logging
from bson import objectid
-from datetime import datetime
-from datetime import timedelta
from opnfv_testapi.common import constants
from opnfv_testapi.common import message
from opnfv_testapi.common import raises
from opnfv_testapi.common.config import CONF
-from opnfv_testapi.resources import handlers
-from opnfv_testapi.resources import result_models
+from opnfv_testapi.handlers import base_handlers
+from opnfv_testapi.models import result_models
from opnfv_testapi.tornado_swagger import swagger
-class GenericResultHandler(handlers.GenericApiHandler):
+class GenericResultHandler(base_handlers.GenericApiHandler):
def __init__(self, application, request, **kwargs):
super(GenericResultHandler, self).__init__(application,
request,
def get_int(self, key, value):
try:
value = int(value)
- except:
+ except Exception:
raises.BadRequest(message.must_int(key))
return value
return {'project_name': self.json_args.get('project_name'),
'name': self.json_args.get('case_name')}
+ def options_check(field, options):
+ return self.json_args.get(field).upper() in options
+
miss_fields = ['pod_name', 'project_name', 'case_name']
carriers = [('pods', pod_query),
('projects', project_query),
('testcases', testcase_query)]
+ values_check = [('criteria', options_check, ['PASS', 'FAIL'])]
- self._create(miss_fields=miss_fields, carriers=carriers)
+ self._create(miss_fields=miss_fields,
+ carriers=carriers,
+ values_check=values_check)
class ResultsUploadHandler(ResultsCLHandler):
from opnfv_testapi.common.config import CONF
-from opnfv_testapi.resources import handlers
+from opnfv_testapi.handlers import base_handlers
-class RootHandler(handlers.GenericApiHandler):
+class RootHandler(base_handlers.GenericApiHandler):
def get_template_path(self):
return CONF.ui_static_path
from opnfv_testapi.common import message
from opnfv_testapi.common import raises
-from opnfv_testapi.resources import handlers
-import opnfv_testapi.resources.scenario_models as models
+from opnfv_testapi.handlers import base_handlers
+import opnfv_testapi.models.scenario_models as models
from opnfv_testapi.tornado_swagger import swagger
-class GenericScenarioHandler(handlers.GenericApiHandler):
+class GenericScenarioHandler(base_handlers.GenericApiHandler):
def __init__(self, application, request, **kwargs):
super(GenericScenarioHandler, self).__init__(application,
request,
from opnfv_testapi.common import constants
from opnfv_testapi.common.config import CONF
from opnfv_testapi.db import api as dbapi
-from opnfv_testapi.resources import handlers
+from opnfv_testapi.handlers import base_handlers
-class SignBaseHandler(handlers.GenericApiHandler):
+class SignBaseHandler(base_handlers.GenericApiHandler):
def __init__(self, application, request, **kwargs):
super(SignBaseHandler, self).__init__(application, request, **kwargs)
self.table = 'users'
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-from opnfv_testapi.resources import handlers
-from opnfv_testapi.resources import testcase_models
+from opnfv_testapi.handlers import base_handlers
+from opnfv_testapi.models import testcase_models
from opnfv_testapi.tornado_swagger import swagger
-class GenericTestcaseHandler(handlers.GenericApiHandler):
+class GenericTestcaseHandler(base_handlers.GenericApiHandler):
def __init__(self, application, request, **kwargs):
super(GenericTestcaseHandler, self).__init__(application,
request,
--- /dev/null
+from opnfv_testapi.common import constants
+from opnfv_testapi.common import raises
+from opnfv_testapi.common.config import CONF
+from opnfv_testapi.handlers import base_handlers
+from opnfv_testapi.models.user_models import User
+
+
+class UserHandler(base_handlers.GenericApiHandler):
+ def __init__(self, application, request, **kwargs):
+ super(UserHandler, self).__init__(application, request, **kwargs)
+ self.table = 'users'
+ self.table_cls = User
+
+ def get(self):
+ if CONF.api_authenticate:
+ username = self.get_secure_cookie(constants.TESTAPI_ID)
+ if username:
+ self._get_one(query={'user': username})
+ else:
+ raises.Unauthorized('Unauthorized')
+ else:
+ self.finish_request(User('anonymous',
+ 'anonymous@linuxfoundation.com',
+ 'anonymous lf',
+ constants.TESTAPI_USERS).format())
elif isinstance(obj, unicode):
try:
obj = self._obj_format(ast.literal_eval(obj))
- except:
+ except Exception:
try:
obj = str(obj)
- except:
+ except Exception:
obj = obj
elif isinstance(obj, list):
hs = list()
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-from opnfv_testapi.resources import models
+from opnfv_testapi.models import base_models
from opnfv_testapi.tornado_swagger import swagger
@swagger.model()
-class PodCreateRequest(models.ModelBase):
+class PodCreateRequest(base_models.ModelBase):
def __init__(self, name, mode='', details='', role=""):
self.name = name
self.mode = mode
@swagger.model()
-class Pod(models.ModelBase):
+class Pod(base_models.ModelBase):
def __init__(self,
name='', mode='', details='',
role="", _id='', create_date='', owner=''):
@swagger.model()
-class Pods(models.ModelBase):
+class Pods(base_models.ModelBase):
"""
@property pods:
@ptype pods: C{list} of L{Pod}
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-from opnfv_testapi.resources import models
+from opnfv_testapi.models import base_models
from opnfv_testapi.tornado_swagger import swagger
@swagger.model()
-class ProjectCreateRequest(models.ModelBase):
+class ProjectCreateRequest(base_models.ModelBase):
def __init__(self, name, description=''):
self.name = name
self.description = description
@swagger.model()
-class ProjectUpdateRequest(models.ModelBase):
+class ProjectUpdateRequest(base_models.ModelBase):
def __init__(self, name='', description=''):
self.name = name
self.description = description
@swagger.model()
-class Project(models.ModelBase):
+class Project(base_models.ModelBase):
def __init__(self,
name=None, _id=None, description=None, create_date=None):
self._id = _id
@swagger.model()
-class Projects(models.ModelBase):
+class Projects(base_models.ModelBase):
"""
@property projects:
@ptype projects: C{list} of L{Project}
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-from opnfv_testapi.resources import models
+from opnfv_testapi.models import base_models
from opnfv_testapi.tornado_swagger import swagger
@swagger.model()
-class TIHistory(models.ModelBase):
+class TIHistory(base_models.ModelBase):
"""
@ptype step: L{float}
"""
@swagger.model()
-class TI(models.ModelBase):
+class TI(base_models.ModelBase):
"""
@property histories: trust_indicator update histories
@ptype histories: C{list} of L{TIHistory}
@swagger.model()
-class ResultCreateRequest(models.ModelBase):
+class ResultCreateRequest(base_models.ModelBase):
"""
@property trust_indicator:
@ptype trust_indicator: L{TI}
@swagger.model()
-class ResultUpdateRequest(models.ModelBase):
+class ResultUpdateRequest(base_models.ModelBase):
"""
@property trust_indicator:
@ptype trust_indicator: L{TI}
@swagger.model()
-class TestResult(models.ModelBase):
+class TestResult(base_models.ModelBase):
"""
@property trust_indicator: used for long duration test case
@ptype trust_indicator: L{TI}
@swagger.model()
-class TestResults(models.ModelBase):
+class TestResults(base_models.ModelBase):
"""
@property results:
@ptype results: C{list} of L{TestResult}
-from opnfv_testapi.resources import models
+from opnfv_testapi.models import base_models
from opnfv_testapi.tornado_swagger import swagger
@swagger.model()
-class ScenarioTI(models.ModelBase):
+class ScenarioTI(base_models.ModelBase):
def __init__(self, date=None, status='silver'):
self.date = date
self.status = status
@swagger.model()
-class ScenarioScore(models.ModelBase):
+class ScenarioScore(base_models.ModelBase):
def __init__(self, date=None, score='0'):
self.date = date
self.score = score
@swagger.model()
-class ScenarioProject(models.ModelBase):
+class ScenarioProject(base_models.ModelBase):
"""
@property customs:
@ptype customs: C{list} of L{string}
@swagger.model()
-class ScenarioVersion(models.ModelBase):
+class ScenarioVersion(base_models.ModelBase):
"""
@property projects:
@ptype projects: C{list} of L{ScenarioProject}
@swagger.model()
-class ScenarioInstaller(models.ModelBase):
+class ScenarioInstaller(base_models.ModelBase):
"""
@property versions:
@ptype versions: C{list} of L{ScenarioVersion}
@swagger.model()
-class ScenarioCreateRequest(models.ModelBase):
+class ScenarioCreateRequest(base_models.ModelBase):
"""
@property installers:
@ptype installers: C{list} of L{ScenarioInstaller}
@swagger.model()
-class ScenarioChangeOwnerRequest(models.ModelBase):
+class ScenarioChangeOwnerRequest(base_models.ModelBase):
def __init__(self, owner=None):
self.owner = owner
@swagger.model()
-class ScenarioUpdateRequest(models.ModelBase):
+class ScenarioUpdateRequest(base_models.ModelBase):
def __init__(self, name=None):
self.name = name
@swagger.model()
-class Scenario(models.ModelBase):
+class Scenario(base_models.ModelBase):
"""
@property installers:
@ptype installers: C{list} of L{ScenarioInstaller}
@swagger.model()
-class Scenarios(models.ModelBase):
+class Scenarios(base_models.ModelBase):
"""
@property scenarios:
@ptype scenarios: C{list} of L{Scenario}
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-from opnfv_testapi.resources import models
+from opnfv_testapi.models import base_models
from opnfv_testapi.tornado_swagger import swagger
@swagger.model()
-class TestcaseCreateRequest(models.ModelBase):
+class TestcaseCreateRequest(base_models.ModelBase):
def __init__(self, name, url=None, description=None,
catalog_description=None, tier=None, ci_loop=None,
criteria=None, blocking=None, dependencies=None, run=None,
@swagger.model()
-class TestcaseUpdateRequest(models.ModelBase):
+class TestcaseUpdateRequest(base_models.ModelBase):
def __init__(self, name=None, description=None, project_name=None,
catalog_description=None, tier=None, ci_loop=None,
criteria=None, blocking=None, dependencies=None, run=None,
@swagger.model()
-class Testcase(models.ModelBase):
+class Testcase(base_models.ModelBase):
def __init__(self, _id=None, name=None, project_name=None,
description=None, url=None, creation_date=None,
catalog_description=None, tier=None, ci_loop=None,
@swagger.model()
-class Testcases(models.ModelBase):
+class Testcases(base_models.ModelBase):
"""
@property testcases:
@ptype testcases: C{list} of L{Testcase}
--- /dev/null
+from opnfv_testapi.models import base_models
+
+
+class User(base_models.ModelBase):
+ def __init__(self, user=None, email=None, fullname=None, groups=None):
+ self.user = user
+ self.email = email
+ self.fullname = fullname
+ self.groups = groups
import tornado.web
from opnfv_testapi.common.config import CONF
-from opnfv_testapi.resources import handlers
-from opnfv_testapi.resources import pod_handlers
-from opnfv_testapi.resources import project_handlers
-from opnfv_testapi.resources import result_handlers
-from opnfv_testapi.resources import scenario_handlers
-from opnfv_testapi.resources import testcase_handlers
-from opnfv_testapi.ui import root
-from opnfv_testapi.ui.auth import sign
-from opnfv_testapi.ui.auth import user
+from opnfv_testapi.handlers import base_handlers
+from opnfv_testapi.handlers import pod_handlers
+from opnfv_testapi.handlers import project_handlers
+from opnfv_testapi.handlers import result_handlers
+from opnfv_testapi.handlers import root_handlers
+from opnfv_testapi.handlers import scenario_handlers
+from opnfv_testapi.handlers import sign_handlers
+from opnfv_testapi.handlers import testcase_handlers
+from opnfv_testapi.handlers import user_handlers
mappings = [
# GET /versions => GET API version
- (r"/versions", handlers.VersionHandler),
+ (r"/versions", base_handlers.VersionHandler),
# few examples:
# GET /api/v1/pods => Get all pods
tornado.web.StaticFileHandler,
{'path': CONF.ui_static_path}),
- (r'/', root.RootHandler),
- (r'/api/v1/auth/signin', sign.SigninHandler),
- (r'/{}'.format(CONF.lfid_signin_return), sign.SigninReturnHandler),
- (r'/api/v1/auth/signout', sign.SignoutHandler),
- (r'/api/v1/profile', user.UserHandler),
+ (r'/', root_handlers.RootHandler),
+ (r'/api/v1/auth/signin', sign_handlers.SigninHandler),
+ (r'/{}'.format(CONF.lfid_signin_return),
+ sign_handlers.SigninReturnHandler),
+ (r'/api/v1/auth/signout', sign_handlers.SignoutHandler),
+ (r'/api/v1/profile', user_handlers.UserHandler),
]
assert CONF.mongo_dbname == 'test_results_collection'
assert CONF.api_port == 8000
assert CONF.api_debug is True
- assert CONF.api_authenticate is False
+ assert CONF.api_token_check is False
+ assert CONF.api_authenticate is True
assert CONF.ui_url == 'http://localhost:8000'
O_get_secure_cookie = (
- 'opnfv_testapi.resources.handlers.GenericApiHandler.get_secure_cookie')
+ 'opnfv_testapi.handlers.base_handlers.GenericApiHandler.get_secure_cookie')
def thread_execute(method, *args, **kwargs):
import mock
from tornado import testing
-from opnfv_testapi.resources import models
-from opnfv_testapi.resources import pod_models
+from opnfv_testapi.models import base_models
+from opnfv_testapi.models import pod_models
from opnfv_testapi.tests.unit import fake_pymongo
def setUp(self):
self._patch_server()
self.basePath = ''
- self.create_res = models.CreateResponse
+ self.create_res = base_models.CreateResponse
self.get_res = None
self.list_res = None
self.update_res = None
import unittest
from opnfv_testapi.common import message
-from opnfv_testapi.resources import pod_models
+from opnfv_testapi.models import pod_models
from opnfv_testapi.tests.unit import executor
from opnfv_testapi.tests.unit import fake_pymongo
-from opnfv_testapi.tests.unit.resources import test_base as base
+from opnfv_testapi.tests.unit.handlers import test_base as base
class TestPodBase(base.TestBase):
import unittest
from opnfv_testapi.common import message
-from opnfv_testapi.resources import project_models
+from opnfv_testapi.models import project_models
from opnfv_testapi.tests.unit import executor
-from opnfv_testapi.tests.unit.resources import test_base as base
+from opnfv_testapi.tests.unit.handlers import test_base as base
class TestProjectBase(base.TestBase):
import unittest
from opnfv_testapi.common import message
-from opnfv_testapi.resources import project_models
-from opnfv_testapi.resources import result_models
-from opnfv_testapi.resources import testcase_models
+from opnfv_testapi.models import project_models
+from opnfv_testapi.models import result_models
+from opnfv_testapi.models import testcase_models
from opnfv_testapi.tests.unit import executor
from opnfv_testapi.tests.unit import fake_pymongo
-from opnfv_testapi.tests.unit.resources import test_base as base
+from opnfv_testapi.tests.unit.handlers import test_base as base
class Details(object):
self.version = 'C'
self.build_tag = 'v3.0'
self.scenario = 'odl-l2'
- self.criteria = 'passed'
+ self.criteria = 'PASS'
self.trust_indicator = result_models.TI(0.7)
self.start_date = str(datetime.now())
self.stop_date = str(datetime.now() + timedelta(minutes=1))
req.case_name = None
return req
+ @executor.create(httplib.BAD_REQUEST,
+ message.invalid_value('criteria', ['PASS', 'FAIL']))
+ def test_invalid_criteria(self):
+ req = self.req_d
+ req.criteria = 'invalid'
+ return req
+
@executor.create(httplib.FORBIDDEN, message.not_found_base)
def test_noPod(self):
req = self.req_d
from datetime import datetime
from opnfv_testapi.common import message
-import opnfv_testapi.resources.scenario_models as models
-from opnfv_testapi.tests.unit.resources import test_base as base
+import opnfv_testapi.models.scenario_models as models
+from opnfv_testapi.tests.unit.handlers import test_base as base
def _none_default(check, default):
import unittest
from opnfv_testapi.common import message
-from opnfv_testapi.resources import project_models
-from opnfv_testapi.resources import testcase_models
+from opnfv_testapi.models import project_models
+from opnfv_testapi.models import testcase_models
from opnfv_testapi.tests.unit import executor
-from opnfv_testapi.tests.unit.resources import test_base as base
+from opnfv_testapi.tests.unit.handlers import test_base as base
class TestCaseBase(base.TestBase):
from opnfv_testapi.common import message
from opnfv_testapi.tests.unit import executor
from opnfv_testapi.tests.unit import fake_pymongo
-from opnfv_testapi.tests.unit.resources import test_result
+from opnfv_testapi.tests.unit.handlers import test_result
class TestTokenCreateResult(test_result.TestResultBase):
import httplib
import unittest
-from opnfv_testapi.resources import models
+from opnfv_testapi.models import base_models
from opnfv_testapi.tests.unit import executor
-from opnfv_testapi.tests.unit.resources import test_base as base
+from opnfv_testapi.tests.unit.handlers import test_base as base
class TestVersionBase(base.TestBase):
def setUp(self):
super(TestVersionBase, self).setUp()
- self.list_res = models.Versions
+ self.list_res = base_models.Versions
self.basePath = '/versions'
+++ /dev/null
-##############################################################################
-# Copyright (c) 2016 ZTE Corporation
-# feng.xiaowei@zte.com.cn
-# 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
-
-from tornado import gen
-from tornado import testing
-from tornado import web
-
-from opnfv_testapi.tests.unit import fake_pymongo
-
-
-class MyTest(testing.AsyncHTTPTestCase):
- def setUp(self):
- super(MyTest, self).setUp()
- self.db = fake_pymongo
- self.addCleanup(self._clear)
- self.io_loop.run_sync(self.fixture_setup)
-
- def get_app(self):
- return web.Application()
-
- @gen.coroutine
- def fixture_setup(self):
- self.test1 = {'_id': '1', 'name': 'test1'}
- self.test2 = {'name': 'test2'}
- yield self.db.pods.insert({'_id': '1', 'name': 'test1'})
- yield self.db.pods.insert({'name': 'test2'})
-
- @testing.gen_test
- def test_find_one(self):
- user = yield self.db.pods.find_one({'name': 'test1'})
- self.assertEqual(user, self.test1)
- self.db.pods.remove()
-
- @testing.gen_test
- def test_find(self):
- cursor = self.db.pods.find()
- names = []
- while (yield cursor.fetch_next):
- ob = cursor.next_object()
- names.append(ob.get('name'))
- self.assertItemsEqual(names, ['test1', 'test2'])
-
- @testing.gen_test
- def test_update(self):
- yield self.db.pods.update({'_id': '1'}, {'name': 'new_test1'})
- user = yield self.db.pods.find_one({'_id': '1'})
- self.assertEqual(user.get('name', None), 'new_test1')
-
- def test_update_dot_error(self):
- self._update_assert({'_id': '1', 'name': {'1. name': 'test1'}},
- 'key 1. name must not contain .')
-
- def test_update_dot_no_error(self):
- self._update_assert({'_id': '1', 'name': {'1. name': 'test1'}},
- None,
- check_keys=False)
-
- def test_update_dollar_error(self):
- self._update_assert({'_id': '1', 'name': {'$name': 'test1'}},
- 'key $name must not start with $')
-
- def test_update_dollar_no_error(self):
- self._update_assert({'_id': '1', 'name': {'$name': 'test1'}},
- None,
- check_keys=False)
-
- @testing.gen_test
- def test_remove(self):
- yield self.db.pods.remove({'_id': '1'})
- user = yield self.db.pods.find_one({'_id': '1'})
- self.assertIsNone(user)
-
- def test_insert_dot_error(self):
- self._insert_assert({'_id': '1', '2. name': 'test1'},
- 'key 2. name must not contain .')
-
- def test_insert_dot_no_error(self):
- self._insert_assert({'_id': '1', '2. name': 'test1'},
- None,
- check_keys=False)
-
- def test_insert_dollar_error(self):
- self._insert_assert({'_id': '1', '$name': 'test1'},
- 'key $name must not start with $')
-
- def test_insert_dollar_no_error(self):
- self._insert_assert({'_id': '1', '$name': 'test1'},
- None,
- check_keys=False)
-
- def _clear(self):
- self.db.pods.clear()
-
- def _update_assert(self, docs, error=None, **kwargs):
- self._db_assert('update', error, {'_id': '1'}, docs, **kwargs)
-
- def _insert_assert(self, docs, error=None, **kwargs):
- self._db_assert('insert', error, docs, **kwargs)
-
- @testing.gen_test
- def _db_assert(self, method, error, *args, **kwargs):
- name_error = None
- try:
- yield self._eval_pods_db(method, *args, **kwargs)
- except NameError as err:
- name_error = err.args[0]
- finally:
- self.assertEqual(name_error, error)
-
- def _eval_pods_db(self, method, *args, **kwargs):
- table_obj = vars(self.db)['pods']
- return table_obj.__getattribute__(method)(*args, **kwargs)
-
-
-if __name__ == '__main__':
- unittest.main()
settings.docs_settings,
name=settings.API_DOCS_NAME),
tornado.web.URLSpec(
- _path(r'resources.json$'),
+ _path(r'models.json$'),
views.SwaggerResourcesHandler,
settings.docs_settings,
name=settings.RESOURCE_LISTING_NAME),
+++ /dev/null
-from opnfv_testapi.common import constants
-from opnfv_testapi.common import raises
-from opnfv_testapi.resources import handlers
-from opnfv_testapi.resources import models
-
-
-class User(models.ModelBase):
- def __init__(self, user=None, email=None, fullname=None, groups=None):
- self.user = user
- self.email = email
- self.fullname = fullname
- self.groups = groups
-
-
-class UserHandler(handlers.GenericApiHandler):
- def __init__(self, application, request, **kwargs):
- super(UserHandler, self).__init__(application, request, **kwargs)
- self.table = 'users'
- self.table_cls = User
-
- def get(self):
- username = self.get_secure_cookie(constants.TESTAPI_ID)
- if username:
- self._get_one(query={'user': username})
- else:
- raises.Unauthorized('Unauthorized')
[metadata]
name = opnfv_testapi
summary = Test Result Collector
-description-file =
- README.rst
author = SerenaFeng
author-email = feng.xiaowei@zte.com.cn
#home-page = http://www.opnfv.org/
data_files =
/etc/opnfv_testapi = etc/config.ini
/usr/local/share/opnfv_testapi = 3rd_party/static/*
+ /usr/local/share/opnfv_testapi/testapi-ui/components = opnfv_testapi/ui/*
[entry_points]
console_scripts =
HOME = {envtmpdir}
PYTHONPATH = {toxinidir}
+[testenv:docs]
+basepython=python2.7
+commands = sphinx-build -W -b html docs/ docs/_build
+
[testenv:pep8]
deps = flake8
commands = flake8 {toxinidir}