Merge "Apex: updates for post-danube"
authorTim Rozet <trozet@redhat.com>
Wed, 19 Jul 2017 13:44:23 +0000 (13:44 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Wed, 19 Jul 2017 13:44:23 +0000 (13:44 +0000)
jjb/doctor/doctor.yml
jjb/functest/functest-alpine.sh [new file with mode: 0644]
jjb/functest/functest-daily-jobs.yml
jjb/global/slave-params.yml
jjb/qtip/qtip-verify-jobs.yml
utils/test/testapi/opnfv_testapi/resources/handlers.py
utils/test/testapi/opnfv_testapi/resources/result_handlers.py
utils/test/testapi/opnfv_testapi/tests/unit/fake_pymongo.py
utils/test/testapi/opnfv_testapi/tests/unit/resources/test_result.py
utils/test/testapi/requirements.txt
utils/test/testapi/test-requirements.txt

index c5454c7..5bb8f74 100644 (file)
             #       so this symbolic link should not be in 'tests/'. Otherwise,
             #       we'll have the same log twice in jenkins console log.
             ln -sfn $HOME/opnfv/functest/results/{stream} functest_results
+            # NOTE: Get functest script in $WORKSPACE. This functest script is
+            #       needed to perform VM image download in set-functest-env.sh
+            #       from E release cycle.
+            mkdir -p functest/ci
+            wget https://git.opnfv.org/functest/plain/functest/ci/download_images.sh -O functest/ci/download_images.sh
         - 'functest-suite-builder'
         - shell: |
             functest_log="$HOME/opnfv/functest/results/{stream}/{project}.log"
diff --git a/jjb/functest/functest-alpine.sh b/jjb/functest/functest-alpine.sh
new file mode 100644 (file)
index 0000000..4b4c365
--- /dev/null
@@ -0,0 +1,72 @@
+#!/bin/bash
+
+set -e
+set +u
+set +o pipefail
+
+[[ $CI_DEBUG == true ]] && redirect="/dev/stdout" || redirect="/dev/null"
+FUNCTEST_DIR=/home/opnfv/functest
+
+# Prepare OpenStack credentials volume
+if [[ ${INSTALLER_TYPE} == 'joid' ]]; then
+    rc_file=$LAB_CONFIG/admin-openrc
+elif [[ ${INSTALLER_TYPE} == 'compass' && ${BRANCH} == 'master' ]]; then
+    cacert_file_vol="-v ${HOME}/os_cacert:${FUNCTEST_DIR}/conf/os_cacert"
+    echo "export OS_CACERT=${FUNCTEST_DIR}/conf/os_cacert" >> ${HOME}/opnfv-openrc.sh
+    rc_file=${HOME}/opnfv-openrc.sh
+else
+    rc_file=${HOME}/opnfv-openrc.sh
+fi
+rc_file_vol="-v ${rc_file}:${FUNCTEST_DIR}/conf/openstack.creds"
+
+
+# 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
+
+DEPLOY_TYPE=baremetal
+[[ $BUILD_TAG =~ "virtual" ]] && DEPLOY_TYPE=virt
+HOST_ARCH=$(uname -m)
+
+echo "Functest: Start Docker and prepare environment"
+
+echo "Functest: Download images that will be used by test cases"
+images_dir="${HOME}/opnfv/functest/images"
+chmod +x ${WORKSPACE}/functest/ci/download_images.sh
+${WORKSPACE}/functest/ci/download_images.sh ${images_dir} ${DEPLOY_SCENARIO} ${HOST_ARCH} 2> ${redirect}
+images_vol="-v ${images_dir}:${FUNCTEST_DIR}/images"
+
+dir_result="${HOME}/opnfv/functest/results/${BRANCH##*/}"
+mkdir -p ${dir_result}
+sudo rm -rf ${dir_result}/*
+results_vol="-v ${dir_result}:${FUNCTEST_DIR}/results"
+custom_params=
+test -f ${HOME}/opnfv/functest/custom/params_${DOCKER_TAG} && custom_params=$(cat ${HOME}/opnfv/functest/custom/params_${DOCKER_TAG})
+
+envs="-e INSTALLER_TYPE=${INSTALLER_TYPE} -e INSTALLER_IP=${INSTALLER_IP} \
+    -e NODE_NAME=${NODE_NAME} -e DEPLOY_SCENARIO=${DEPLOY_SCENARIO} \
+    -e BUILD_TAG=${BUILD_TAG} -e DEPLOY_TYPE=${DEPLOY_TYPE}"
+
+if [[ ${INSTALLER_TYPE} == 'compass' && ${DEPLOY_SCENARIO} == *'os-nosdn-openo-ha'* ]]; then
+    ssh_options="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
+    openo_msb_port=${openo_msb_port:-80}
+    openo_msb_endpoint="$(sshpass -p'root' ssh 2>/dev/null $ssh_options root@${installer_ip} \
+    'mysql -ucompass -pcompass -Dcompass -e "select package_config from cluster;" \
+    | sed s/,/\\n/g | grep openo_ip | cut -d \" -f 4'):$openo_msb_port"
+
+    envs=${env}" -e OPENO_MSB_ENDPOINT=${openo_msb_endpoint}"
+fi
+
+volumes="${images_vol} ${results_vol} ${sshkey_vol} ${rc_file_vol}"
+
+
+tiers=(healthcheck smoke)
+for tier in ${tiers[@]}; do
+    FUNCTEST_IMAGE=opnfv/functest-${tier}
+    echo "Functest: Pulling Functest Docker image ${FUNCTEST_IMAGE} ..."
+    docker pull ${FUNCTEST_IMAGE}>/dev/null
+    cmd="docker run ${envs} ${volumes} ${FUNCTEST_IMAGE}"
+    echo "Running Functest tier '${tier}'. CMD: ${cmd}"
+    ${cmd}
+done
index fdef6f4..cc9bac0 100644 (file)
 #            <<: *master
 #--------------------------------
 
+    alpine-pod:
+        - ericsson-virtual-pod1bl01:
+            slave-label: '{alpine-pod}'
+            installer: fuel
+            <<: *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
 ########################
         - 'functest-store-results'
         - 'functest-exit'
 
+- builder:
+    name: functest-alpine-daily-builder
+    builders:
+        - shell:
+            !include-raw:
+                - ./functest-env-presetup.sh
+                - ../../utils/fetch_os_creds.sh
+                - ./functest-alpine.sh
+
 - builder:
     name: functest-daily
     builders:
index 50859c4..3694c0b 100644 (file)
             name: GIT_BASE
             default: https://gerrit.opnfv.org/gerrit/$PROJECT
             description: 'Git URL to use on this Jenkins Slave'
+- parameter:
+    name: 'ericsson-virtual-pod1bl01-defaults'
+    parameters:
+        - label:
+            name: SLAVE_LABEL
+            default: 'ericsson-virtual-pod1bl01'
+        - string:
+            name: GIT_BASE
+            default: https://gerrit.opnfv.org/gerrit/$PROJECT
+            description: 'Git URL to use on this Jenkins Slave'
 - parameter:
     name: 'odl-netvirt-virtual-defaults'
     parameters:
index dd444c7..57d24b4 100644 (file)
@@ -7,6 +7,8 @@
     project: qtip
     jobs:
         - 'qtip-verify-{stream}'
+        - 'qtip-review-notebook-{stream}'
+        - 'qtip-merge-{stream}'
     stream:
         - master:
             branch: '{stream}'
     publishers:
         - publish-coverage
 
+# upload juypter notebook to artifacts for review
+- job-template:
+    name: 'qtip-review-notebook-{stream}'
+
+    disabled: '{obj:disabled}'
+
+    parameters:
+        - project-parameter:
+            project: '{project}'
+            branch: '{branch}'
+        - 'opnfv-build-ubuntu-defaults'
+
+    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: '{project}'
+                branches:
+                  - branch-compare-type: 'ANT'
+                    branch-pattern: '**/{branch}'
+                disable-strict-forbidden-file-verification: 'true'
+                file-paths:
+                  - compare-type: ANT
+                    pattern: 'examples/**'
+    builders:
+        - upload-under-review-notebooks-to-opnfv-artifacts
+        - report-build-result-to-gerrit
+
+- job-template:
+    name: 'qtip-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'
+            projects:
+                - project-compare-type: 'ANT'
+                  project-pattern: '*'
+                  branches:
+                      - branch-compare-type: 'ANT'
+                        branch-pattern: '**/{branch}'
+                  file-paths:
+                      - compare-type: ANT
+                        pattern: examples/**
+
+    builders:
+        - remove-old-docs-from-opnfv-artifacts
+
 ################################
 ## job builders
 #################################
             set -o xtrace
 
             tox
+
+# modified from upload-under-review-docs-to-opnfv-artifacts in global/releng-macro.yml
+- builder:
+    name: upload-under-review-notebooks-to-opnfv-artifacts
+    builders:
+        - shell: |
+            #!/bin/bash
+            set -o errexit
+            set -o pipefail
+            set -o xtrace
+            export PATH=$PATH:/usr/local/bin/
+
+            [[ $GERRIT_CHANGE_NUMBER =~ .+ ]]
+            [[ -d examples ]] || exit 0
+
+            echo
+            echo "###########################"
+            echo "UPLOADING DOCS UNDER REVIEW"
+            echo "###########################"
+            echo
+
+            gs_base="artifacts.opnfv.org/$PROJECT/review"
+            gs_path="$gs_base/$GERRIT_CHANGE_NUMBER"
+            local_path="upload/$GERRIT_CHANGE_NUMBER"
+
+            mkdir -p upload
+            cp -r examples "$local_path"
+            gsutil -m cp -r "$local_path" "gs://$gs_base/"
+
+            echo "Document link(s):" >> gerrit_comment.txt
+            find "$local_path" | grep -e 'ipynb$' | \
+                sed -e "s|^$local_path|    https://nbviewer.jupyter.org/urls/$gs_path|" >> gerrit_comment.txt
index c7fed8f..f23cc57 100644 (file)
@@ -107,12 +107,15 @@ class GenericApiHandler(web.RequestHandler):
         per_page = kwargs.get('per_page', 0)
         if query is None:
             query = {}
-        cursor = self._eval_db(self.table, 'find', query)
-        records_count = yield cursor.count()
-        total_pages = self._calc_total_pages(records_count,
-                                             last,
-                                             page,
-                                             per_page)
+
+        total_pages = 0
+        if page > 0:
+            cursor = self._eval_db(self.table, 'find', query)
+            records_count = yield cursor.count()
+            total_pages = self._calc_total_pages(records_count,
+                                                 last,
+                                                 page,
+                                                 per_page)
         pipelines = self._set_pipelines(query, sort, last, page, per_page)
         cursor = self._eval_db(self.table,
                                'aggregate',
@@ -125,7 +128,7 @@ class GenericApiHandler(web.RequestHandler):
             res = {self.table: data}
         else:
             res = res_op(data, *args)
-        if total_pages > 0:
+        if page > 0:
             res.update({
                 'pagination': {
                     'current_page': kwargs.get('page'),
@@ -140,12 +143,10 @@ class GenericApiHandler(web.RequestHandler):
         if (records_count > last) and (last > 0):
             records_nr = last
 
-        total_pages = 0
-        if page > 0:
-            total_pages, remainder = divmod(records_nr, per_page)
-            if remainder > 0:
-                total_pages += 1
-        if page > total_pages:
+        total_pages, remainder = divmod(records_nr, per_page)
+        if remainder > 0:
+            total_pages += 1
+        if page > 1 and page > total_pages:
             raises.BadRequest(
                 'Request page > total_pages [{}]'.format(total_pages))
         return total_pages
index 1773216..f9706fc 100644 (file)
@@ -60,6 +60,12 @@ class GenericResultHandler(handlers.GenericApiHandler):
                 query[k] = v
             if date_range:
                 query['start_date'] = date_range
+
+            # if $lt is not provided,
+            # empty/None/null/'' start_date will also be returned
+            if 'start_date' in query and '$lt' not in query['start_date']:
+                query['start_date'].update({'$lt': str(datetime.now())})
+
         return query
 
 
@@ -147,7 +153,7 @@ class ResultsCLHandler(GenericResultHandler):
             @in trust_indicator: query
             @required trust_indicator: False
         """
-        limitations = {'sort': {'start_date': -1}}
+        limitations = {'sort': {'_id': -1}}
         last = self.get_query_argument('last', 0)
         if last is not None:
             last = self.get_int('last', last)
index adaf6f7..04785d2 100644 (file)
@@ -119,10 +119,14 @@ class MemDb(object):
 
     @staticmethod
     def _compare_date(spec, value):
+        gte = True
+        lt = False
         for k, v in spec.iteritems():
-            if k == '$gte' and value >= v:
-                return True
-        return False
+            if k == '$gte' and value < v:
+                gte = False
+            elif k == '$lt' and value < v:
+                lt = True
+        return gte and lt
 
     def _in(self, content, *args):
         if self.name == 'scenarios':
index c8463cb..2bff048 100644 (file)
@@ -208,9 +208,9 @@ class TestResultCreate(TestResultBase):
 class TestResultGet(TestResultBase):
     def setUp(self):
         super(TestResultGet, self).setUp()
+        self.req_10d_before = self._create_changed_date(days=-10)
         self.req_d_id = self._create_d()
         self.req_10d_later = self._create_changed_date(days=10)
-        self.req_10d_before = self._create_changed_date(days=-10)
 
     @executor.get(httplib.OK, 'assert_res')
     def test_getOne(self):
@@ -256,9 +256,9 @@ class TestResultGet(TestResultBase):
     def test_queryPeriodNotInt(self):
         return self._set_query('period=a')
 
-    @executor.query(httplib.OK, '_query_last_one', 1)
+    @executor.query(httplib.OK, '_query_period_one', 1)
     def test_queryPeriodSuccess(self):
-        return self._set_query('period=1')
+        return self._set_query('period=11')
 
     @executor.query(httplib.BAD_REQUEST, message.must_int('last'))
     def test_queryLastNotInt(self):
@@ -268,7 +268,7 @@ class TestResultGet(TestResultBase):
     def test_queryLast(self):
         return self._set_query('last=1')
 
-    @executor.query(httplib.OK, '_query_last_one', 1)
+    @executor.query(httplib.OK, '_query_period_one', 1)
     def test_combination(self):
         return self._set_query('pod',
                                'project',
@@ -279,7 +279,7 @@ class TestResultGet(TestResultBase):
                                'scenario',
                                'trust_indicator',
                                'criteria',
-                               'period=1')
+                               'period=11')
 
     @executor.query(httplib.OK, '_query_success', 0)
     def test_notFound(self):
@@ -294,6 +294,14 @@ class TestResultGet(TestResultBase):
                                'criteria',
                                'period=1')
 
+    @executor.query(httplib.OK, '_query_success', 1)
+    def test_filterErrorStartdate(self):
+        self._create_error_start_date(None)
+        # self._create_error_start_date('None')
+        self._create_error_start_date('null')
+        self._create_error_start_date('')
+        return self._set_query('period=11')
+
     def _query_success(self, body, number):
         self.assertEqual(number, len(body.results))
 
@@ -301,6 +309,16 @@ class TestResultGet(TestResultBase):
         self.assertEqual(number, len(body.results))
         self.assert_res(body.results[0], self.req_10d_later)
 
+    def _query_period_one(self, body, number):
+        self.assertEqual(number, len(body.results))
+        self.assert_res(body.results[0], self.req_10d_before)
+
+    def _create_error_start_date(self, start_date):
+        req = copy.deepcopy(self.req_d)
+        req.start_date = start_date
+        self.create(req)
+        return req
+
     def _create_changed_date(self, **kwargs):
         req = copy.deepcopy(self.req_d)
         req.start_date = datetime.now() + timedelta(**kwargs)
index d2a45dc..4b6f75c 100644 (file)
@@ -2,9 +2,9 @@
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
 
-pbr==2.0.0
-setuptools>=16.0
-tornado>=3.1,<=4.3
+pbr>=2.0.0,!=2.1.0  # Apache-2.0
+setuptools>=16.0,!=24.0.0,!=34.0.0,!=34.0.1,!=34.0.2,!=34.0.3,!=34.1.0,!=34.1.1,!=34.2.0,!=34.3.0,!=34.3.1,!=34.3.2  # PSF/ZPL
+tornado>=3.1,<=4.3  # Apache-2.0
 epydoc>=0.3.1
-six>=1.9.0
-motor
+six>=1.9.0  # MIT
+motor  # Apache-2.0
index 3bead79..233f465 100644 (file)
@@ -2,9 +2,9 @@
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
 
-coverage
-mock>=2.0
-nose>=1.3.1
-pytest
-pytest-cov
-pytest-mock
+coverage>=4.0,!=4.4  # Apache-2.0
+mock>=2.0  # BSD
+nose  # LGPL
+pytest  # MIT
+pytest-cov  # MIT
+pytest-mock  # MIT