Merge "Fetch admin.conf from master on kubernetes scenario"
authorJun Li <lijun_1203@126.com>
Tue, 29 Aug 2017 02:04:18 +0000 (02:04 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Tue, 29 Aug 2017 02:04:18 +0000 (02:04 +0000)
14 files changed:
jjb/apex/apex-deploy.sh
jjb/apex/apex.yml
jjb/apex/apex.yml.j2
jjb/releng/opnfv-docker.yml
jjb/securedlab/check-jinja2.yml
jjb/xci/osa-periodic-jobs.yml
utils/test/testapi/.gitignore
utils/test/testapi/docker/Dockerfile
utils/test/testapi/install.sh [deleted file]
utils/test/testapi/opnfv_testapi/resources/scenario_handlers.py
utils/test/testapi/opnfv_testapi/resources/scenario_models.py
utils/test/testapi/opnfv_testapi/router/url_mappings.py
utils/test/testapi/opnfv_testapi/tests/unit/resources/test_scenario.py
utils/test/testapi/setup.py

index 4244f44..ce9544b 100755 (executable)
@@ -10,6 +10,8 @@ echo "Starting the Apex deployment."
 echo "--------------------------------------------------------"
 echo
 
+sudo rm -rf /tmp/tmp*
+
 if [ -z "$DEPLOY_SCENARIO" ]; then
   echo "Deploy scenario not set!"
   exit 1
index 51f59f7..a3cd7b3 100644 (file)
 
     properties:
         - logrotate-default
+        - build-blocker:
+            use-build-blocker: true
+            block-level: 'NODE'
+            blocking-jobs:
+                - 'apex-verify.*'
         - throttle:
-            max-per-node: 3
+            max-per-node: 1
             max-total: 10
             option: 'project'
 
 
     properties:
         - logrotate-default
+        - build-blocker:
+            use-build-blocker: true
+            block-level: 'NODE'
+            blocking-jobs:
+                - 'apex-verify.*'
         - throttle:
-            max-per-node: 3
+            max-per-node: 1
             max-total: 10
             option: 'project'
 
 
     wrappers:
         - timeout:
-            timeout: 120
+            timeout: 140
             fail: true
 
     parameters:
                   enable-condition: "def m = '$DEPLOY_SCENARIO' ==~ /os-(nosdn-nofeature|nosdn-kvm|odl_l3-fdio)-ha/"
                   abort-all-job: false
                   git-revision: false
-        - multijob:
-            name: StorPerf
-            condition: ALWAYS
-            projects:
-                - name: 'storperf-apex-baremetal-daily-{scenario_stream}'
-                  node-parameters: true
-                  current-parameters: false
-                  predefined-parameters:
-                    DEPLOY_SCENARIO=$DEPLOY_SCENARIO
-                  kill-phase-on: NEVER
-                  abort-all-job: false
-                  git-revision: false
+#        - multijob:
+#            name: StorPerf
+#            condition: ALWAYS
+#            projects:
+#                - name: 'storperf-apex-baremetal-daily-{scenario_stream}'
+#                  node-parameters: true
+#                  current-parameters: false
+#                  predefined-parameters:
+#                    DEPLOY_SCENARIO=$DEPLOY_SCENARIO
+#                  kill-phase-on: NEVER
+#                  abort-all-job: false
+#                  git-revision: false
 # Build status is always success due conditional plugin prefetching
 # build status before multijob phases execute
 #        - conditional-step:
index 99076fb..3f69ff6 100644 (file)
 
     properties:
         - logrotate-default
+        - build-blocker:
+            use-build-blocker: true
+            block-level: 'NODE'
+            blocking-jobs:
+                - 'apex-verify.*'
         - throttle:
-            max-per-node: 3
+            max-per-node: 1
             max-total: 10
             option: 'project'
 
 
     properties:
         - logrotate-default
+        - build-blocker:
+            use-build-blocker: true
+            block-level: 'NODE'
+            blocking-jobs:
+                - 'apex-verify.*'
         - throttle:
-            max-per-node: 3
+            max-per-node: 1
             max-total: 10
             option: 'project'
 
 
     wrappers:
         - timeout:
-            timeout: 120
+            timeout: 140
             fail: true
 
     parameters:
                   enable-condition: "def m = '$DEPLOY_SCENARIO' ==~ /os-(nosdn-nofeature|nosdn-kvm|odl_l3-fdio)-ha/"
                   abort-all-job: false
                   git-revision: false
-        - multijob:
-            name: StorPerf
-            condition: ALWAYS
-            projects:
-                - name: 'storperf-apex-baremetal-daily-{scenario_stream}'
-                  node-parameters: true
-                  current-parameters: false
-                  predefined-parameters:
-                    DEPLOY_SCENARIO=$DEPLOY_SCENARIO
-                  kill-phase-on: NEVER
-                  abort-all-job: false
-                  git-revision: false
+#        - multijob:
+#            name: StorPerf
+#            condition: ALWAYS
+#            projects:
+#                - name: 'storperf-apex-baremetal-daily-{scenario_stream}'
+#                  node-parameters: true
+#                  current-parameters: false
+#                  predefined-parameters:
+#                    DEPLOY_SCENARIO=$DEPLOY_SCENARIO
+#                  kill-phase-on: NEVER
+#                  abort-all-job: false
+#                  git-revision: false
 # Build status is always success due conditional plugin prefetching
 # build status before multijob phases execute
 #        - conditional-step:
index 9d27329..414eba2 100644 (file)
             dockerdir: 'docker/storperf-master'
             <<: *master
             <<: *other-receivers
+        - 'storperf-graphite':
+            project: 'storperf'
+            dockerdir: 'docker/storperf-graphite'
+            <<: *master
+            <<: *other-receivers
         - 'storperf-httpfrontend':
             project: 'storperf'
             dockerdir: 'docker/storperf-httpfrontend'
index 1e85536..430ced5 100644 (file)
                     pattern: '**/*.jinja2'
                   - compare-type: ANT
                     pattern: '**/*.yaml'
+            skip-vote:
+                successful: true
+                failed: true
+                unstable: true
+                notbuilt: true
+
     builders:
         - check-jinja
 
index 350ee76..8335750 100644 (file)
 - project:
-    project: 'releng-xci'
+    name: 'opnfv-osa-periodic'
 
-    name: 'os-periodic'
-#--------------------------------
-# Branch Anchors
-#--------------------------------
-# the versions stated here default to branches which then later
-# on used for checking out the branches, pulling in head of the branch.
-    master: &master
-        stream: master
-        openstack-osa-version: '{stream}'
-        opnfv-releng-version: 'master'
-        gs-pathname: ''
-    ocata: &ocata
-        stream: ocata
-        openstack-osa-version: 'stable/{stream}'
-        opnfv-releng-version: 'master'
-        gs-pathname: '/{stream}'
+    project: 'releng-xci'
 #--------------------------------
-#        XCI PODs
+# branches
 #--------------------------------
-    pod:
-        - virtual:
-            <<: *master
-        - virtual:
-            <<: *ocata
+    stream:
+        - master:
+            branch: '{stream}'
 #--------------------------------
-# Supported Distros
+# distros
 #--------------------------------
     distro:
         - 'xenial':
             disabled: false
-            slave-label: xci-xenial-virtual
-            dib-os-release: 'xenial'
-            dib-os-element: 'ubuntu-minimal'
-            dib-os-packages: 'vlan,vim,less,bridge-utils,sudo,language-pack-en,iputils-ping,rsyslog,curl,python,debootstrap,ifenslave,ifenslave-2.6,lsof,lvm2,tcpdump,nfs-kernel-server,chrony,iptables'
-            extra-dib-elements: 'openssh-server'
         - 'centos7':
             disabled: true
-            slave-label: xci-centos7-virtual
-            dib-os-release: '7'
-            dib-os-element: 'centos7'
-            dib-os-packages: 'vim,less,bridge-utils,iputils,rsyslog,curl'
-            extra-dib-elements: 'openssh-server'
         - 'suse':
             disabled: true
-            slave-label: xci-suse-virtual
-            dib-os-release: '42.2'
-            dib-os-element: 'opensuse-minimal'
-            dib-os-packages: 'vim,less,bridge-utils,iputils,rsyslog,curl'
-            extra-dib-elements: 'openssh-server'
-
+#--------------------------------
+# type
+#--------------------------------
+    type:
+        - virtual
+#--------------------------------
+# phases
+#--------------------------------
+    phase:
+        - 'deploy'
+        - 'healthcheck'
 #--------------------------------
 # jobs
 #--------------------------------
     jobs:
-        - 'osa-deploy-{pod}-{distro}-periodic-{stream}'
-
+        - 'osa-periodic-{distro}-{type}-{stream}'
+        - 'osa-periodic-{phase}-{type}-{stream}'
 #--------------------------------
 # job templates
 #--------------------------------
 - job-template:
-    name: 'osa-deploy-{pod}-{distro}-periodic-{stream}'
+    name: 'osa-periodic-{distro}-{type}-{stream}'
+
+    project-type: multijob
 
     disabled: '{obj:disabled}'
 
     concurrent: false
 
     properties:
+        - logrotate-default
         - build-blocker:
             use-build-blocker: true
             blocking-jobs:
-                - '^xci-os.*'
-                - '^xci-deploy.*'
-                - '^xci-functest.*'
-                - '^bifrost-.*periodic.*'
-                - '^osa-.*periodic.*'
+                - 'xci-verify-.*'
+                - 'bifrost-verify-.*'
+                - 'bifrost-periodic-.*'
+                - 'osa-verify-.*'
+                - 'osa-periodic-.*'
             block-level: 'NODE'
+
+    wrappers:
+        - ssh-agent-wrapper
+        - build-timeout:
+            timeout: 240
+        - fix-workspace-permissions
+
+    scm:
+        - git-scm-osa
+
+    triggers:
+        - pollscm:
+            cron: "@midnight"
+            ignore-post-commit-hooks: True
+
+    parameters:
+        - project-parameter:
+            project: '{project}'
+            branch: '{branch}'
+        - label:
+            name: SLAVE_LABEL
+            default: 'xci-virtual-{distro}'
+
+    builders:
+        - description-setter:
+            description: "Built on $NODE_NAME"
+        - multijob:
+            name: deploy
+            condition: SUCCESSFUL
+            projects:
+                - name: 'osa-periodic-deploy-{type}-{stream}'
+                  current-parameters: true
+                  predefined-parameters: |
+                    DISTRO={distro}
+                    DEPLOY_SCENARIO=os-nosdn-nofeature-noha
+                  git-revision: true
+                  node-parameters: true
+                  kill-phase-on: FAILURE
+                  abort-all-job: true
+        - multijob:
+            name: healthcheck
+            condition: SUCCESSFUL
+            projects:
+                - name: 'osa-periodic-healthcheck-{type}-{stream}'
+                  current-parameters: true
+                  predefined-parameters: |
+                    DISTRO={distro}
+                    DEPLOY_SCENARIO=os-nosdn-nofeature-noha
+                    FUNCTEST_SUITE_NAME=healthcheck
+                  node-parameters: true
+                  kill-phase-on: NEVER
+                  abort-all-job: false
+
+- job-template:
+    name: 'osa-periodic-{phase}-{type}-{stream}'
+
+    disabled: false
+
+    concurrent: true
+
+    properties:
         - logrotate-default
+        - build-blocker:
+            use-build-blocker: true
+            blocking-jobs:
+                - 'xci-verify-deploy-.*'
+                - 'xci-verify-healthcheck-.*'
+                - 'bifrost-verify-.*'
+                - 'bifrost-periodic-.*'
+                - 'osa-verify-.*'
+                - 'osa-periodic-.*'
+            block-level: 'NODE'
 
     parameters:
         - project-parameter:
             project: '{project}'
-            branch: '{opnfv-releng-version}'
-        - string:
-            name: GIT_BASE
-            default: https://gerrit.opnfv.org/gerrit/$PROJECT
-        - string:
-            name: XCI_FLAVOR
-            default: 'ha'
+            branch: '{branch}'
+        - label:
+            name: SLAVE_LABEL
+            default: 'xci-virtual-{distro}'
         - string:
             name: OPENSTACK_OSA_VERSION
-            default: '{openstack-osa-version}'
-        - string:
-            name: OPNFV_RELENG_VERSION
-            default: '{opnfv-releng-version}'
+            default: 'master'
         - string:
             name: DISTRO
-            default: '{distro}'
+            default: 'xenial'
         - string:
-            name: DIB_OS_RELEASE
-            default: '{dib-os-release}'
+            name: DEPLOY_SCENARIO
+            default: 'os-nosdn-nofeature-noha'
         - string:
-            name: DIB_OS_ELEMENT
-            default: '{dib-os-element}'
+            name: XCI_FLAVOR
+            default: 'mini'
         - string:
-            name: DIB_OS_PACKAGES
-            default: '{dib-os-packages}'
+            name: XCI_LOOP
+            default: 'periodic'
         - string:
-            name: EXTRA_DIB_ELEMENTS
-            default: '{extra-dib-elements}'
+            name: OPNFV_RELENG_DEV_PATH
+            default: $WORKSPACE/releng-xci
         - string:
-            name: CLEAN_DIB_IMAGES
-            default: 'true'
-        - label:
-            name: SLAVE_LABEL
-            default: '{slave-label}'
+            name: FUNCTEST_SUITE_NAME
+            default: 'healthcheck'
         - string:
             name: ANSIBLE_VERBOSITY
-            default: ''
+            default: '-vvvv'
         - string:
-            name: XCI_LOOP
-            default: 'periodic'
-
-    wrappers:
-        - fix-workspace-permissions
+            name: FORCE_MASTER
+            default: 'true'
+        - string:
+            name: GIT_BASE
+            default: https://gerrit.opnfv.org/gerrit/$PROJECT
 
     scm:
-        - git-scm
+        - git-scm-osa
 
-    # trigger is disabled until we know which jobs we will have
-    # and adjust stuff accordingly
-    triggers:
-        - timed: ''  # '@midnight'
+    wrappers:
+        - ssh-agent-wrapper
+        - build-timeout:
+            timeout: 240
+        - fix-workspace-permissions
 
     builders:
         - description-setter:
-            description: "Built on $NODE_NAME - Scenario: $DEPLOY_SCENARIO"
-        - 'osa-deploy-builder'
+            description: "Built on $NODE_NAME"
+        - 'osa-periodic-{phase}-macro'
 
-#---------------------------
+#--------------------------------
 # builder macros
-#---------------------------
+#--------------------------------
 - builder:
-    name: osa-deploy-builder
+    name: 'osa-periodic-deploy-macro'
     builders:
-        - shell:
-            !include-raw: ./xci-deploy.sh
+        - shell: |
+            #!/bin/bash
+
+            # here we will
+            # - clone releng-xci repo as the jobs are running against openstack gerrit
+            #   and we need to clone releng-xci ourselves to $OPNFV_RELENG_DEV_PATH
+            # - run sources-branch-updater.sh from osa to update/pin the role versions
+            #   at the time this job gets triggered against osa master in case if the
+            #   deployment succeeds and we decide to bump version used by xci
+            # - copy generated role versions into $OPNFV_RELENG_DEV_PATH/xci/file
+            # - start the deployment by executing xci-deploy.sh as usual
+            #
+            # we might also need to pin versions of openstack services as well.
+
+            echo "Hello World!"
+
+- builder:
+    name: 'osa-periodic-healthcheck-macro'
+    builders:
+        - shell: |
+            #!/bin/bash
+
+            echo "Hello World!"
+#--------------------------------
+# scm macro
+#--------------------------------
+- scm:
+    name: git-scm-osa
+    scm:
+        - git:
+            url: https://review.openstack.org/p/openstack/openstack-ansible.git
+            branches:
+                - master
+            timeout: 15
index c7b63b5..00f8a03 100644 (file)
@@ -1,4 +1,7 @@
 AUTHORS
 ChangeLog
 setup.cfg-e
+opnfv_testapi/static
+build
+*.egg-info
 
index 5311f35..a46fce2 100644 (file)
@@ -47,5 +47,5 @@ RUN git clone https://gerrit.opnfv.org/gerrit/releng /home/releng
 
 WORKDIR /home/releng/utils/test/testapi/
 RUN pip install -r requirements.txt
-RUN bash install.sh
+RUN python setup.py install
 CMD ["bash", "docker/start-server.sh"]
diff --git a/utils/test/testapi/install.sh b/utils/test/testapi/install.sh
deleted file mode 100755 (executable)
index d470e38..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-usage="
-Script to install opnfv_tesgtapi automatically.
-This script should be run under root.
-
-usage:
-    bash $(basename "$0") [-h|--help] [-t <test_name>]
-
-where:
-    -h|--help         show this help text"
-
-# Ref :-  https://openstack.nimeyo.com/87286/openstack-packaging-all-definition-data-files-config-setup
-if [ -z "$VIRTUAL_ENV" ];
-then
-    if [[ $(whoami) != "root" ]];
-    then
-        echo "Error: This script must be run as root!"
-        exit 1
-    fi
-else
-    sed -i -e 's#/etc/opnfv_testapi =#etc/opnfv_testapi =#g' setup.cfg
-fi
-
-cp -fr 3rd_party/static opnfv_testapi/static
-python setup.py install
-rm -fr opnfv_testapi/static
-if [ ! -z "$VIRTUAL_ENV" ]; then
-    sed -i -e 's#etc/opnfv_testapi =#/etc/opnfv_testapi =#g' setup.cfg
-fi
\ No newline at end of file
index d6918a6..e9c19a7 100644 (file)
@@ -114,8 +114,21 @@ class ScenarioGURHandler(GenericScenarioHandler):
         self._get_one(query={'name': name})
         pass
 
+    @swagger.operation(nickname="updateScenarioName")
     def put(self, name):
-        pass
+        """
+            @description: update scenario, only rename is supported currently
+            @param body: fields to be updated
+            @type body: L{ScenarioUpdateRequest}
+            @in body: body
+            @rtype: L{Scenario}
+            @return 200: update success
+            @raise 404: scenario not exist
+            @raise 403: nothing to update
+        """
+        query = {'name': name}
+        db_keys = ['name']
+        self._update(query=query, db_keys=db_keys)
 
     @swagger.operation(nickname="deleteScenarioByName")
     def delete(self, name):
@@ -150,6 +163,9 @@ class ScenarioUpdater(object):
             ('versions', 'post'): self._update_requests_add_versions,
             ('versions', 'put'): self._update_requests_update_versions,
             ('versions', 'delete'): self._update_requests_delete_versions,
+            ('installers', 'post'): self._update_requests_add_installers,
+            ('installers', 'put'): self._update_requests_update_installers,
+            ('installers', 'delete'): self._update_requests_delete_installers,
         }
         updates[(item, action)](self.data)
 
