summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xjjb/apex/apex-upload-artifact.sh47
-rw-r--r--jjb/apex/apex.yml52
-rw-r--r--jjb/armband/armband-ci-jobs.yml17
-rw-r--r--jjb/armband/armband-project-jobs.yml1
-rw-r--r--jjb/bottlenecks/bottlenecks-project-jobs.yml1
-rw-r--r--jjb/compass4nfv/compass-ci-jobs.yml8
-rw-r--r--jjb/compass4nfv/compass-project-jobs.yml8
-rw-r--r--jjb/cperf/cperf-ci-jobs.yml1
-rw-r--r--jjb/domino/domino.yml55
-rw-r--r--jjb/fastpathmetrics/fastpathmetrics.yml2
-rw-r--r--jjb/fuel/fuel-ci-jobs.yml8
-rw-r--r--jjb/fuel/fuel-project-jobs.yml3
-rw-r--r--jjb/functest/functest-ci-jobs.yml48
-rwxr-xr-xjjb/functest/functest-loop.sh (renamed from jjb/functest/functest-daily.sh)0
-rwxr-xr-xjjb/functest/set-functest-env.sh7
-rw-r--r--jjb/joid/joid-ci-jobs.yml12
-rwxr-xr-xjjb/moon/moon-verify.sh3
-rw-r--r--jjb/moon/moon.yml54
-rw-r--r--jjb/opnfv/artifact-cleanup.yml42
-rw-r--r--jjb/opnfv/installer-params.yml16
-rw-r--r--jjb/opnfv/slave-params.yml28
-rw-r--r--jjb/opnfv/test-sign.yml42
-rw-r--r--jjb/sandbox/sandbox-verify-jobs.yml280
-rw-r--r--jjb/vswitchperf/vswitchperf.yml2
-rw-r--r--jjb/yardstick/yardstick-ci-jobs.yml3
-rw-r--r--utils/gpg_import_key.sh42
-rw-r--r--utils/push-test-logs.sh4
-rw-r--r--utils/retention_script.sh37
-rwxr-xr-xutils/test-sign-artifact.sh26
-rw-r--r--utils/test/reporting/functest/reporting-status.py118
-rw-r--r--utils/test/reporting/functest/reporting-tempest.py71
-rw-r--r--utils/test/reporting/functest/reporting-vims.py68
-rw-r--r--utils/test/reporting/functest/reportingConf.py12
-rw-r--r--utils/test/reporting/functest/reportingUtils.py47
-rw-r--r--utils/test/reporting/functest/template/index-status-tmpl.html2
-rw-r--r--utils/test/reporting/functest/testCase.py58
-rw-r--r--utils/test/result_collection_api/docker/Dockerfile52
-rwxr-xr-xutils/test/result_collection_api/docker/prepare-env.sh16
-rwxr-xr-xutils/test/result_collection_api/docker/start-server.sh4
-rw-r--r--utils/test/result_collection_api/etc/config.ini2
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/resources/handlers.py5
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/resources/result_handlers.py24
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/resources/result_models.py104
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/tests/unit/fake_pymongo.py5
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/tests/unit/test_fake_pymongo.py2
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/tests/unit/test_project.py4
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/tests/unit/test_result.py51
47 files changed, 1291 insertions, 203 deletions
diff --git a/jjb/apex/apex-upload-artifact.sh b/jjb/apex/apex-upload-artifact.sh
index 0598f5615..d45c7c01b 100755
--- a/jjb/apex/apex-upload-artifact.sh
+++ b/jjb/apex/apex-upload-artifact.sh
@@ -11,6 +11,38 @@ echo
# source the opnfv.properties to get ARTIFACT_VERSION
source $WORKSPACE/opnfv.properties
+# clone releng repository
+echo "Cloning releng repository..."
+[ -d releng ] && rm -rf releng
+git clone https://gerrit.opnfv.org/gerrit/releng $WORKSPACE/releng/ &> /dev/null
+#this is where we import the siging key
+if [ -f $WORKSPACE/releng/utils/gpg_import_key.sh ]; then
+ source $WORKSPACE/releng/utils/gpg_import_key.sh
+fi
+
+signrpm () {
+for artifact in $RPM_LIST $SRPM_LIST; do
+ echo "Signing artifact: ${artifact}"
+ gpg2 -vvv --batch --yes --no-tty \
+ --default-key opnfv-helpdesk@rt.linuxfoundation.org \
+ --passphrase besteffort \
+ --detach-sig $artifact
+ gsutil cp "$artifact".sig gs://$GS_URL/$(basename "$artifact".sig)
+ echo "Upload complete for ${artifact} signature"
+done
+}
+
+signiso () {
+time gpg2 -vvv --batch --yes --no-tty \
+ --default-key opnfv-helpdesk@rt.linuxfoundation.org \
+ --passphrase notreallysecure \
+ --detach-sig $BUILD_DIRECTORY/release/OPNFV-CentOS-7-x86_64-$OPNFV_ARTIFACT_VERSION.iso
+
+gsutil cp $BUILD_DIRECTORY/release/OPNFV-CentOS-7-x86_64-$OPNFV_ARTIFACT_VERSION.iso.sig gs://$GS_URL/opnfv-$OPNFV_ARTIFACT_VERSION.iso.sig
+echo "ISO signature Upload Complete!"
+}
+
+uploadiso () {
# upload artifact and additional files to google storage
gsutil cp $BUILD_DIRECTORY/release/OPNFV-CentOS-7-x86_64-$OPNFV_ARTIFACT_VERSION.iso gs://$GS_URL/opnfv-$OPNFV_ARTIFACT_VERSION.iso > gsutil.iso.log
echo "ISO Upload Complete!"
@@ -26,7 +58,10 @@ VERSION_EXTENSION=$(echo $(basename $OPNFV_SRPM_URL) | sed 's/opnfv-apex-//')
for pkg in common undercloud opendaylight-sfc onos; do
SRPM_LIST+=" ${SRPM_INSTALL_PATH}/opnfv-apex-${pkg}-${VERSION_EXTENSION}"
done
+}
+uploadrpm () {
+#This is where we upload the rpms
for artifact in $RPM_LIST $SRPM_LIST; do
echo "Uploading artifact: ${artifact}"
gsutil cp $artifact gs://$GS_URL/$(basename $artifact) > gsutil.iso.log
@@ -34,6 +69,18 @@ for artifact in $RPM_LIST $SRPM_LIST; do
done
gsutil cp $WORKSPACE/opnfv.properties gs://$GS_URL/opnfv-$OPNFV_ARTIFACT_VERSION.properties > gsutil.properties.log
gsutil cp $WORKSPACE/opnfv.properties gs://$GS_URL/latest.properties > gsutil.latest.log
+}
+
+if gpg2 --list-keys | grep "opnfv-helpdesk@rt.linuxfoundation.org"; then
+ echo "Signing Key avaliable"
+ signiso
+ uploadiso
+ signrpm
+ uploadrpm
+else
+ uploadiso
+ uploadrpm
+fi
echo
echo "--------------------------------------------------------"
diff --git a/jjb/apex/apex.yml b/jjb/apex/apex.yml
index 6c14a8107..3ba8842fc 100644
--- a/jjb/apex/apex.yml
+++ b/jjb/apex/apex.yml
@@ -226,6 +226,7 @@
- throttle:
max-per-node: 1
max-total: 10
+ option: 'project'
builders:
- 'apex-unit-test'
@@ -238,13 +239,13 @@
git-revision: false
block: true
same-node: true
-# - trigger-builds:
-# - project: 'functest-apex-{verify-slave}-suite-{stream1}'
-# predefined-parameters: |
-# DEPLOY_SCENARIO=os-nosdn-nofeature-ha
-# FUNCTEST_SUITE_NAME=vping_userdata
-# block: true
-# same-node: true
+ - trigger-builds:
+ - project: 'functest-apex-{verify-slave}-suite-{stream1}'
+ predefined-parameters: |
+ DEPLOY_SCENARIO=os-nosdn-nofeature-ha
+ FUNCTEST_SUITE_NAME=healthcheck
+ block: true
+ same-node: true
- trigger-builds:
- project: 'apex-deploy-virtual-os-odl_l2-nofeature-ha-{stream1}'
predefined-parameters: |
@@ -253,6 +254,13 @@
git-revision: false
block: true
same-node: true
+ - trigger-builds:
+ - project: 'functest-apex-{verify-slave}-suite-{stream1}'
+ predefined-parameters: |
+ DEPLOY_SCENARIO=os-odl_l2-nofeature-ha
+ FUNCTEST_SUITE_NAME=healthcheck
+ block: true
+ same-node: true
- 'apex-workspace-cleanup'
- job-template:
@@ -356,6 +364,7 @@
- throttle:
max-per-node: 1
max-total: 10
+ option: 'project'
builders:
- 'apex-build'
@@ -412,6 +421,7 @@
- throttle:
max-per-node: 1
max-total: 10
+ option: 'project'
builders:
- 'apex-deploy'
@@ -729,6 +739,34 @@
build-step-failure-threshold: 'never'
failure-threshold: 'never'
unstable-threshold: 'FAILURE'
+ - trigger-builds:
+ - project: 'apex-deploy-baremetal-os-onos-nofeature-ha-{stream1}'
+ predefined-parameters: |
+ BUILD_DIRECTORY=apex-build-{stream1}/build
+ OPNFV_CLEAN=yes
+ git-revision: true
+ same-node: true
+ block: true
+ - trigger-builds:
+ - project: 'functest-apex-{daily-slave}-daily-{stream1}'
+ predefined-parameters:
+ DEPLOY_SCENARIO=os-onos-nofeature-ha
+ block: true
+ same-node: true
+ block-thresholds:
+ build-step-failure-threshold: 'never'
+ failure-threshold: 'never'
+ unstable-threshold: 'FAILURE'
+ - trigger-builds:
+ - project: 'yardstick-apex-{slave}-daily-{stream1}'
+ predefined-parameters:
+ DEPLOY_SCENARIO=os-onos-nofeature-ha
+ block: true
+ same-node: true
+ block-thresholds:
+ build-step-failure-threshold: 'never'
+ failure-threshold: 'never'
+ unstable-threshold: 'FAILURE'
- job-template:
name: 'apex-gs-clean-{stream}'
diff --git a/jjb/armband/armband-ci-jobs.yml b/jjb/armband/armband-ci-jobs.yml
index 7d392414f..ba02af8d6 100644
--- a/jjb/armband/armband-ci-jobs.yml
+++ b/jjb/armband/armband-ci-jobs.yml
@@ -23,6 +23,8 @@
pod:
- arm-pod1:
<<: *brahmaputra
+ - arm-pod2:
+ <<: *brahmaputra
#--------------------------------
# master
#--------------------------------
@@ -34,8 +36,14 @@
#--------------------------------
scenario:
# HA scenarios
+ - 'os-nosdn-nofeature-ha':
+ auto-trigger-name: 'daily-trigger-disabled'
- 'os-odl_l2-nofeature-ha':
auto-trigger-name: 'armband-{scenario}-{pod}-{stream}-trigger'
+ - 'os-odl_l3-nofeature-ha':
+ auto-trigger-name: 'daily-trigger-disabled'
+ - 'os-odl_l2-bgpvpn-ha':
+ auto-trigger-name: 'daily-trigger-disabled'
# NOHA scenarios
- 'os-odl_l2-nofeature-noha':
@@ -58,6 +66,7 @@
enabled: true
max-total: 1
max-per-node: 1
+ option: 'project'
- build-blocker:
use-build-blocker: true
blocking-jobs:
@@ -113,6 +122,7 @@
enabled: true
max-total: 1
max-per-node: 1
+ option: 'project'
- build-blocker:
use-build-blocker: true
blocking-jobs:
@@ -191,3 +201,10 @@
name: 'armband-os-odl_l2-nofeature-ha-arm-pod1-brahmaputra-trigger'
triggers:
- timed: '0 18 * * *'
+#---------------------------------------------------------------
+# Enea Armband POD 2 Triggers running against brahmaputra branch
+#---------------------------------------------------------------
+- trigger:
+ name: 'armband-os-odl_l2-nofeature-ha-arm-pod2-brahmaputra-trigger'
+ triggers:
+ - timed: ''
diff --git a/jjb/armband/armband-project-jobs.yml b/jjb/armband/armband-project-jobs.yml
index aa089e0d5..732a9ea4d 100644
--- a/jjb/armband/armband-project-jobs.yml
+++ b/jjb/armband/armband-project-jobs.yml
@@ -71,6 +71,7 @@
enabled: true
max-total: 1
max-per-node: 1
+ option: 'project'
parameters:
- project-parameter:
diff --git a/jjb/bottlenecks/bottlenecks-project-jobs.yml b/jjb/bottlenecks/bottlenecks-project-jobs.yml
index a28e2a407..ea000d8b9 100644
--- a/jjb/bottlenecks/bottlenecks-project-jobs.yml
+++ b/jjb/bottlenecks/bottlenecks-project-jobs.yml
@@ -114,6 +114,7 @@
enabled: true
max-total: 1
max-per-node: 1
+ option: 'project'
parameters:
- project-parameter:
diff --git a/jjb/compass4nfv/compass-ci-jobs.yml b/jjb/compass4nfv/compass-ci-jobs.yml
index 2ef25a749..52d678554 100644
--- a/jjb/compass4nfv/compass-ci-jobs.yml
+++ b/jjb/compass4nfv/compass-ci-jobs.yml
@@ -77,6 +77,7 @@
- throttle:
enabled: true
max-per-node: 1
+ option: 'project'
- build-blocker:
use-build-blocker: true
blocking-jobs:
@@ -104,6 +105,8 @@
- '{auto-trigger-name}'
builders:
+ - description-setter:
+ description: "POD: $NODE_NAME"
- trigger-builds:
- project: 'compass-deploy-{pod}-daily-{stream}'
current-parameters: true
@@ -146,6 +149,7 @@
- throttle:
enabled: true
max-per-node: 1
+ option: 'project'
- build-blocker:
use-build-blocker: true
blocking-jobs:
@@ -181,6 +185,8 @@
builders:
+ - description-setter:
+ description: "POD: $NODE_NAME"
- shell:
!include-raw-escape: ./compass-download-artifact.sh
- shell:
@@ -209,8 +215,8 @@
- choice:
name: COMPASS_OPENSTACK_VERSION
choices:
- - 'liberty'
- 'mitaka'
+ - 'liberty'
########################
# trigger macros
diff --git a/jjb/compass4nfv/compass-project-jobs.yml b/jjb/compass4nfv/compass-project-jobs.yml
index cb5b2e589..da286878e 100644
--- a/jjb/compass4nfv/compass-project-jobs.yml
+++ b/jjb/compass4nfv/compass-project-jobs.yml
@@ -43,6 +43,7 @@
- throttle:
enabled: true
max-per-node: 1
+ option: 'project'
- build-blocker:
use-build-blocker: true
blocking-jobs:
@@ -99,7 +100,7 @@
- project: 'functest-{slave-label}-suite-{stream}'
current-parameters: true
predefined-parameters:
- FUNCTEST_SUITE_NAME=vping_userdata
+ FUNCTEST_SUITE_NAME=healthcheck
same-node: true
block: true
block-thresholds:
@@ -116,6 +117,7 @@
- throttle:
enabled: true
max-per-node: 1
+ option: 'project'
- build-blocker:
use-build-blocker: true
blocking-jobs:
@@ -150,6 +152,7 @@
enabled: true
max-total: 1
max-per-node: 1
+ option: 'project'
parameters:
- project-parameter:
@@ -191,6 +194,7 @@
enabled: true
max-total: 1
max-per-node: 1
+ option: 'project'
parameters:
- project-parameter:
@@ -239,8 +243,8 @@
- choice:
name: COMPASS_OPENSTACK_VERSION
choices:
- - 'liberty'
- 'mitaka'
+ - 'liberty'
- choice:
name: COMPASS_OS_VERSION
choices:
diff --git a/jjb/cperf/cperf-ci-jobs.yml b/jjb/cperf/cperf-ci-jobs.yml
index f6a8acabb..d6c8601c6 100644
--- a/jjb/cperf/cperf-ci-jobs.yml
+++ b/jjb/cperf/cperf-ci-jobs.yml
@@ -45,6 +45,7 @@
- throttle:
enabled: true
max-per-node: 1
+ option: 'project'
wrappers:
- build-name:
diff --git a/jjb/domino/domino.yml b/jjb/domino/domino.yml
new file mode 100644
index 000000000..29e171b80
--- /dev/null
+++ b/jjb/domino/domino.yml
@@ -0,0 +1,55 @@
+- project:
+ name: domino
+
+ project: '{name}'
+
+ jobs:
+ - 'domino-verify-{stream}'
+
+ stream:
+ - master:
+ branch: '{stream}'
+ gs-pathname: ''
+
+- job-template:
+ name: 'domino-verify-{stream}'
+
+ parameters:
+ - project-parameter:
+ project: '{project}'
+ - gerrit-parameter:
+ branch: '{branch}'
+ - 'opnfv-build-ubuntu-defaults'
+
+ scm:
+ - gerrit-trigger-scm:
+ credentials-id: '{ssh-credentials}'
+ refspec: '$GERRIT_REFSPEC'
+ choosing-strategy: 'gerrit'
+
+ triggers:
+ - gerrit:
+ 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: '{project}'
+ branches:
+ - branch-compare-type: 'ANT'
+ branch-pattern: '**/{branch}'
+ forbidden-file-paths:
+ - compare-type: ANT
+ pattern: 'docs/**|.gitignore'
+
+ builders:
+ - shell: |
+ #!/bin/bash
+ ./tests/run.sh
diff --git a/jjb/fastpathmetrics/fastpathmetrics.yml b/jjb/fastpathmetrics/fastpathmetrics.yml
index db06afca4..ad1b601da 100644
--- a/jjb/fastpathmetrics/fastpathmetrics.yml
+++ b/jjb/fastpathmetrics/fastpathmetrics.yml
@@ -83,6 +83,7 @@
enabled: true
max-total: 3
max-per-node: 2
+ option: 'project'
parameters:
- project-parameter:
@@ -134,6 +135,7 @@
enabled: true
max-total: 3
max-per-node: 2
+ option: 'project'
parameters:
- project-parameter:
diff --git a/jjb/fuel/fuel-ci-jobs.yml b/jjb/fuel/fuel-ci-jobs.yml
index 8c7e72f25..de7ca6af1 100644
--- a/jjb/fuel/fuel-ci-jobs.yml
+++ b/jjb/fuel/fuel-ci-jobs.yml
@@ -86,6 +86,7 @@
enabled: true
max-total: 4
max-per-node: 1
+ option: 'project'
- build-blocker:
use-build-blocker: true
blocking-jobs:
@@ -112,6 +113,8 @@
gs-pathname: '{gs-pathname}'
builders:
+ - description-setter:
+ description: "POD: $NODE_NAME"
- trigger-builds:
- project: 'fuel-deploy-{pod}-daily-{stream}'
current-parameters: false
@@ -156,6 +159,7 @@
enabled: true
max-total: 4
max-per-node: 1
+ option: 'project'
- build-blocker:
use-build-blocker: true
blocking-jobs:
@@ -186,6 +190,8 @@
name: '$BUILD_NUMBER - Scenario: $DEPLOY_SCENARIO'
builders:
+ - description-setter:
+ description: "POD: $NODE_NAME"
- shell:
!include-raw-escape: ./fuel-download-artifact.sh
- shell:
@@ -314,7 +320,7 @@
- trigger:
name: 'fuel-os-odl_l2-nofeature-ha-zte-pod1-daily-master-trigger'
triggers:
- - timed: '0 12 * * *'
+ - timed: '15 9 * * *'
- trigger:
name: 'fuel-os-odl_l3-nofeature-ha-zte-pod1-daily-master-trigger'
triggers:
diff --git a/jjb/fuel/fuel-project-jobs.yml b/jjb/fuel/fuel-project-jobs.yml
index 4e59c01d8..67343fb1b 100644
--- a/jjb/fuel/fuel-project-jobs.yml
+++ b/jjb/fuel/fuel-project-jobs.yml
@@ -38,6 +38,7 @@
enabled: true
max-total: 1
max-per-node: 1
+ option: 'project'
parameters:
- project-parameter:
@@ -220,6 +221,7 @@
enabled: true
max-total: 2
max-per-node: 1
+ option: 'project'
- build-blocker:
use-build-blocker: true
blocking-jobs:
@@ -295,6 +297,7 @@
- throttle:
enabled: true
max-per-node: 1
+ option: 'project'
- build-blocker:
use-build-blocker: true
blocking-jobs:
diff --git a/jjb/functest/functest-ci-jobs.yml b/jjb/functest/functest-ci-jobs.yml
index 27e1ee333..f9cf01162 100644
--- a/jjb/functest/functest-ci-jobs.yml
+++ b/jjb/functest/functest-ci-jobs.yml
@@ -134,6 +134,7 @@
testsuite:
- 'daily'
+ - 'weekly'
- 'suite'
jobs:
@@ -151,6 +152,7 @@
- throttle:
enabled: true
max-per-node: 1
+ option: 'project'
wrappers:
- build-name:
@@ -182,6 +184,8 @@
branch: '{branch}'
builders:
+ - description-setter:
+ description: "POD: $NODE_NAME"
- 'functest-{testsuite}-builder'
########################
@@ -193,7 +197,14 @@
- string:
name: FUNCTEST_SUITE_NAME
default: 'daily'
- description: "Suite name to run"
+ description: "Daily suite name to run"
+- parameter:
+ name: functest-weekly-parameter
+ parameters:
+ - string:
+ name: FUNCTEST_SUITE_NAME
+ default: 'weekly'
+ description: "Weekly suite name to run"
- parameter:
name: functest-suite-parameter
parameters:
@@ -201,16 +212,19 @@
name: FUNCTEST_SUITE_NAME
choices:
- 'healthcheck'
- - 'tempest'
- - 'rally'
+ - 'vping_userdata'
+ - 'vping_ssh'
+ - 'tempest_smoke_serial'
+ - 'rally_sanity'
- 'odl'
- 'onos'
- - 'ovno'
- 'promise'
- 'doctor'
+ - 'bgpvpn'
+ - 'security_scan'
+ - 'tempest_full_parallel'
+ - 'rally_full'
- 'vims'
- - 'vping_userdata'
- - 'vping_ssh'
- parameter:
name: functest-parameter
parameters:
@@ -250,6 +264,14 @@
- 'functest-store-results'
- builder:
+ name: functest-weekly-builder
+ builders:
+ - 'functest-cleanup'
+ - 'set-functest-env'
+ - 'functest-weekly'
+ - 'functest-store-results'
+
+- builder:
name: functest-suite-builder
builders:
- 'functest-cleanup'
@@ -257,16 +279,22 @@
- 'functest-suite'
- builder:
- name: functest-suite
+ name: functest-daily
builders:
- shell:
- !include-raw: ./functest-suite.sh
+ !include-raw: ./functest-loop.sh
- builder:
- name: functest-daily
+ name: functest-weekly
builders:
- shell:
- !include-raw: ./functest-daily.sh
+ !include-raw: ./functest-loop.sh
+
+- builder:
+ name: functest-suite
+ builders:
+ - shell:
+ !include-raw: ./functest-suite.sh
- builder:
name: set-functest-env
diff --git a/jjb/functest/functest-daily.sh b/jjb/functest/functest-loop.sh
index 5abddfd84..5abddfd84 100755
--- a/jjb/functest/functest-daily.sh
+++ b/jjb/functest/functest-loop.sh
diff --git a/jjb/functest/set-functest-env.sh b/jjb/functest/set-functest-env.sh
index 0b8747a6f..d2e232de5 100755
--- a/jjb/functest/set-functest-env.sh
+++ b/jjb/functest/set-functest-env.sh
@@ -27,6 +27,7 @@ if [[ ${INSTALLER_TYPE} == 'apex' ]]; then
if sudo iptables -C FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable 2> ${redirect}; then
sudo iptables -D FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable
fi
+
elif [[ ${INSTALLER_TYPE} == 'joid' ]]; then
# If production lab then creds may be retrieved dynamically
# creds are on the jumphost, always in the same folder
@@ -34,6 +35,12 @@ elif [[ ${INSTALLER_TYPE} == 'joid' ]]; then
# If dev lab, credentials may not be the default ones, just provide a path to put them into docker
# replace the default one by the customized one provided by jenkins config
fi
+
+# Set iptables rule to allow forwarding return traffic for container
+if ! sudo iptables -C FORWARD -j RETURN 2> ${redirect} || ! sudo iptables -L FORWARD | awk 'NR==3' | grep RETURN 2> ${redirect}; then
+ sudo iptables -I FORWARD -j RETURN
+fi
+
echo "Functest: Start Docker and prepare environment"
envs="-e INSTALLER_TYPE=${INSTALLER_TYPE} -e INSTALLER_IP=${INSTALLER_IP} \
-e NODE_NAME=${NODE_NAME} -e DEPLOY_SCENARIO=${DEPLOY_SCENARIO} \
diff --git a/jjb/joid/joid-ci-jobs.yml b/jjb/joid/joid-ci-jobs.yml
index f6f12298a..a1e56770b 100644
--- a/jjb/joid/joid-ci-jobs.yml
+++ b/jjb/joid/joid-ci-jobs.yml
@@ -91,6 +91,7 @@
enabled: true
max-total: 4
max-per-node: 1
+ option: 'project'
- build-blocker:
use-build-blocker: true
blocking-jobs:
@@ -115,6 +116,8 @@
default: '{scenario}'
builders:
+ - description-setter:
+ description: "POD: $NODE_NAME"
- trigger-builds:
- project: 'joid-deploy-{pod}-daily-{stream}'
current-parameters: true
@@ -123,18 +126,18 @@
same-node: true
block: true
- trigger-builds:
- - project: 'functest-joid-{pod}-daily-{stream}'
+ - project: 'yardstick-joid-{pod}-daily-{stream}'
current-parameters: false
predefined-parameters:
DEPLOY_SCENARIO={scenario}
- same-node: true
block: true
+ same-node: true
block-thresholds:
build-step-failure-threshold: 'never'
failure-threshold: 'never'
unstable-threshold: 'FAILURE'
- trigger-builds:
- - project: 'yardstick-joid-{pod}-daily-{stream}'
+ - project: 'functest-joid-{pod}-daily-{stream}'
current-parameters: false
predefined-parameters:
DEPLOY_SCENARIO={scenario}
@@ -155,6 +158,7 @@
enabled: true
max-total: 4
max-per-node: 1
+ option: 'project'
- build-blocker:
use-build-blocker: true
blocking-jobs:
@@ -185,6 +189,8 @@
branch: '{branch}'
builders:
+ - description-setter:
+ description: "POD: $NODE_NAME"
- 'builder-macro'
########################
# builder macros
diff --git a/jjb/moon/moon-verify.sh b/jjb/moon/moon-verify.sh
new file mode 100755
index 000000000..23bf47c06
--- /dev/null
+++ b/jjb/moon/moon-verify.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+echo "Hello World"
diff --git a/jjb/moon/moon.yml b/jjb/moon/moon.yml
new file mode 100644
index 000000000..0044eb9ec
--- /dev/null
+++ b/jjb/moon/moon.yml
@@ -0,0 +1,54 @@
+- project:
+ name: moon
+
+ project: '{name}'
+
+ jobs:
+ - 'moon-verify-{stream}'
+
+ stream:
+ - master:
+ branch: '{stream}'
+ gs-pathname: ''
+
+- job-template:
+ name: 'moon-verify-{stream}'
+
+ parameters:
+ - project-parameter:
+ project: '{project}'
+ - gerrit-parameter:
+ branch: '{branch}'
+ - 'opnfv-build-ubuntu-defaults'
+
+ scm:
+ - gerrit-trigger-scm:
+ credentials-id: '{ssh-credentials}'
+ refspec: '$GERRIT_REFSPEC'
+ choosing-strategy: 'gerrit'
+
+ triggers:
+ - gerrit:
+ 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: '{project}'
+ branches:
+ - branch-compare-type: 'ANT'
+ branch-pattern: '**/{branch}'
+ forbidden-file-paths:
+ - compare-type: ANT
+ pattern: 'docs/**|.gitignore'
+
+ builders:
+ - shell:
+ !include-raw: ./moon-verify.sh
diff --git a/jjb/opnfv/artifact-cleanup.yml b/jjb/opnfv/artifact-cleanup.yml
new file mode 100644
index 000000000..b0f819145
--- /dev/null
+++ b/jjb/opnfv/artifact-cleanup.yml
@@ -0,0 +1,42 @@
+- project:
+ name: artifact-cleanup
+
+ project: 'releng'
+
+ jobs:
+ - 'artifact-cleanup-daily-{stream}'
+
+ stream:
+ - master:
+ branch: '{stream}'
+ gs-pathname: ''
+
+
+- job-template:
+ name: 'artifact-cleanup-daily-{stream}'
+
+ # Job template for daily builders
+ #
+ # Required Variables:
+ # stream: branch with - in place of / (eg. stable)
+ # branch: branch (eg. stable)
+ node: master
+
+ disabled: false
+
+ parameters:
+ - project-parameter:
+ project: '{project}'
+
+ scm:
+ - git-scm:
+ credentials-id: '{ssh-credentials}'
+ refspec: ''
+ branch: '{branch}'
+
+ triggers:
+ - timed: 'H H * * *'
+
+ builders:
+ - shell: |
+ $WORKSPACE/utils/retention_script.sh
diff --git a/jjb/opnfv/installer-params.yml b/jjb/opnfv/installer-params.yml
index f95d79f93..60fee9263 100644
--- a/jjb/opnfv/installer-params.yml
+++ b/jjb/opnfv/installer-params.yml
@@ -93,3 +93,19 @@
name: CPU_ARCHITECTURE
default: 'amd64'
description: "CPU Architecture to use for Ubuntu distro "
+
+- parameter:
+ name: 'sandbox-defaults'
+ parameters:
+ - string:
+ name: INSTALLER_IP
+ default: '10.20.0.2'
+ description: 'IP of the installer'
+ - string:
+ name: INSTALLER_TYPE
+ default: sandbox
+ description: 'Installer used for deploying OPNFV on this POD'
+ - string:
+ name: EXTERNAL_NETWORK
+ default: 'admin_floating_net'
+ description: 'external network for test'
diff --git a/jjb/opnfv/slave-params.yml b/jjb/opnfv/slave-params.yml
index da0808b76..e5313c801 100644
--- a/jjb/opnfv/slave-params.yml
+++ b/jjb/opnfv/slave-params.yml
@@ -621,6 +621,34 @@
name: LAB_CONFIG_URL
default: ssh://git@git.enea.com/pharos/lab-config
description: 'Base URI to the configuration directory'
+
+- parameter:
+ name: 'arm-pod2-defaults'
+ parameters:
+ - node:
+ name: SLAVE_NAME
+ description: 'Slave name on Jenkins'
+ allowed-slaves:
+ - arm-pod2
+ default-slaves:
+ - arm-pod2
+ - string:
+ name: GIT_BASE
+ default: https://gerrit.opnfv.org/gerrit/$PROJECT
+ description: 'Git URL to use on this Jenkins Slave'
+ - string:
+ name: DEFAULT_BRIDGE
+ default: 'admin_br0,public_br0'
+ desciption: 'The bridge to use for Fuel PXE booting. It can be a comma sparated list of bridges, in which case the first is the PXE boot bridge, and all subsequent interfaces that will be added to the VM. If left empty, most deploy scripts will default to pxebr.'
+ - string:
+ name: DEPLOY_TIMEOUT
+ default: '360'
+ description: 'Deployment timeout in minutes'
+ - string:
+ name: LAB_CONFIG_URL
+ default: ssh://git@git.enea.com/pharos/lab-config
+ description: 'Base URI to the configuration directory'
+
- parameter:
name: 'opnfv-build-centos-defaults'
parameters:
diff --git a/jjb/opnfv/test-sign.yml b/jjb/opnfv/test-sign.yml
new file mode 100644
index 000000000..b27d75777
--- /dev/null
+++ b/jjb/opnfv/test-sign.yml
@@ -0,0 +1,42 @@
+- project:
+ name: test-sign
+
+ project: 'releng'
+
+ jobs:
+ - 'test-sign-daily-{stream}'
+
+ stream:
+ - master:
+ branch: '{stream}'
+ gs-pathname: ''
+
+
+- job-template:
+ name: 'test-sign-daily-{stream}'
+
+ # Job template for daily builders
+ #
+ # Required Variables:
+ # stream: branch with - in place of / (eg. stable)
+ # branch: branch (eg. stable)
+ node: master
+
+ disabled: false
+
+ parameters:
+ - project-parameter:
+ project: '{project}'
+
+ scm:
+ - git-scm:
+ credentials-id: '{ssh-credentials}'
+ refspec: ''
+ branch: '{branch}'
+
+ triggers:
+ - timed: 'H H * * *'
+
+ builders:
+ - shell: |
+ $WORKSPACE/utils/test-sign-artifact.sh
diff --git a/jjb/sandbox/sandbox-verify-jobs.yml b/jjb/sandbox/sandbox-verify-jobs.yml
new file mode 100644
index 000000000..b1e8e93cd
--- /dev/null
+++ b/jjb/sandbox/sandbox-verify-jobs.yml
@@ -0,0 +1,280 @@
+- project:
+ name: 'sandbox-verify-jobs'
+
+ project: 'sandbox'
+
+ installer: 'sandbox'
+
+ stream:
+ - master:
+ branch: '{stream}'
+ gs-pathname: ''
+
+# what are the verification activities we do for this installer
+ activity:
+ - 'basic'
+ - 'build'
+ - 'deploy'
+ - 'test'
+
+ jobs:
+ - 'sandbox-verify-{stream}'
+ - 'sandbox-verify-{activity}-{stream}'
+
+- job-template:
+ name: 'sandbox-verify-{stream}'
+
+ parameters:
+ - project-parameter:
+ project: '{project}'
+ - gerrit-parameter:
+ branch: '{branch}'
+ - 'opnfv-build-ubuntu-defaults'
+
+ wrappers:
+ - ssh-agent-credentials:
+ users:
+ - '{ssh-credentials}'
+ - timeout:
+ timeout: 360
+ fail: true
+
+ triggers:
+ - gerrit:
+ 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: '{project}'
+ branches:
+ - branch-compare-type: 'ANT'
+ branch-pattern: '**/{branch}'
+ forbidden-file-paths:
+ - compare-type: ANT
+ pattern: 'docs/**|.gitignore'
+ readable-message: true
+
+ builders:
+ - description-setter:
+ description: "POD: $NODE_NAME"
+ - '{project}-verify-builder'
+ - trigger-builds:
+ - project: 'sandbox-verify-basic-{stream}'
+ block: true
+ - trigger-builds:
+ - project: 'sandbox-verify-build-{stream}'
+ block: true
+ - trigger-builds:
+ - project: 'sandbox-verify-deploy-{stream}'
+ block: true
+ - trigger-builds:
+ - project: 'sandbox-verify-test-{stream}'
+ block: true
+
+- job-template:
+ name: 'sandbox-verify-{activity}-{stream}'
+
+ scm:
+ - gerrit-trigger-scm:
+ credentials-id: '{ssh-credentials}'
+ refspec: '$GERRIT_REFSPEC'
+ choosing-strategy: 'gerrit'
+
+ wrappers:
+ - ssh-agent-credentials:
+ users:
+ - '{ssh-credentials}'
+ - timeout:
+ timeout: 360
+ fail: true
+
+ parameters:
+ - project-parameter:
+ project: '{project}'
+ - gerrit-parameter:
+ branch: '{branch}'
+ - '{installer}-defaults'
+ - '{project}-verify-{activity}-parameter'
+
+ builders:
+ - description-setter:
+ description: "POD: $NODE_NAME"
+ - '{project}-verify-{activity}-builder'
+
+#####################################
+# parameter builders
+#####################################
+- parameter:
+ name: 'sandbox-verify-basic-parameter'
+ parameters:
+ - 'opnfv-build-ubuntu-defaults'
+
+- parameter:
+ name: 'sandbox-verify-build-parameter'
+ parameters:
+ - 'opnfv-build-ubuntu-defaults'
+
+- parameter:
+ name: 'sandbox-verify-deploy-parameter'
+ parameters:
+ - 'opnfv-build-centos-defaults'
+
+- parameter:
+ name: 'sandbox-verify-test-parameter'
+ parameters:
+ - 'opnfv-build-centos-defaults'
+#####################################
+# builder builders
+#####################################
+- builder:
+ name: 'sandbox-verify-builder'
+ builders:
+ - shell: |
+ #!/bin/bash
+
+ # this is the builder for the parent/upstream job which we do nothing
+ cd $WORKSPACE
+ echo
+ echo "Commit Message is"
+ echo "-------------------------------------"
+ echo $GERRIT_CHANGE_COMMIT_MESSAGE
+ echo "-------------------------------------"
+ echo
+ echo "Repo contents"
+ echo "-------------------------------------"
+ ls -al
+ echo "-------------------------------------"
+ echo
+ echo "Changed files are"
+ echo "-------------------------------------"
+ git diff origin/master --name-only
+ echo "-------------------------------------"
+ echo
+ echo "Change introduced"
+ echo "-------------------------------------"
+ git diff origin/master
+ echo "-------------------------------------"
+
+- builder:
+ name: 'sandbox-verify-basic-builder'
+ builders:
+ - shell: |
+ #!/bin/bash
+
+ # this is where we check the commit message, unit test, etc.
+ cd $WORKSPACE
+ echo
+ echo "Commit Message is"
+ echo "-------------------------------------"
+ echo $GERRIT_CHANGE_COMMIT_MESSAGE
+ echo "-------------------------------------"
+ echo
+ echo "Repo contents"
+ echo "-------------------------------------"
+ ls -al
+ echo "-------------------------------------"
+ echo
+ echo "Changed files are"
+ echo "-------------------------------------"
+ git diff origin/master --name-only
+ echo "-------------------------------------"
+ echo
+ echo "Change introduced"
+ echo "-------------------------------------"
+ git diff origin/master
+ echo "-------------------------------------"
+
+- builder:
+ name: 'sandbox-verify-build-builder'
+ builders:
+ - shell: |
+ #!/bin/bash
+
+ # this is where we do the build
+ cd $WORKSPACE
+ echo
+ echo "Commit Message is"
+ echo "-------------------------------------"
+ echo $GERRIT_CHANGE_COMMIT_MESSAGE
+ echo "-------------------------------------"
+ echo
+ echo "Repo contents"
+ echo "-------------------------------------"
+ ls -al
+ echo "-------------------------------------"
+ echo
+ echo "Changed files are"
+ echo "-------------------------------------"
+ git diff origin/master --name-only
+ echo "-------------------------------------"
+ echo
+ echo "Change introduced"
+ echo "-------------------------------------"
+ git diff origin/master
+ echo "-------------------------------------"
+
+- builder:
+ name: 'sandbox-verify-deploy-builder'
+ builders:
+ - shell: |
+ #!/bin/bash
+
+ # this is where we start the virtual deployment
+ cd $WORKSPACE
+ echo
+ echo "Commit Message is"
+ echo "-------------------------------------"
+ echo $GERRIT_CHANGE_COMMIT_MESSAGE
+ echo "-------------------------------------"
+ echo
+ echo "Repo contents"
+ echo "-------------------------------------"
+ ls -al
+ echo "-------------------------------------"
+ echo
+ echo "Changed files are"
+ echo "-------------------------------------"
+ git diff origin/master --name-only
+ echo "-------------------------------------"
+ echo
+ echo "Change introduced"
+ echo "-------------------------------------"
+ git diff origin/master
+ echo "-------------------------------------"
+
+- builder:
+ name: 'sandbox-verify-test-builder'
+ builders:
+ - shell: |
+ #!/bin/bash
+
+ # this is where we do functest smoketest
+ cd $WORKSPACE
+ echo
+ echo "Commit Message is"
+ echo "-------------------------------------"
+ echo $GERRIT_CHANGE_COMMIT_MESSAGE
+ echo "-------------------------------------"
+ echo
+ echo "Repo contents"
+ echo "-------------------------------------"
+ ls -al
+ echo "-------------------------------------"
+ echo
+ echo "Changed files are"
+ echo "-------------------------------------"
+ git diff origin/master --name-only
+ echo "-------------------------------------"
+ echo
+ echo "Change introduced"
+ echo "-------------------------------------"
+ git diff origin/master
+ echo "-------------------------------------"
diff --git a/jjb/vswitchperf/vswitchperf.yml b/jjb/vswitchperf/vswitchperf.yml
index 0cf7f9786..bf2fe8faa 100644
--- a/jjb/vswitchperf/vswitchperf.yml
+++ b/jjb/vswitchperf/vswitchperf.yml
@@ -59,6 +59,7 @@
enabled: true
max-total: 3
max-per-node: 2
+ option: 'project'
parameters:
- project-parameter:
@@ -116,6 +117,7 @@
enabled: true
max-total: 3
max-per-node: 2
+ option: 'project'
parameters:
- project-parameter:
diff --git a/jjb/yardstick/yardstick-ci-jobs.yml b/jjb/yardstick/yardstick-ci-jobs.yml
index 48c335a03..8b8ced1ba 100644
--- a/jjb/yardstick/yardstick-ci-jobs.yml
+++ b/jjb/yardstick/yardstick-ci-jobs.yml
@@ -170,6 +170,7 @@
- throttle:
enabled: true
max-per-node: 1
+ option: 'project'
wrappers:
- build-name:
@@ -210,6 +211,8 @@
branch: '{branch}'
builders:
+ - description-setter:
+ description: "POD: $NODE_NAME"
- 'yardstick-cleanup'
#- 'yardstick-fetch-os-creds'
- 'yardstick-{testsuite}'
diff --git a/utils/gpg_import_key.sh b/utils/gpg_import_key.sh
new file mode 100644
index 000000000..3afeda839
--- /dev/null
+++ b/utils/gpg_import_key.sh
@@ -0,0 +1,42 @@
+#!/bin/bash -e
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2016 NEC and others.
+# 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
+##############################################################################
+
+function isinstalled {
+if rpm -q "$@" >/dev/null 2>&1; then
+ true
+ else
+ echo installing "$1"
+ sudo yum install "$1"
+ false
+fi
+}
+
+if ! isinstalled gnupg2; then
+ echo "error with install"
+ exit 1
+fi
+
+if ! which gsutil;
+ then echo "error gsutil not installed";
+ exit 1
+fi
+
+if gpg2 --list-keys | grep "opnfv-helpdesk@rt.linuxfoundation.org"; then
+ echo "Key Already available"
+else
+ if [ -z "$NODE_NAME" ];
+ then echo "Cannot find node name"
+ exit 1
+ else echo "Importing key for '$NODE_NAME'";
+ gsutil cp gs://opnfv-signing-keys/"$NODE_NAME"-subkey .
+ gpg2 --import "$NODE_NAME"-subkey
+ rm -f "$NODE_NAME"-subkey
+ fi
+fi
diff --git a/utils/push-test-logs.sh b/utils/push-test-logs.sh
index 745645041..964b41908 100644
--- a/utils/push-test-logs.sh
+++ b/utils/push-test-logs.sh
@@ -17,13 +17,13 @@ res_build_date=${1:-$(date -u +"%Y-%m-%d_%H-%M-%S")}
project=$PROJECT
branch=${GIT_BRANCH##*/}
testbed=$NODE_NAME
-dir_result="${HOME}/opnfv/$project/results"
+dir_result="${HOME}/opnfv/$project/results/${branch}"
# src: https://wiki.opnfv.org/display/INF/Hardware+Infrastructure
# + intel-pod3 (vsperf)
node_list=(\
'lf-pod1' 'lf-pod2' 'intel-pod2' 'intel-pod3' \
'intel-pod5' 'intel-pod6' 'intel-pod7' 'intel-pod8' \
-'ericsson-pod2' 'huawei-pod1')
+'ericsson-pod2' 'huawei-pod1' 'huawei-pod2' 'huawei-virtual1' 'huawei-virtual2' 'huawei-virtual3' 'huawei-virtual4')
if [[ ! " ${node_list[@]} " =~ " ${testbed} " ]]; then
echo "This is not a CI POD. Aborting pushing the logs to artifacts."
diff --git a/utils/retention_script.sh b/utils/retention_script.sh
new file mode 100644
index 000000000..9a8986ca5
--- /dev/null
+++ b/utils/retention_script.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2016 The Linux Foundation and others
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##############################################################################
+
+#These are the only projects that generate artifacts
+for x in armband ovsnfv fuel apex compass4nfv
+do
+
+ echo "Looking at artifacts for project $x"
+
+ while IFS= read -r artifact; do
+
+ artifact_date="$(gsutil ls -L $artifact | grep "Creation time:" | awk '{print $4,$5,$6}')"
+ age=$(($(date +%s)-$(date -d"$artifact_date" +%s)))
+ daysold=$(($age/86400))
+
+ if [[ "$daysold" -gt "10" ]]; then
+ echo "$daysold Days old Deleting: $(basename $artifact)"
+ else
+ echo "$daysold Days old Retaining: $(basename $artifact)"
+ fi
+
+ done < <(gsutil ls gs://artifacts.opnfv.org/"$x" |grep -v "/$")
+done
diff --git a/utils/test-sign-artifact.sh b/utils/test-sign-artifact.sh
new file mode 100755
index 000000000..f09b7f4e2
--- /dev/null
+++ b/utils/test-sign-artifact.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+export PATH=$PATH:/usr/local/bin/
+
+# clone releng repository
+echo "Cloning releng repository..."
+[ -d releng ] && rm -rf releng
+git clone https://gerrit.opnfv.org/gerrit/releng $WORKSPACE/releng/ &> /dev/null
+#this is where we import the siging key
+if [ -f $WORKSPACE/releng/utils/gpg_import_key.sh ]; then
+ source $WORKSPACE/releng/utils/gpg_import_key.sh
+fi
+
+artifact="foo"
+echo foo > foo
+
+testsign () {
+ echo "Signing artifact: ${artifact}"
+ gpg2 -vvv --batch \
+ --default-key opnfv-helpdesk@rt.linuxfoundation.org \
+ --passphrase besteffort \
+ --detach-sig $artifact
+}
+
+testsign
+
diff --git a/utils/test/reporting/functest/reporting-status.py b/utils/test/reporting/functest/reporting-status.py
index 2ce5efbd0..622c375cc 100644
--- a/utils/test/reporting/functest/reporting-status.py
+++ b/utils/test/reporting/functest/reporting-status.py
@@ -8,7 +8,6 @@
#
import datetime
import jinja2
-import os
import requests
import sys
import time
@@ -19,7 +18,11 @@ import reportingConf as conf
import testCase as tc
import scenarioResult as sr
-testCases4Validation = []
+# Logger
+logger = utils.getLogger("Status")
+
+# Initialization
+testValid = []
otherTestCases = []
# init just tempest to get the list of scenarios
@@ -28,16 +31,16 @@ tempest = tc.TestCase("tempest_smoke_serial", "functest", -1)
# Retrieve the Functest configuration to detect which tests are relevant
# according to the installer, scenario
-# cf = "https://git.opnfv.org/cgit/functest/plain/ci/config_functest.yaml"
-cf = "https://git.opnfv.org/cgit/functest/plain/ci/testcases.yaml"
+cf = conf.TEST_CONF
response = requests.get(cf)
+
functest_yaml_config = yaml.load(response.text)
-print "****************************************"
-print "* Generating reporting..... *"
-print ("* Data retention = %s days *" % conf.PERIOD)
-print "* *"
-print "****************************************"
+logger.info("*******************************************")
+logger.info("* Generating reporting scenario status *")
+logger.info("* Data retention = %s days *" % conf.PERIOD)
+logger.info("* *")
+logger.info("*******************************************")
# Retrieve test cases of Tier 1 (smoke)
config_tiers = functest_yaml_config.get("tiers")
@@ -50,19 +53,22 @@ config_tiers = functest_yaml_config.get("tiers")
for tier in config_tiers:
if tier['order'] > 0 and tier['order'] < 3:
for case in tier['testcases']:
- testCases4Validation.append(tc.TestCase(case['name'],
- "functest",
- case['dependencies']))
+ if case['name'] not in conf.blacklist:
+ testValid.append(tc.TestCase(case['name'],
+ "functest",
+ case['dependencies']))
elif tier['order'] == 3:
for case in tier['testcases']:
- testCases4Validation.append(tc.TestCase(case['name'],
- case['name'],
- case['dependencies']))
+ if case['name'] not in conf.blacklist:
+ testValid.append(tc.TestCase(case['name'],
+ case['name'],
+ case['dependencies']))
elif tier['order'] > 3:
for case in tier['testcases']:
- otherTestCases.append(tc.TestCase(case['name'],
- "functest",
- case['dependencies']))
+ if case['name'] not in conf.blacklist:
+ otherTestCases.append(tc.TestCase(case['name'],
+ "functest",
+ case['dependencies']))
# For all the versions
for version in conf.versions:
@@ -84,27 +90,32 @@ for version in conf.versions:
# Check if test case is runnable / installer, scenario
# for the test case used for Scenario validation
try:
- print ("---------------------------------")
- print ("installer %s, version %s, scenario %s:" %
- (installer, version, s))
+ logger.info("---------------------------------")
+ logger.info("installer %s, version %s, scenario %s:" %
+ (installer, version, s))
# 1) Manage the test cases for the scenario validation
# concretely Tiers 0-3
- for test_case in testCases4Validation:
+ for test_case in testValid:
test_case.checkRunnable(installer, s,
test_case.getConstraints())
- print ("testcase %s is %s" % (test_case.getName(),
- test_case.isRunnable))
+ logger.debug("testcase %s is %s" %
+ (test_case.getDisplayName(),
+ test_case.isRunnable))
time.sleep(1)
if test_case.isRunnable:
dbName = test_case.getDbName()
name = test_case.getName()
+ displayName = test_case.getDisplayName()
project = test_case.getProject()
nb_test_runnable_for_this_scenario += 1
- print (" Searching results for case %s " %
- (dbName))
+ logger.info(" Searching results for case %s " %
+ (displayName))
result = utils.getResult(dbName, installer, s, version)
- print " >>>> Test result=" + str(result)
+ # if no result set the value to 0
+ if result < 0:
+ result = 0
+ logger.info(" >>>> Test score = " + str(result))
test_case.setCriteria(result)
test_case.setIsRunnable(True)
testCases2BeDisplayed.append(tc.TestCase(name,
@@ -120,30 +131,35 @@ for version in conf.versions:
for test_case in otherTestCases:
test_case.checkRunnable(installer, s,
test_case.getConstraints())
- print ("testcase %s is %s" % (test_case.getName(),
- test_case.isRunnable))
+ logger.info("testcase %s is %s" %
+ (test_case.getName(), test_case.isRunnable))
time.sleep(1)
if test_case.isRunnable:
dbName = test_case.getDbName()
name = test_case.getName()
+ displayName = test_case.getDisplayName()
project = test_case.getProject()
- print (" Searching results for case %s " %
- (dbName))
+ logger.info(" Searching results for case %s " %
+ (displayName))
result = utils.getResult(dbName, installer, s, version)
- test_case.setCriteria(result)
- test_case.setIsRunnable(True)
- testCases2BeDisplayed.append(tc.TestCase(name,
- project,
- "",
- result,
- True,
- 4))
+ # at least 1 result for the test
+ if result > -1:
+ test_case.setCriteria(result)
+ test_case.setIsRunnable(True)
+ testCases2BeDisplayed.append(tc.TestCase(name,
+ project,
+ "",
+ result,
+ True,
+ 4))
+ else:
+ logger.debug("No results found")
items[s] = testCases2BeDisplayed
except:
- print ("Error: installer %s, version %s, scenario %s" %
- (installer, version, s))
- print "No data available , error %s " % (sys.exc_info()[0])
+ logger.error("Error: installer %s, version %s, scenario %s" %
+ (installer, version, s))
+ logger.error("No data available: %s " % (sys.exc_info()[0]))
# **********************************************
# Evaluate the results for scenario validation
@@ -158,13 +174,13 @@ for version in conf.versions:
s_score = str(scenario_score) + "/" + str(scenario_criteria)
s_status = "KO"
if scenario_score < scenario_criteria:
- print (">>>> scenario not OK, score = %s/%s" %
- (scenario_score, scenario_criteria))
+ logger.info(">>>> scenario not OK, score = %s/%s" %
+ (scenario_score, scenario_criteria))
s_status = "KO"
else:
- print ">>>>> scenario OK, save the information"
+ logger.info(">>>>> scenario OK, save the information")
s_status = "OK"
- path_validation_file = ("./release/" + version +
+ path_validation_file = (conf.REPORTING_PATH + "/release/" + version +
"/validated_scenario_history.txt")
with open(path_validation_file, "a") as f:
time_format = "%Y-%m-%d %H:%M"
@@ -173,14 +189,12 @@ for version in conf.versions:
f.write(info)
scenario_result_criteria[s] = sr.ScenarioResult(s_status, s_score)
- print "--------------------------"
+ logger.info("--------------------------")
- templateLoader = jinja2.FileSystemLoader(os.path.dirname
- (os.path.abspath
- (__file__)))
+ templateLoader = jinja2.FileSystemLoader(conf.REPORTING_PATH)
templateEnv = jinja2.Environment(loader=templateLoader)
- TEMPLATE_FILE = "./template/index-status-tmpl.html"
+ TEMPLATE_FILE = "/template/index-status-tmpl.html"
template = templateEnv.get_template(TEMPLATE_FILE)
outputText = template.render(scenario_stats=scenario_stats,
@@ -190,6 +204,6 @@ for version in conf.versions:
period=conf.PERIOD,
version=version)
- with open("./release/" + version +
+ with open(conf.REPORTING_PATH + "/release/" + version +
"/index-status-" + installer + ".html", "wb") as fh:
fh.write(outputText)
diff --git a/utils/test/reporting/functest/reporting-tempest.py b/utils/test/reporting/functest/reporting-tempest.py
index a065ef442..e3f4e3306 100644
--- a/utils/test/reporting/functest/reporting-tempest.py
+++ b/utils/test/reporting/functest/reporting-tempest.py
@@ -1,28 +1,44 @@
from urllib2 import Request, urlopen, URLError
import json
import jinja2
-import os
+import reportingConf as conf
+import reportingUtils as utils
-installers = ["apex", "compass", "fuel", "joid"]
+installers = conf.installers
items = ["tests", "Success rate", "duration"]
-PERIOD = 7
-print "Generate Tempest automatic reporting"
+PERIOD = conf.PERIOD
+criteria_nb_test = 165
+criteria_duration = 1800
+criteria_success_rate = 90
+
+logger = utils.getLogger("Tempest")
+logger.info("************************************************")
+logger.info("* Generating reporting Tempest_smoke_serial *")
+logger.info("* Data retention = %s days *" % PERIOD)
+logger.info("* *")
+logger.info("************************************************")
+
+logger.info("Success criteria:")
+logger.info("nb tests executed > %s s " % criteria_nb_test)
+logger.info("test duration < %s s " % criteria_duration)
+logger.info("success rate > %s " % criteria_success_rate)
+
for installer in installers:
# we consider the Tempest results of the last PERIOD days
- url = "http://testresults.opnfv.org/test/api/v1/results?case=tempest_smoke_serial"
- request = Request(url + '&period=' + str(PERIOD)
- + '&installer=' + installer + '&version=master')
-
+ url = conf.URL_BASE + "?case=tempest_smoke_serial"
+ request = Request(url + '&period=' + str(PERIOD) +
+ '&installer=' + installer + '&version=master')
+ logger.info("Search tempest_smoke_serial results for installer %s"
+ % installer)
try:
response = urlopen(request)
k = response.read()
results = json.loads(k)
except URLError, e:
- print 'No kittez. Got an error code:', e
+ logger.error("Error code: %s" % e)
test_results = results['results']
- test_results.reverse()
scenario_results = {}
criteria = {}
@@ -48,8 +64,8 @@ for installer in installers:
nb_tests_run = result['details']['tests']
nb_tests_failed = result['details']['failures']
if nb_tests_run != 0:
- success_rate = 100*(int(nb_tests_run)
- - int(nb_tests_failed))/int(nb_tests_run)
+ success_rate = 100*(int(nb_tests_run) -
+ int(nb_tests_failed)) / int(nb_tests_run)
else:
success_rate = 0
@@ -63,40 +79,49 @@ for installer in installers:
crit_time = False
# Expect that at least 165 tests are run
- if nb_tests_run >= 165:
+ if nb_tests_run >= criteria_nb_test:
crit_tests = True
# Expect that at least 90% of success
- if success_rate >= 90:
+ if success_rate >= criteria_success_rate:
crit_rate = True
# Expect that the suite duration is inferior to 30m
- if result['details']['duration'] < 1800:
+ if result['details']['duration'] < criteria_duration:
crit_time = True
result['criteria'] = {'tests': crit_tests,
'Success rate': crit_rate,
'duration': crit_time}
- # error management
+ try:
+ logger.debug("Scenario %s, Installer %s"
+ % (s_result[1]['scenario'], installer))
+ logger.debug("Nb Test run: %s" % nb_tests_run)
+ logger.debug("Test duration: %s"
+ % result['details']['duration'])
+ logger.debug("Success rate: %s" % success_rate)
+ except:
+ logger.error("Data format error")
+
+ # Error management
# ****************
try:
errors = result['details']['errors']
result['errors'] = errors.replace('{0}', '')
except:
- print "Error field not present (Brahamputra runs?)"
+ logger.error("Error field not present (Brahamputra runs?)")
- mypath = os.path.abspath(__file__)
- tplLoader = jinja2.FileSystemLoader(os.path.dirname(mypath))
- templateEnv = jinja2.Environment(loader=tplLoader)
+ templateLoader = jinja2.FileSystemLoader(conf.REPORTING_PATH)
+ templateEnv = jinja2.Environment(loader=templateLoader)
- TEMPLATE_FILE = "./template/index-tempest-tmpl.html"
+ TEMPLATE_FILE = "/template/index-tempest-tmpl.html"
template = templateEnv.get_template(TEMPLATE_FILE)
outputText = template.render(scenario_results=scenario_results,
items=items,
installer=installer)
- with open("./release/master/index-tempest-" +
+ with open(conf.REPORTING_PATH + "/release/master/index-tempest-" +
installer + ".html", "wb") as fh:
fh.write(outputText)
-print "Tempest automatic reporting Done"
+logger.info("Tempest automatic reporting succesfully generated.")
diff --git a/utils/test/reporting/functest/reporting-vims.py b/utils/test/reporting/functest/reporting-vims.py
index 4033687e8..d0436ed14 100644
--- a/utils/test/reporting/functest/reporting-vims.py
+++ b/utils/test/reporting/functest/reporting-vims.py
@@ -1,7 +1,11 @@
from urllib2 import Request, urlopen, URLError
import json
import jinja2
-import os
+import reportingConf as conf
+import reportingUtils as utils
+
+logger = utils.getLogger("vIMS")
+
def sig_test_format(sig_test):
nbPassed = 0
@@ -9,7 +13,7 @@ def sig_test_format(sig_test):
nbSkipped = 0
for data_test in sig_test:
if data_test['result'] == "Passed":
- nbPassed+= 1
+ nbPassed += 1
elif data_test['result'] == "Failed":
nbFailures += 1
elif data_test['result'] == "Skipped":
@@ -20,21 +24,29 @@ def sig_test_format(sig_test):
total_sig_test_result['skipped'] = nbSkipped
return total_sig_test_result
-installers = ["fuel", "compass", "joid", "apex"]
-step_order = ["initialisation", "orchestrator", "vIMS", "sig_test"]
+logger.info("****************************************")
+logger.info("* Generating reporting vIMS *")
+logger.info("* Data retention = %s days *" % conf.PERIOD)
+logger.info("* *")
+logger.info("****************************************")
+installers = conf.installers
+step_order = ["initialisation", "orchestrator", "vIMS", "sig_test"]
+logger.info("Start processing....")
for installer in installers:
- request = Request('http://testresults.opnfv.org/test/api/v1/results?case=vims&installer=' + installer)
+ logger.info("Search vIMS results for installer %s" % installer)
+ request = Request(conf.URL_BASE + '?case=vims&installer=' + installer)
try:
response = urlopen(request)
k = response.read()
results = json.loads(k)
except URLError, e:
- print 'No kittez. Got an error code:', e
+ logger.error("Error code: %s" % e)
test_results = results['results']
- test_results.reverse()
+
+ logger.debug("Results found: %s" % test_results)
scenario_results = {}
for r in test_results:
@@ -44,6 +56,7 @@ for installer in installers:
for s, s_result in scenario_results.items():
scenario_results[s] = s_result[0:5]
+ logger.debug("Search for success criteria")
for result in scenario_results[s]:
result["start_date"] = result["start_date"].split(".")[0]
sig_test = result['details']['sig_test']['result']
@@ -67,17 +80,34 @@ for installer in installers:
result['pr_step_ok'] = 0
if nb_step != 0:
result['pr_step_ok'] = (float(nb_step_ok)/nb_step)*100
-
-
- templateLoader = jinja2.FileSystemLoader(os.path.dirname(os.path.abspath(__file__)))
- templateEnv = jinja2.Environment( loader=templateLoader )
-
- TEMPLATE_FILE = "./template/index-vims-tmpl.html"
- template = templateEnv.get_template( TEMPLATE_FILE )
-
- outputText = template.render( scenario_results = scenario_results, step_order = step_order, installer = installer)
-
- with open("./release/master/index-vims-" + installer + ".html", "wb") as fh:
+ try:
+ logger.debug("Scenario %s, Installer %s"
+ % (s_result[1]['scenario'], installer))
+ logger.debug("Orchestrator deployment: %s s"
+ % result['details']['orchestrator']['duration'])
+ logger.debug("vIMS deployment: %s s"
+ % result['details']['vIMS']['duration'])
+ logger.debug("Signaling testing: %s s"
+ % result['details']['sig_test']['duration'])
+ logger.debug("Signaling testing results: %s"
+ % format_result)
+ except:
+ logger.error("Data badly formatted")
+ logger.debug("------------------------------------------------")
+
+ templateLoader = jinja2.FileSystemLoader(conf.REPORTING_PATH)
+ templateEnv = jinja2.Environment(loader=templateLoader)
+
+ TEMPLATE_FILE = "/template/index-vims-tmpl.html"
+ template = templateEnv.get_template(TEMPLATE_FILE)
+
+ outputText = template.render(scenario_results=scenario_results,
+ step_order=step_order,
+ installer=installer)
+
+ with open(conf.REPORTING_PATH +
+ "/release/master/index-vims-" +
+ installer + ".html", "wb") as fh:
fh.write(outputText)
-
+logger.info("vIMS report succesfully generated")
diff --git a/utils/test/reporting/functest/reportingConf.py b/utils/test/reporting/functest/reportingConf.py
index 649246d64..a58eeecc9 100644
--- a/utils/test/reporting/functest/reportingConf.py
+++ b/utils/test/reporting/functest/reportingConf.py
@@ -10,9 +10,19 @@
#
# ****************************************************
installers = ["apex", "compass", "fuel", "joid"]
-# installers = ["compass"]
+# installers = ["apex"]
+# list of test cases declared in testcases.yaml but that must not be
+# taken into account for the scoring
+blacklist = ["odl", "ovno", "security_scan", "copper", "moon"]
# versions = ["brahmaputra", "master"]
versions = ["master"]
PERIOD = 10
MAX_SCENARIO_CRITERIA = 18
+# get the last 5 test results to determinate the success criteria
+NB_TESTS = 5
+# REPORTING_PATH = "/usr/share/nginx/html/reporting/functest"
+REPORTING_PATH = "."
URL_BASE = 'http://testresults.opnfv.org/test/api/v1/results'
+TEST_CONF = "https://git.opnfv.org/cgit/functest/plain/ci/testcases.yaml"
+LOG_LEVEL = "ERROR"
+LOG_FILE = REPORTING_PATH + "/reporting.log"
diff --git a/utils/test/reporting/functest/reportingUtils.py b/utils/test/reporting/functest/reportingUtils.py
index 0db570f32..5051ffa95 100644
--- a/utils/test/reporting/functest/reportingUtils.py
+++ b/utils/test/reporting/functest/reportingUtils.py
@@ -7,8 +7,26 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
from urllib2 import Request, urlopen, URLError
+import logging
import json
-import reportingConf
+import reportingConf as conf
+
+
+def getLogger(module):
+ logFormatter = logging.Formatter("%(asctime)s [" +
+ module +
+ "] [%(levelname)-5.5s] %(message)s")
+ logger = logging.getLogger()
+
+ fileHandler = logging.FileHandler("{0}/{1}".format('.', conf.LOG_FILE))
+ fileHandler.setFormatter(logFormatter)
+ logger.addHandler(fileHandler)
+
+ consoleHandler = logging.StreamHandler()
+ consoleHandler.setFormatter(logFormatter)
+ logger.addHandler(consoleHandler)
+ logger.setLevel(conf.LOG_LEVEL)
+ return logger
def getApiResults(case, installer, scenario, version):
@@ -19,9 +37,10 @@ def getApiResults(case, installer, scenario, version):
# urllib2.install_opener(opener)
# url = "http://127.0.0.1:8000/results?case=" + case + \
# "&period=30&installer=" + installer
- url = (reportingConf.URL_BASE + "?case=" + case +
- "&period=" + str(reportingConf.PERIOD) + "&installer=" + installer +
- "&scenario=" + scenario + "&version=" + version)
+ url = (conf.URL_BASE + "?case=" + case +
+ "&period=" + str(conf.PERIOD) + "&installer=" + installer +
+ "&scenario=" + scenario + "&version=" + version +
+ "&last=" + str(conf.NB_TESTS))
request = Request(url)
try:
@@ -37,9 +56,8 @@ def getApiResults(case, installer, scenario, version):
def getScenarios(case, installer, version):
case = case.getName()
- print case
- url = (reportingConf.URL_BASE + "?case=" + case +
- "&period=" + str(reportingConf.PERIOD) + "&installer=" + installer +
+ url = (conf.URL_BASE + "?case=" + case +
+ "&period=" + str(conf.PERIOD) + "&installer=" + installer +
"&version=" + version)
request = Request(url)
@@ -104,7 +122,7 @@ def getResult(testCase, installer, scenario, version):
# print "nb of results:" + str(len(test_results))
for r in test_results:
- # print r["creation_date"]
+ # print r["start_date"]
# print r["criteria"]
scenario_results.append({r["start_date"]: r["criteria"]})
# sort results
@@ -114,11 +132,16 @@ def getResult(testCase, installer, scenario, version):
# 2: <4 successful consecutive runs but passing the criteria
# 1: close to pass the success criteria
# 0: 0% success, not passing
+ # -1: no run available
test_result_indicator = 0
nbTestOk = getNbtestOk(scenario_results)
- # print "Nb test OK:"+ str(nbTestOk)
+
+ # print "Nb test OK (last 10 days):"+ str(nbTestOk)
# check that we have at least 4 runs
- if nbTestOk < 1:
+ if len(scenario_results) < 1:
+ # No results available
+ test_result_indicator = -1
+ elif nbTestOk < 1:
test_result_indicator = 0
elif nbTestOk < 2:
test_result_indicator = 1
@@ -126,7 +149,9 @@ def getResult(testCase, installer, scenario, version):
# Test the last 4 run
if (len(scenario_results) > 3):
last4runResults = scenario_results[-4:]
- if getNbtestOk(last4runResults):
+ nbTestOkLast4 = getNbtestOk(last4runResults)
+ # print "Nb test OK (last 4 run):"+ str(nbTestOkLast4)
+ if nbTestOkLast4 > 3:
test_result_indicator = 3
else:
test_result_indicator = 2
diff --git a/utils/test/reporting/functest/template/index-status-tmpl.html b/utils/test/reporting/functest/template/index-status-tmpl.html
index 89a1d1527..0c3fa9426 100644
--- a/utils/test/reporting/functest/template/index-status-tmpl.html
+++ b/utils/test/reporting/functest/template/index-status-tmpl.html
@@ -76,7 +76,7 @@
{% for test in items[scenario] -%}
<th>
{% if test.getCriteria() > -1 -%}
- {{test.getDbName() }}
+ {{test.getDisplayName() }}
{%- endif %}
{% if test.getTier() > 3 -%}
*
diff --git a/utils/test/reporting/functest/testCase.py b/utils/test/reporting/functest/testCase.py
index f0e8f5995..e19853a09 100644
--- a/utils/test/reporting/functest/testCase.py
+++ b/utils/test/reporting/functest/testCase.py
@@ -19,6 +19,28 @@ class TestCase(object):
self.criteria = criteria
self.isRunnable = isRunnable
self.tier = tier
+ display_name_matrix = {'healthcheck': 'healthcheck',
+ 'vping_ssh': 'vPing (ssh)',
+ 'vping_userdata': 'vPing (userdata)',
+ 'odl': 'ODL',
+ 'onos': 'ONOS',
+ 'ocl': 'OCL',
+ 'tempest_smoke_serial': 'Tempest (smoke)',
+ 'tempest_full_parallel': 'Tempest (full)',
+ 'rally_sanity': 'Rally (smoke)',
+ 'bgpvpn': 'bgpvpn',
+ 'rally_full': 'Rally (full)',
+ 'vims': 'vIMS',
+ 'doctor': 'Doctor',
+ 'promise': 'Promise',
+ 'moon': 'moon',
+ 'copper': 'copper',
+ 'security_scan': 'security'
+ }
+ try:
+ self.displayName = display_name_matrix[self.name]
+ except:
+ self.displayName = "unknown"
def getName(self):
return self.name
@@ -74,10 +96,10 @@ class TestCase(object):
self.isRunnable = is_runnable
def toString(self):
- testcase = ("Name=" + self.name + ";Criteria=" + str(self.criteria)
- + ";Project=" + self.project + ";Constraints="
- + str(self.constraints) + ";IsRunnable"
- + str(self.isRunnable))
+ testcase = ("Name=" + self.name + ";Criteria=" +
+ str(self.criteria) + ";Project=" + self.project +
+ ";Constraints=" + str(self.constraints) +
+ ";IsRunnable" + str(self.isRunnable))
return testcase
def getDbName(self):
@@ -98,31 +120,15 @@ class TestCase(object):
'rally_full': 'rally_full',
'vims': 'vims',
'doctor': 'doctor-notification',
- 'promise': 'promise'
+ 'promise': 'promise',
+ 'moon': 'moon',
+ 'copper': 'copper',
+ 'security_scan': 'security'
}
try:
return test_match_matrix[self.name]
except:
return "unknown"
- def getTestDisplayName(self):
- # Correspondance name of the test case / name in the DB
- test_match_matrix = {'healthcheck': 'healthcheck',
- 'vping_ssh': 'vPing (ssh)',
- 'vping_userdata': 'vPing (userdata)',
- 'odl': 'ODL',
- 'onos': 'ONOS',
- 'ocl': 'OCL',
- 'tempest_smoke_serial': 'Tempest (smoke)',
- 'tempest_full_parallel': 'Tempest (full)',
- 'rally_sanity': 'Rally (smoke)',
- 'bgpvpn': 'bgpvpn',
- 'rally_full': 'Rally (full)',
- 'vims': 'vIMS',
- 'doctor': 'Doctor',
- 'promise': 'Promise'
- }
- try:
- return test_match_matrix[self.name]
- except:
- return "unknown"
+ def getDisplayName(self):
+ return self.displayName
diff --git a/utils/test/result_collection_api/docker/Dockerfile b/utils/test/result_collection_api/docker/Dockerfile
new file mode 100644
index 000000000..ffee4c231
--- /dev/null
+++ b/utils/test/result_collection_api/docker/Dockerfile
@@ -0,0 +1,52 @@
+#######################################################
+# Docker container for OPNFV-TESTAPI
+#######################################################
+# Purpose: run opnfv-testapi for gathering test results
+#
+# Maintained by SerenaFeng
+# Build:
+# $ docker build -t opnfv/testapi:tag .
+#
+# Execution:
+# $ docker run -dti -p 8000:8000 \
+# -e "swagger_url=http://10.63.243.17:8000" \
+# -e "mongodb_url=mongodb://10.63.243.17:27017/" \
+# -e "api_port=8000"
+# opnfv/testapi:tag
+#
+# NOTE: providing swagger_url, api_port, mongodb_url is optional.
+# If not provided, it will use the default one
+# configured in config.ini
+#
+# 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
+#
+
+FROM ubuntu:14.04
+MAINTAINER SerenaFeng <feng.xiaowei@zte.com.cn>
+LABEL version="v1" description="OPNFV TestAPI Docker container"
+
+ENV HOME /home
+
+# Packaged dependencies
+RUN apt-get update && apt-get install -y \
+curl \
+git \
+gcc \
+wget \
+python-dev \
+python-pip \
+crudini \
+--no-install-recommends
+
+RUN pip install --upgrade pip
+
+RUN git config --global http.sslVerify false
+RUN git clone https://gerrit.opnfv.org/gerrit/releng /home/releng
+
+WORKDIR /home/releng/utils/test/result_collection_api/
+RUN pip install -r requirements.txt
+RUN python setup.py install
+CMD ["bash", "docker/start-server.sh"]
diff --git a/utils/test/result_collection_api/docker/prepare-env.sh b/utils/test/result_collection_api/docker/prepare-env.sh
new file mode 100755
index 000000000..99433cc8c
--- /dev/null
+++ b/utils/test/result_collection_api/docker/prepare-env.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+FILE=/etc/opnfv_testapi/config.ini
+
+
+if [ "$mongodb_url" != "" ]; then
+ sudo crudini --set --existing $FILE mongo url $mongodb_url
+fi
+
+if [ "$swagger_url" != "" ]; then
+ sudo crudini --set --existing $FILE swagger base_url $swagger_url
+fi
+
+if [ "$api_port" != "" ];then
+ sudo crudini --set --existing $FILE api port $api_port
+fi
+
diff --git a/utils/test/result_collection_api/docker/start-server.sh b/utils/test/result_collection_api/docker/start-server.sh
new file mode 100755
index 000000000..8bf6084ae
--- /dev/null
+++ b/utils/test/result_collection_api/docker/start-server.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+bash docker/prepare-env.sh
+opnfv-testapi
diff --git a/utils/test/result_collection_api/etc/config.ini b/utils/test/result_collection_api/etc/config.ini
index 16346bf36..0edb73a3f 100644
--- a/utils/test/result_collection_api/etc/config.ini
+++ b/utils/test/result_collection_api/etc/config.ini
@@ -13,4 +13,4 @@ port = 8000
debug = True
[swagger]
-base_url = http://testresults.opnfv.org/test \ No newline at end of file
+base_url = http://localhost:8000
diff --git a/utils/test/result_collection_api/opnfv_testapi/resources/handlers.py b/utils/test/result_collection_api/opnfv_testapi/resources/handlers.py
index 873701103..f98c35e8f 100644
--- a/utils/test/result_collection_api/opnfv_testapi/resources/handlers.py
+++ b/utils/test/result_collection_api/opnfv_testapi/resources/handlers.py
@@ -198,9 +198,8 @@ class GenericApiHandler(RequestHandler):
comparing values
"""
if not (new_value is None):
- if len(new_value) > 0:
- if new_value != old_value:
- edit_request[key] = new_value
+ if new_value != old_value:
+ edit_request[key] = new_value
return edit_request
diff --git a/utils/test/result_collection_api/opnfv_testapi/resources/result_handlers.py b/utils/test/result_collection_api/opnfv_testapi/resources/result_handlers.py
index 56bed6c81..400b84ac1 100644
--- a/utils/test/result_collection_api/opnfv_testapi/resources/result_handlers.py
+++ b/utils/test/result_collection_api/opnfv_testapi/resources/result_handlers.py
@@ -45,7 +45,7 @@ class GenericResultHandler(GenericApiHandler):
obj = {"$gte": str(period)}
query['start_date'] = obj
elif k == 'trust_indicator':
- query[k] = float(v)
+ query[k + '.current'] = float(v)
elif k != 'last':
query[k] = v
return query
@@ -112,12 +112,12 @@ class ResultsCLHandler(GenericResultHandler):
@type period: L{string}
@in period: query
@required period: False
- @param last: last days
+ @param last: last records stored until now
@type last: L{string}
@in last: query
@required last: False
- @param trust_indicator: must be int/long/float
- @type trust_indicator: L{string}
+ @param trust_indicator: must be float
+ @type trust_indicator: L{float}
@in trust_indicator: query
@required trust_indicator: False
"""
@@ -180,3 +180,19 @@ class ResultsGURHandler(GenericResultHandler):
query = dict()
query["_id"] = ObjectId(result_id)
self._get_one(query)
+
+ @swagger.operation(nickname="update")
+ def put(self, result_id):
+ """
+ @description: update a single result by _id
+ @param body: fields to be updated
+ @type body: L{ResultUpdateRequest}
+ @in body: body
+ @rtype: L{Result}
+ @return 200: update success
+ @raise 404: result not exist
+ @raise 403: nothing to update
+ """
+ query = {'_id': ObjectId(result_id)}
+ db_keys = []
+ self._update(query, db_keys)
diff --git a/utils/test/result_collection_api/opnfv_testapi/resources/result_models.py b/utils/test/result_collection_api/opnfv_testapi/resources/result_models.py
index fb6a80961..dd1e3dc53 100644
--- a/utils/test/result_collection_api/opnfv_testapi/resources/result_models.py
+++ b/utils/test/result_collection_api/opnfv_testapi/resources/result_models.py
@@ -10,7 +10,69 @@ from opnfv_testapi.tornado_swagger import swagger
@swagger.model()
+class TIHistory(object):
+ """
+ @ptype step: L{float}
+ """
+ def __init__(self, date=None, step=0):
+ self.date = date
+ self.step = step
+
+ def format(self):
+ return {
+ "date": self.date,
+ "step": self.step
+ }
+
+ @staticmethod
+ def from_dict(a_dict):
+ if a_dict is None:
+ return None
+
+ return TIHistory(a_dict.get('date'), a_dict.get('step'))
+
+
+@swagger.model()
+class TI(object):
+ """
+ @property histories: trust_indicator update histories
+ @ptype histories: C{list} of L{TIHistory}
+ @ptype current: L{float}
+ """
+ def __init__(self, current=0):
+ self.current = current
+ self.histories = list()
+
+ def format(self):
+ hs = []
+ for h in self.histories:
+ hs.append(h.format())
+
+ return {
+ "current": self.current,
+ "histories": hs
+ }
+
+ @staticmethod
+ def from_dict(a_dict):
+ if a_dict is None:
+ return None
+ t = TI()
+ t.current = a_dict.get('current')
+ if 'histories' in a_dict.keys():
+ for history in a_dict.get('histories', None):
+ t.histories.append(TIHistory.from_dict(history))
+ else:
+ t.histories = []
+ return t
+
+
+@swagger.model()
class ResultCreateRequest(object):
+ """
+ @property trust_indicator:
+ @ptype trust_indicator: L{TI}
+ """
def __init__(self,
pod_name=None,
project_name=None,
@@ -50,15 +112,30 @@ class ResultCreateRequest(object):
"build_tag": self.build_tag,
"scenario": self.scenario,
"criteria": self.criteria,
- "trust_indicator": self.trust_indicator
+ "trust_indicator": self.trust_indicator.format()
+ }
+
+
+@swagger.model()
+class ResultUpdateRequest(object):
+ """
+ @property trust_indicator:
+ @ptype trust_indicator: L{TI}
+ """
+ def __init__(self, trust_indicator=None):
+ self.trust_indicator = trust_indicator
+
+ def format(self):
+ return {
+ "trust_indicator": self.trust_indicator.format(),
}
@swagger.model()
class TestResult(object):
"""
- @property trust_indicator: must be int/long/float
- @ptype trust_indicator: L{float}
+ @property trust_indicator: used for long duration test case
+ @ptype trust_indicator: L{TI}
"""
def __init__(self, _id=None, case_name=None, project_name=None,
pod_name=None, installer=None, version=None,
@@ -90,7 +167,6 @@ class TestResult(object):
t.case_name = a_dict.get('case_name')
t.pod_name = a_dict.get('pod_name')
t.project_name = a_dict.get('project_name')
- t.description = a_dict.get('description')
t.start_date = str(a_dict.get('start_date'))
t.stop_date = str(a_dict.get('stop_date'))
t.details = a_dict.get('details')
@@ -99,19 +175,7 @@ class TestResult(object):
t.build_tag = a_dict.get('build_tag')
t.scenario = a_dict.get('scenario')
t.criteria = a_dict.get('criteria')
- # 0 < trust indicator < 1
- # if bad value => set this indicator to 0
- t.trust_indicator = a_dict.get('trust_indicator')
- if t.trust_indicator is not None:
- if isinstance(t.trust_indicator, (int, long, float)):
- if t.trust_indicator < 0:
- t.trust_indicator = 0
- elif t.trust_indicator > 1:
- t.trust_indicator = 1
- else:
- t.trust_indicator = 0
- else:
- t.trust_indicator = 0
+ t.trust_indicator = TI.from_dict(a_dict.get('trust_indicator'))
return t
def format(self):
@@ -119,7 +183,6 @@ class TestResult(object):
"case_name": self.case_name,
"project_name": self.project_name,
"pod_name": self.pod_name,
- "description": self.description,
"start_date": str(self.start_date),
"stop_date": str(self.stop_date),
"version": self.version,
@@ -128,7 +191,7 @@ class TestResult(object):
"build_tag": self.build_tag,
"scenario": self.scenario,
"criteria": self.criteria,
- "trust_indicator": self.trust_indicator
+ "trust_indicator": self.trust_indicator.format()
}
def format_http(self):
@@ -137,7 +200,6 @@ class TestResult(object):
"case_name": self.case_name,
"project_name": self.project_name,
"pod_name": self.pod_name,
- "description": self.description,
"start_date": str(self.start_date),
"stop_date": str(self.stop_date),
"version": self.version,
@@ -146,7 +208,7 @@ class TestResult(object):
"build_tag": self.build_tag,
"scenario": self.scenario,
"criteria": self.criteria,
- "trust_indicator": self.trust_indicator
+ "trust_indicator": self.trust_indicator.format()
}
diff --git a/utils/test/result_collection_api/opnfv_testapi/tests/unit/fake_pymongo.py b/utils/test/result_collection_api/opnfv_testapi/tests/unit/fake_pymongo.py
index 6ab98c720..450969248 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tests/unit/fake_pymongo.py
+++ b/utils/test/result_collection_api/opnfv_testapi/tests/unit/fake_pymongo.py
@@ -116,8 +116,8 @@ class MemDb(object):
if k == 'start_date':
if not MemDb._compare_date(v, content.get(k)):
return False
- elif k == 'trust_indicator':
- if float(content.get(k)) != float(v):
+ elif k == 'trust_indicator.current':
+ if content.get('trust_indicator').get('current') != v:
return False
elif content.get(k, None) != v:
return False
@@ -173,7 +173,6 @@ class MemDb(object):
def _check_keys(self, doc):
for key in doc.keys():
- print('key', key, 'value', doc.get(key))
if '.' in key:
raise NameError('key {} must not contain .'.format(key))
if key.startswith('$'):
diff --git a/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_fake_pymongo.py b/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_fake_pymongo.py
index 27382f089..9a1253e94 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_fake_pymongo.py
+++ b/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_fake_pymongo.py
@@ -8,9 +8,9 @@
##############################################################################
import unittest
-from tornado.web import Application
from tornado import gen
from tornado.testing import AsyncHTTPTestCase, gen_test
+from tornado.web import Application
import fake_pymongo
diff --git a/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_project.py b/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_project.py
index d47306093..327ddf7b2 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_project.py
+++ b/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_project.py
@@ -10,7 +10,7 @@ import unittest
from test_base import TestBase
from opnfv_testapi.resources.project_models import ProjectCreateRequest, \
- Project, Projects
+ Project, Projects, ProjectUpdateRequest
from opnfv_testapi.common.constants import HTTP_OK, HTTP_BAD_REQUEST, \
HTTP_FORBIDDEN, HTTP_NOT_FOUND
@@ -112,7 +112,7 @@ class TestProjectUpdate(TestProjectBase):
code, body = self.get(self.req_d.name)
_id = body._id
- req = ProjectCreateRequest('newName', 'new description')
+ req = ProjectUpdateRequest('newName', 'new description')
code, body = self.update(req, self.req_d.name)
self.assertEqual(code, HTTP_OK)
self.assertEqual(_id, body._id)
diff --git a/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_result.py b/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_result.py
index bba3b228f..98ef7c08c 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_result.py
+++ b/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_result.py
@@ -6,15 +6,16 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-import unittest
import copy
+import unittest
+from datetime import datetime, timedelta
from opnfv_testapi.common.constants import HTTP_OK, HTTP_BAD_REQUEST, \
HTTP_NOT_FOUND
from opnfv_testapi.resources.pod_models import PodCreateRequest
from opnfv_testapi.resources.project_models import ProjectCreateRequest
from opnfv_testapi.resources.result_models import ResultCreateRequest, \
- TestResult, TestResults
+ TestResult, TestResults, ResultUpdateRequest, TI, TIHistory
from opnfv_testapi.resources.testcase_models import TestcaseCreateRequest
from test_base import TestBase
@@ -55,9 +56,11 @@ class TestResultBase(TestBase):
self.build_tag = 'v3.0'
self.scenario = 'odl-l2'
self.criteria = 'passed'
- self.trust_indicator = 0.7
+ self.trust_indicator = TI(0.7)
self.start_date = "2016-05-23 07:16:09.477097"
self.stop_date = "2016-05-23 07:16:19.477097"
+ self.update_date = "2016-05-24 07:16:19.477097"
+ self.update_step = -0.05
super(TestResultBase, self).setUp()
self.details = Details(timestart='0', duration='9s', status='OK')
self.req_d = ResultCreateRequest(pod_name=self.pod,
@@ -74,6 +77,7 @@ class TestResultBase(TestBase):
trust_indicator=self.trust_indicator)
self.get_res = TestResult
self.list_res = TestResults
+ self.update_res = TestResult
self.basePath = '/api/v1/results'
self.req_pod = PodCreateRequest(self.pod, 'metal', 'zte pod 1')
self.req_project = ProjectCreateRequest(self.project, 'vping test')
@@ -103,10 +107,19 @@ class TestResultBase(TestBase):
self.assertEqual(result.build_tag, req.build_tag)
self.assertEqual(result.scenario, req.scenario)
self.assertEqual(result.criteria, req.criteria)
- self.assertEqual(result.trust_indicator, req.trust_indicator)
self.assertEqual(result.start_date, req.start_date)
self.assertEqual(result.stop_date, req.stop_date)
self.assertIsNotNone(result._id)
+ ti = result.trust_indicator
+ self.assertEqual(ti.current, req.trust_indicator.current)
+ if ti.histories:
+ history = ti.histories[0]
+ self.assertEqual(history.date, self.update_date)
+ self.assertEqual(history.step, self.update_step)
+
+ def _create_d(self):
+ _, res = self.create_d()
+ return res.href.split('/')[-1]
class TestResultCreate(TestResultBase):
@@ -172,8 +185,7 @@ class TestResultCreate(TestResultBase):
class TestResultGet(TestResultBase):
def test_getOne(self):
- _, res = self.create_d()
- _id = res.href.split('/')[-1]
+ _id = self._create_d()
code, body = self.get(_id)
self.assert_res(code, body)
@@ -266,8 +278,6 @@ class TestResultGet(TestResultBase):
self.assert_res(code, result, req)
def _create_changed_date(self, **kwargs):
- import copy
- from datetime import datetime, timedelta
req = copy.deepcopy(self.req_d)
req.start_date = datetime.now() + timedelta(**kwargs)
req.stop_date = str(req.start_date + timedelta(minutes=10))
@@ -276,13 +286,36 @@ class TestResultGet(TestResultBase):
return req
def _set_query(self, *args):
+ def get_value(arg):
+ return eval('self.' + arg) \
+ if arg != 'trust_indicator' else self.trust_indicator.current
uri = ''
for arg in args:
if '=' in arg:
uri += arg + '&'
else:
- uri += '{}={}&'.format(arg, eval('self.' + arg))
+ uri += '{}={}&'.format(arg, get_value(arg))
return uri[0: -1]
+
+class TestResultUpdate(TestResultBase):
+ def test_success(self):
+ _id = self._create_d()
+
+ new_ti = copy.deepcopy(self.trust_indicator)
+ new_ti.current += self.update_step
+ new_ti.histories.append(TIHistory(self.update_date, self.update_step))
+ new_data = copy.deepcopy(self.req_d)
+ new_data.trust_indicator = new_ti
+ update = ResultUpdateRequest(trust_indicator=new_ti)
+ code, body = self.update(update, _id)
+ self.assertEqual(_id, body._id)
+ self.assert_res(code, body, new_data)
+
+ code, new_body = self.get(_id)
+ self.assertEqual(_id, new_body._id)
+ self.assert_res(code, new_body, new_data)
+
+
if __name__ == '__main__':
unittest.main()