@@ -250,6 +266,19 @@ class ScenarioUpdater(object):
     def _update_requests_delete_versions(self, installer):
         installer.versions = self._remove_versions(installer.versions)
 
+    def _update_requests_add_installers(self, scenario):
+        scenario.installers = self._update_with_body(models.ScenarioInstaller,
+                                                     'installer',
+                                                     scenario.installers)
+
+    def _update_requests_update_installers(self, scenario):
+        scenario.installers = self._update_with_body(models.ScenarioInstaller,
+                                                     'installer',
+                                                     list())
+
+    def _update_requests_delete_installers(self, scenario):
+        scenario.installers = self._remove_installers(scenario.installers)
+
     def _update_with_body(self, clazz, field, withs):
         exists = list()
         malformat = list()
@@ -272,6 +301,9 @@ class ScenarioUpdater(object):
     def _filter_installers(self, installers):
         return self._filter('installer', installers)
 
+    def _remove_installers(self, installers):
+        return self._remove('installer', installers)
+
     def _filter_versions(self, versions):
         return self._filter('version', versions)
 
@@ -688,3 +720,56 @@ class ScenarioVersionsHandler(GenericScenarioUpdateHandler):
                        'delete',
                        locators={'scenario': scenario,
                                  'installer': None})
+
+
+class ScenarioInstallersHandler(GenericScenarioUpdateHandler):
+    @swagger.operation(nickname="addInstallersUnderScenario")
+    def post(self, scenario):
+        """
+        @description: add installers to scenario
+        @notes: add one or multiple installers
+            POST /api/v1/scenarios/<scenario_name>/installers
+        @param body: installers to be added
+        @type body: C{list} of L{ScenarioInstaller}
+        @in body: body
+        @return 200: installers are added.
+        @raise 400: bad schema
+        @raise 409: conflict, installer already exists
+        @raise 404:  scenario not exist
+        """
+        self.do_update('installers',
+                       'post',
+                       locators={'scenario': scenario})
+
+    @swagger.operation(nickname="updateInstallersUnderScenario")
+    def put(self, scenario):
+        """
+        @description: replace all installers
+        @notes: substitute all installers as a totality
+            PUT /api/v1/scenarios/<scenario_name>/installers
+        @param body: new installers
+        @type body: C{list} of L{ScenarioInstaller}
+        @in body: body
+        @return 200: replace versions success.
+        @raise 400: bad schema
+        @raise 404:  scenario/installer not exist
+        """
+        self.do_update('installers',
+                       'put',
+                       locators={'scenario': scenario})
+
+    @swagger.operation(nickname="deleteInstallersUnderScenario")
+    def delete(self, scenario):
+        """
+        @description: delete one or multiple installers
+        @notes: delete one or multiple installers
+            DELETE /api/v1/scenarios/<scenario_name>/installers
+        @param body: installers(names) to be deleted
+        @type body: C{list} of L{string}
+        @in body: body
+        @return 200: delete versions success.
+        @raise 404:  scenario/installer not exist
+        """
+        self.do_update('installers',
+                       'delete',
+                       locators={'scenario': scenario})
index c6da76b..d950ed1 100644 (file)
@@ -166,6 +166,12 @@ class ScenarioChangeOwnerRequest(models.ModelBase):
         self.owner = owner
 
 
+@swagger.model()
+class ScenarioUpdateRequest(models.ModelBase):
+    def __init__(self, name=None):
+        self.name = name
+
+
 @swagger.model()
 class Scenario(models.ModelBase):
     """
index bdfc701..3e3ab87 100644 (file)
@@ -66,6 +66,8 @@ mappings = [
      scenario_handlers.ScenarioOwnerHandler),
     (r"/api/v1/scenarios/([^/]+)/versions",
      scenario_handlers.ScenarioVersionsHandler),
+    (r"/api/v1/scenarios/([^/]+)/installers",
+     scenario_handlers.ScenarioInstallersHandler),
 
     # static path
     (r'/(.*\.(css|png|gif|js|html|json|map|woff2|woff|ttf))',
index 360b4fa..1367fc6 100644 (file)
@@ -2,7 +2,7 @@ import functools
 import httplib
 import json
 import os
-from copy import deepcopy
+
 from datetime import datetime
 
 from opnfv_testapi.common import message
@@ -50,15 +50,15 @@ class TestScenarioBase(base.TestBase):
         self.assertEqual(scenario, models.Scenario.from_dict(req))
 
     @staticmethod
-    def _set_query(*args):
+    def set_query(*args):
         uri = ''
         for arg in args:
             uri += arg + '&'
         return uri[0: -1]
 
-    def _get_and_assert(self, name, req=None):
+    def get_and_assert(self, name):
         code, body = self.get(name)
-        self.assert_res(code, body, req)
+        self.assert_res(code, body, self.req_d)
 
 
 class TestScenarioCreate(TestScenarioBase):
@@ -97,25 +97,25 @@ class TestScenarioGet(TestScenarioBase):
         self.scenario_2 = self.create_return_name(self.req_2)
 
     def test_getByName(self):
-        self._get_and_assert(self.scenario_1, self.req_d)
+        self.get_and_assert(self.scenario_1)
 
     def test_getAll(self):
         self._query_and_assert(query=None, reqs=[self.req_d, self.req_2])
 
     def test_queryName(self):
-        query = self._set_query('name=nosdn-nofeature-ha')
+        query = self.set_query('name=nosdn-nofeature-ha')
         self._query_and_assert(query, reqs=[self.req_d])
 
     def test_queryInstaller(self):
-        query = self._set_query('installer=apex')
+        query = self.set_query('installer=apex')
         self._query_and_assert(query, reqs=[self.req_d])
 
     def test_queryVersion(self):
-        query = self._set_query('version=master')
+        query = self.set_query('version=master')
         self._query_and_assert(query, reqs=[self.req_d])
 
     def test_queryProject(self):
-        query = self._set_query('project=functest')
+        query = self.set_query('project=functest')
         self._query_and_assert(query, reqs=[self.req_d, self.req_2])
 
     # close due to random fail, open again after solve it in another patch
@@ -170,6 +170,7 @@ class TestScenarioUpdate(TestScenarioBase):
     def update_url_fixture(item):
         def _update_url_fixture(xstep):
             def wrapper(self, *args, **kwargs):
+                self.update_url = '{}/{}'.format(self.scenario_url, item)
                 locator = None
                 if item in ['projects', 'owner']:
                     locator = 'installer={}&version={}'.format(
@@ -178,10 +179,12 @@ class TestScenarioUpdate(TestScenarioBase):
                 elif item in ['versions']:
                     locator = 'installer={}'.format(
                         self.installer)
+                elif item in ['rename']:
+                    self.update_url = self.scenario_url
+
+                if locator:
+                    self.update_url = '{}?{}'.format(self.update_url, locator)
 
-                self.update_url = '{}/{}?{}'.format(self.scenario_url,
-                                                    item,
-                                                    locator)
                 xstep(self, *args, **kwargs)
             return wrapper
         return _update_url_fixture
@@ -190,203 +193,257 @@ class TestScenarioUpdate(TestScenarioBase):
         def _update_partial(set_update):
             @functools.wraps(set_update)
             def wrapper(self):
-                update, scenario = set_update(self, deepcopy(self.req_d))
-                code, body = getattr(self, operate)(update, self.scenario)
-                getattr(self, expected)(code, scenario)
+                update = set_update(self)
+                code, body = getattr(self, operate)(update)
+                getattr(self, expected)(code)
             return wrapper
         return _update_partial
 
     @update_partial('_add', '_success')
-    def test_addScore(self, scenario):
+    def test_addScore(self):
         add = models.ScenarioScore(date=str(datetime.now()), score='11/12')
-        projects = scenario['installers'][0]['versions'][0]['projects']
+        projects = self.req_d['installers'][0]['versions'][0]['projects']
         functest = filter(lambda f: f['project'] == 'functest', projects)[0]
         functest['scores'].append(add.format())
         self.update_url = '{}/scores?{}'.format(self.scenario_url,
                                                 self.locate_project)
 
-        return add, scenario
+        return add
 
     @update_partial('_add', '_success')
-    def test_addTrustIndicator(self, scenario):
+    def test_addTrustIndicator(self):
         add = models.ScenarioTI(date=str(datetime.now()), status='gold')
-        projects = scenario['installers'][0]['versions'][0]['projects']
+        projects = self.req_d['installers'][0]['versions'][0]['projects']
         functest = filter(lambda f: f['project'] == 'functest', projects)[0]
         functest['trust_indicators'].append(add.format())
         self.update_url = '{}/trust_indicators?{}'.format(self.scenario_url,
                                                           self.locate_project)
 
-        return add, scenario
+        return add
 
     @update_partial('_add', '_success')
-    def test_addCustoms(self, scenario):
-        add = ['odl', 'parser', 'vping_ssh']
-        projects = scenario['installers'][0]['versions'][0]['projects']
+    def test_addCustoms(self):
+        adds = ['odl', 'parser', 'vping_ssh']
+        projects = self.req_d['installers'][0]['versions'][0]['projects']
         functest = filter(lambda f: f['project'] == 'functest', projects)[0]
-        functest['customs'] = list(set(functest['customs'] + add))
+        functest['customs'] = list(set(functest['customs'] + adds))
         self.update_url = '{}/customs?{}'.format(self.scenario_url,
                                                  self.locate_project)
-        return add, scenario
+        return adds
 
     @update_partial('_update', '_success')
-    def test_updateCustoms(self, scenario):
-        news = ['odl', 'parser', 'vping_ssh']
-        projects = scenario['installers'][0]['versions'][0]['projects']
+    def test_updateCustoms(self):
+        updates = ['odl', 'parser', 'vping_ssh']
+        projects = self.req_d['installers'][0]['versions'][0]['projects']
         functest = filter(lambda f: f['project'] == 'functest', projects)[0]
-        functest['customs'] = news
+        functest['customs'] = updates
         self.update_url = '{}/customs?{}'.format(self.scenario_url,
                                                  self.locate_project)
 
-        return news, scenario
+        return updates
 
     @update_partial('_delete', '_success')
-    def test_deleteCustoms(self, scenario):
-        obsoletes = ['vping_ssh']
-        projects = scenario['installers'][0]['versions'][0]['projects']
+    def test_deleteCustoms(self):
+        deletes = ['vping_ssh']
+        projects = self.req_d['installers'][0]['versions'][0]['projects']
         functest = filter(lambda f: f['project'] == 'functest', projects)[0]
         functest['customs'] = ['healthcheck']
         self.update_url = '{}/customs?{}'.format(self.scenario_url,
                                                  self.locate_project)
 
-        return obsoletes, scenario
+        return deletes
 
     @update_url_fixture('projects')
     @update_partial('_add', '_success')
-    def test_addProjects_succ(self, scenario):
+    def test_addProjects_succ(self):
         add = models.ScenarioProject(project='qtip').format()
-        scenario['installers'][0]['versions'][0]['projects'].append(add)
-        return [add], scenario
+        self.req_d['installers'][0]['versions'][0]['projects'].append(add)
+        return [add]
 
     @update_url_fixture('projects')
     @update_partial('_add', '_conflict')
-    def test_addProjects_already_exist(self, scenario):
+    def test_addProjects_already_exist(self):
         add = models.ScenarioProject(project='functest').format()
-        scenario['installers'][0]['versions'][0]['projects'].append(add)
-        return [add], scenario
+        return [add]
 
     @update_url_fixture('projects')
     @update_partial('_add', '_bad_request')
-    def test_addProjects_bad_schema(self, scenario):
+    def test_addProjects_bad_schema(self):
         add = models.ScenarioProject(project='functest').format()
         add['score'] = None
-        scenario['installers'][0]['versions'][0]['projects'].append(add)
-        return [add], scenario
+        return [add]
 
     @update_url_fixture('projects')
     @update_partial('_update', '_success')
-    def test_updateProjects_succ(self, scenario):
+    def test_updateProjects_succ(self):
         update = models.ScenarioProject(project='qtip').format()
-        scenario['installers'][0]['versions'][0]['projects'] = [update]
-        return [update], scenario
+        self.req_d['installers'][0]['versions'][0]['projects'] = [update]
+        return [update]
 
     @update_url_fixture('projects')
     @update_partial('_update', '_conflict')
-    def test_updateProjects_duplicated(self, scenario):
-        update1 = models.ScenarioProject(project='qtip').format()
-        update2 = models.ScenarioProject(project='qtip').format()
-        scenario['installers'][0]['versions'][0]['projects'] = [update1,
-                                                                update2]
-        return [update1, update2], scenario
+    def test_updateProjects_duplicated(self):
+        update = models.ScenarioProject(project='qtip').format()
+        return [update, update]
 
     @update_url_fixture('projects')
     @update_partial('_update', '_bad_request')
-    def test_updateProjects_bad_schema(self, scenario):
+    def test_updateProjects_bad_schema(self):
         update = models.ScenarioProject(project='functest').format()
         update['score'] = None
-        scenario['installers'][0]['versions'][0]['projects'] = [update]
-        return [update], scenario
+        return [update]
 
     @update_url_fixture('projects')
     @update_partial('_delete', '_success')
-    def test_deleteProjects(self, scenario):
+    def test_deleteProjects(self):
         deletes = ['functest']
-        projects = scenario['installers'][0]['versions'][0]['projects']
-        scenario['installers'][0]['versions'][0]['projects'] = filter(
+        projects = self.req_d['installers'][0]['versions'][0]['projects']
+        self.req_d['installers'][0]['versions'][0]['projects'] = filter(
             lambda f: f['project'] != 'functest',
             projects)
-        return deletes, scenario
+        return deletes
 
     @update_url_fixture('owner')
     @update_partial('_update', '_success')
-    def test_changeOwner(self, scenario):
+    def test_changeOwner(self):
         new_owner = 'new_owner'
         update = models.ScenarioChangeOwnerRequest(new_owner).format()
-        scenario['installers'][0]['versions'][0]['owner'] = new_owner
-        return update, scenario
+        self.req_d['installers'][0]['versions'][0]['owner'] = new_owner
+        return update
 
     @update_url_fixture('versions')
     @update_partial('_add', '_success')
-    def test_addVersions_succ(self, scenario):
+    def test_addVersions_succ(self):
         add = models.ScenarioVersion(version='Euphrates').format()
-        scenario['installers'][0]['versions'].append(add)
-        return [add], scenario
+        self.req_d['installers'][0]['versions'].append(add)
+        return [add]
 
     @update_url_fixture('versions')
     @update_partial('_add', '_conflict')
-    def test_addVersions_already_exist(self, scenario):
+    def test_addVersions_already_exist(self):
         add = models.ScenarioVersion(version='master').format()
-        scenario['installers'][0]['versions'].append(add)
-        return [add], scenario
+        return [add]
 
     @update_url_fixture('versions')
     @update_partial('_add', '_bad_request')
-    def test_addVersions_bad_schema(self, scenario):
+    def test_addVersions_bad_schema(self):
         add = models.ScenarioVersion(version='euphrates').format()
         add['notexist'] = None
-        scenario['installers'][0]['versions'].append(add)
-        return [add], scenario
+        return [add]
 
     @update_url_fixture('versions')
     @update_partial('_update', '_success')
-    def test_updateVersions_succ(self, scenario):
+    def test_updateVersions_succ(self):
         update = models.ScenarioVersion(version='euphrates').format()
-        scenario['installers'][0]['versions'] = [update]
-        return [update], scenario
+        self.req_d['installers'][0]['versions'] = [update]
+        return [update]
 
     @update_url_fixture('versions')
     @update_partial('_update', '_conflict')
-    def test_updateVersions_duplicated(self, scenario):
-        update1 = models.ScenarioVersion(version='euphrates').format()
-        update2 = models.ScenarioVersion(version='euphrates').format()
-        scenario['installers'][0]['versions'] = [update1, update2]
-        return [update1, update2], scenario
+    def test_updateVersions_duplicated(self):
+        update = models.ScenarioVersion(version='euphrates').format()
+        return [update, update]
 
     @update_url_fixture('versions')
     @update_partial('_update', '_bad_request')
-    def test_updateVersions_bad_schema(self, scenario):
+    def test_updateVersions_bad_schema(self):
         update = models.ScenarioVersion(version='euphrates').format()
         update['not_owner'] = 'Iam'
-        scenario['installers'][0]['versions'] = [update]
-        return [update], scenario
+        return [update]
 
     @update_url_fixture('versions')
     @update_partial('_delete', '_success')
-    def test_deleteVersions(self, scenario):
+    def test_deleteVersions(self):
         deletes = ['master']
-        versions = scenario['installers'][0]['versions']
-        scenario['installers'][0]['versions'] = filter(
+        versions = self.req_d['installers'][0]['versions']
+        self.req_d['installers'][0]['versions'] = filter(
             lambda f: f['version'] != 'master',
             versions)
-        return deletes, scenario
+        return deletes
+
+    @update_url_fixture('installers')
+    @update_partial('_add', '_success')
+    def test_addInstallers_succ(self):
+        add = models.ScenarioInstaller(installer='daisy').format()
+        self.req_d['installers'].append(add)
+        return [add]
+
+    @update_url_fixture('installers')
+    @update_partial('_add', '_conflict')
+    def test_addInstallers_already_exist(self):
+        add = models.ScenarioInstaller(installer='apex').format()
+        return [add]
+
+    @update_url_fixture('installers')
+    @update_partial('_add', '_bad_request')
+    def test_addInstallers_bad_schema(self):
+        add = models.ScenarioInstaller(installer='daisy').format()
+        add['not_exist'] = 'not_exist'
+        return [add]
+
+    @update_url_fixture('installers')
+    @update_partial('_update', '_success')
+    def test_updateInstallers_succ(self):
+        update = models.ScenarioInstaller(installer='daisy').format()
+        self.req_d['installers'] = [update]
+        return [update]
+
+    @update_url_fixture('installers')
+    @update_partial('_update', '_conflict')
+    def test_updateInstallers_duplicated(self):
+        update = models.ScenarioInstaller(installer='daisy').format()
+        return [update, update]
 
-    def _add(self, update_req, new_scenario):
+    @update_url_fixture('installers')
+    @update_partial('_update', '_bad_request')
+    def test_updateInstallers_bad_schema(self):
+        update = models.ScenarioInstaller(installer='daisy').format()
+        update['not_exist'] = 'not_exist'
+        return [update]
+
+    @update_url_fixture('installers')
+    @update_partial('_delete', '_success')
+    def test_deleteInstallers(self):
+        deletes = ['apex']
+        installers = self.req_d['installers']
+        self.req_d['installers'] = filter(
+            lambda f: f['installer'] != 'apex',
+            installers)
+        return deletes
+
+    @update_url_fixture('rename')
+    @update_partial('_update', '_success')
+    def test_renameScenario(self):
+        new_name = 'new_scenario_name'
+        update = models.ScenarioUpdateRequest(name=new_name)
+        self.req_d['name'] = new_name
+        return update
+
+    @update_url_fixture('rename')
+    @update_partial('_update', '_forbidden')
+    def test_renameScenario_exist(self):
+        new_name = self.req_d['name']
+        update = models.ScenarioUpdateRequest(name=new_name)
+        return update
+
+    def _add(self, update_req):
         return self.post_direct_url(self.update_url, update_req)
 
-    def _update(self, update_req, new_scenario):
+    def _update(self, update_req):
         return self.update_direct_url(self.update_url, update_req)
 
-    def _delete(self, update_req, new_scenario):
+    def _delete(self, update_req):
         return self.delete_direct_url(self.update_url, update_req)
 
-    def _success(self, status, new_scenario):
+    def _success(self, status):
         self.assertEqual(status, httplib.OK)
-        self._get_and_assert(new_scenario.get('name'), new_scenario)
+        self.get_and_assert(self.req_d['name'])
 
-    def _forbidden(self, status, new_scenario):
+    def _forbidden(self, status):
         self.assertEqual(status, httplib.FORBIDDEN)
 
-    def _bad_request(self, status, new_scenario):
+    def _bad_request(self, status):
         self.assertEqual(status, httplib.BAD_REQUEST)
 
-    def _conflict(self, status, new_scenario):
+    def _conflict(self, status):
         self.assertEqual(status, httplib.CONFLICT)
index f689cb3..dd52373 100644 (file)
@@ -1,5 +1,7 @@
-import setuptools
+import os
+import subprocess
 
+import setuptools
 
 __author__ = 'serena'
 
@@ -8,6 +10,11 @@ try:
 except ImportError:
     pass
 
+dirpath = os.path.dirname(os.path.abspath(__file__))
+subprocess.call(['ln', '-s',
+                 '{}/3rd_party/static'.format(dirpath),
+                 '{}/opnfv_testapi/static'.format(dirpath)])
+
 setuptools.setup(
     setup_requires=['pbr==2.0.0'],
     pbr=True)