diff --git a/.zuul.yaml b/.zuul.yaml index 4e16fd78f..f030ebdb9 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -36,6 +36,7 @@ - openstack/neutron-lbaas - openstack/python-zaqarclient - openstack/senlin + - openstack/senlin-tempest-plugin - openstack/tempest - openstack/zaqar - openstack/zaqar-ui @@ -43,6 +44,7 @@ - ^.*\.rst$ - ^api-ref/.*$ - ^doc/.*$ + - ^senlin/tests/unit/.*$ - ^releasenotes/.*$ - job: @@ -57,6 +59,7 @@ - openstack/neutron-lbaas - openstack/python-zaqarclient - openstack/senlin + - openstack/senlin-tempest-plugin - openstack/tempest - openstack/zaqar - openstack/zaqar-ui @@ -64,6 +67,7 @@ - ^.*\.rst$ - ^api-ref/.*$ - ^doc/.*$ + - ^senlin/tests/unit/.*$ - ^releasenotes/.*$ - job: @@ -78,13 +82,16 @@ - openstack/neutron-lbaas - openstack/python-zaqarclient - openstack/senlin + - openstack/senlin-tempest-plugin - openstack/tempest - openstack/zaqar - openstack/zaqar-ui + - openstack/zaqar-tempest-plugin irrelevant-files: - ^.*\.rst$ - ^api-ref/.*$ - ^doc/.*$ + - ^senlin/tests/unit/.*$ - ^releasenotes/.*$ - job: @@ -99,6 +106,7 @@ - openstack/neutron-lbaas - openstack/python-zaqarclient - openstack/senlin + - openstack/senlin-tempest-plugin - openstack/tempest - openstack/zaqar - openstack/zaqar-ui @@ -106,6 +114,7 @@ - ^.*\.rst$ - ^api-ref/.*$ - ^doc/.*$ + - ^senlin/tests/unit/.*$ - ^releasenotes/.*$ - job: @@ -120,6 +129,7 @@ - openstack/neutron-lbaas - openstack/python-zaqarclient - openstack/senlin + - openstack/senlin-tempest-plugin - openstack/tempest - openstack/zaqar - openstack/zaqar-ui @@ -127,6 +137,7 @@ - ^.*\.rst$ - ^api-ref/.*$ - ^doc/.*$ + - ^senlin/tests/unit/.*$ - ^releasenotes/.*$ - job: @@ -141,13 +152,16 @@ - openstack/neutron-lbaas - openstack/python-zaqarclient - openstack/senlin + - openstack/senlin-tempest-plugin - openstack/tempest - openstack/zaqar - openstack/zaqar-ui + - openstack/zaqar-tempest-plugin irrelevant-files: - ^.*\.rst$ - ^api-ref/.*$ - ^doc/.*$ + - ^senlin/tests/unit/.*$ - ^releasenotes/.*$ - job: diff --git a/README.rst b/README.rst index b5781a93d..af3540688 100644 --- a/README.rst +++ b/README.rst @@ -50,20 +50,25 @@ Launchpad Projects - Server: https://launchpad.net/senlin - Client: https://launchpad.net/python-senlinclient - Dashboard: https://launchpad.net/senlin-dashboard +- Tempest Plugin: https://launchpad.net/senlin-tempest-plugin Code Repository --------------- - Server: https://git.openstack.org/cgit/openstack/senlin - Client: https://git.openstack.org/cgit/openstack/python-senlinclient - Dashboard: https://git.openstack.org/cgit/openstack/senlin-dashboard +- Tempest Plugin: https://git.openstack.org/cgit/openstack/senlin-tempest-plugin Blueprints ---------- -- Blueprints: https://blueprints.launchpad.net/senlin +- Blueprints: https://blueprints.launchpad.net/senlinA Bug Tracking ------------ -- Bugs: https://bugs.launchpad.net/senlin +- Server Bugs: https://bugs.launchpad.net/senlin +- Client Bugs: https://bugs.launchpad.net/python-senlinclient +- Dashboard Bugs: https://bugs.launchpad.net/senlin-dashboard +- Tempest Plugin Bugs: https://bugs.launchpad.net/senlin-tempest-plugin Weekly Meetings --------------- diff --git a/playbooks/legacy/senlin-dsvm-tempest-py27-api/run.yaml b/playbooks/legacy/senlin-dsvm-tempest-py27-api/run.yaml index db319a817..e9396c4b2 100644 --- a/playbooks/legacy/senlin-dsvm-tempest-py27-api/run.yaml +++ b/playbooks/legacy/senlin-dsvm-tempest-py27-api/run.yaml @@ -42,7 +42,8 @@ export DEVSTACK_GATE_USE_PYTHON3=False fi - export DEVSTACK_GATE_TEMPEST_REGEX="senlin.tests.tempest.api" + export SENLIN_TEST_TYPE="api" + export DEVSTACK_GATE_TEMPEST_REGEX="senlin_tempest_plugin.tests.${SENLIN_TEST_TYPE}" services=rabbit,mysql,dstat,key,tempest services+=,g-api,g-reg @@ -57,7 +58,7 @@ export PROJECTS="openstack/senlin $PROJECTS" export DEVSTACK_LOCAL_CONFIG="enable_plugin senlin https://git.openstack.org/openstack/senlin" - if [ "api" == "api" ]||[ "api" == "functional" ]; then + if [ "${SENLIN_TEST_TYPE}" == "api" ]||[ "${SENLIN_TEST_TYPE}" == "functional" ]; then export SENLIN_BACKEND="openstack_test" else export SENLIN_BACKEND="openstack" @@ -76,6 +77,10 @@ export DEVSTACK_LOCAL_CONFIG+=$'\n'"enable_plugin zaqar git://git.openstack.org/openstack/zaqar" fi + # use senlin-tempest-plugin + export PROJECTS="openstack/senlin-tempest-plugin $PROJECTS" + export DEVSTACK_LOCAL_CONFIG+=$'\n'"TEMPEST_PLUGINS+=' /opt/stack/new/senlin-tempest-plugin'" + export OVERRIDE_ENABLED_SERVICES=$services if [ "$BRANCH_OVERRIDE" != "default" ] ; then @@ -90,7 +95,7 @@ function post_test_hook { cd /opt/stack/new/senlin/senlin/tests/tempest/ - ./post_test_hook.sh + ./post_test_hook.sh senlin_tempest_plugin.tests.${SENLIN_TEST_TYPE} } export -f post_test_hook diff --git a/playbooks/legacy/senlin-dsvm-tempest-py27-functional/run.yaml b/playbooks/legacy/senlin-dsvm-tempest-py27-functional/run.yaml index 0037b9e9f..b5d48f6b2 100644 --- a/playbooks/legacy/senlin-dsvm-tempest-py27-functional/run.yaml +++ b/playbooks/legacy/senlin-dsvm-tempest-py27-functional/run.yaml @@ -43,7 +43,8 @@ export DEVSTACK_GATE_USE_PYTHON3=False fi - export DEVSTACK_GATE_TEMPEST_REGEX="senlin.tests.tempest.functional" + export SENLIN_TEST_TYPE="functional" + export DEVSTACK_GATE_TEMPEST_REGEX="senlin_tempest_plugin.tests.${SENLIN_TEST_TYPE}" services=rabbit,mysql,dstat,key,tempest services+=,g-api,g-reg @@ -58,7 +59,7 @@ export PROJECTS="openstack/senlin $PROJECTS" export DEVSTACK_LOCAL_CONFIG="enable_plugin senlin https://git.openstack.org/openstack/senlin" - if [ "functional" == "api" ]||[ "functional" == "functional" ]; then + if [ "${SENLIN_TEST_TYPE}" == "api" ]||[ "${SENLIN_TEST_TYPE}" == "functional" ]; then export SENLIN_BACKEND="openstack_test" else export SENLIN_BACKEND="openstack" @@ -77,6 +78,10 @@ export DEVSTACK_LOCAL_CONFIG+=$'\n'"enable_plugin zaqar git://git.openstack.org/openstack/zaqar" fi + # use senlin-tempest-plugin + export PROJECTS="openstack/senlin-tempest-plugin $PROJECTS" + export DEVSTACK_LOCAL_CONFIG+=$'\n'"TEMPEST_PLUGINS+=' /opt/stack/new/senlin-tempest-plugin'" + export OVERRIDE_ENABLED_SERVICES=$services if [ "$BRANCH_OVERRIDE" != "default" ] ; then @@ -91,7 +96,7 @@ function post_test_hook { cd /opt/stack/new/senlin/senlin/tests/tempest/ - ./post_test_hook.sh + ./post_test_hook.sh senlin_tempest_plugin.tests.${SENLIN_TEST_TYPE} } export -f post_test_hook diff --git a/playbooks/legacy/senlin-dsvm-tempest-py27-integration/run.yaml b/playbooks/legacy/senlin-dsvm-tempest-py27-integration/run.yaml index 0ba03b342..2cabbbd75 100644 --- a/playbooks/legacy/senlin-dsvm-tempest-py27-integration/run.yaml +++ b/playbooks/legacy/senlin-dsvm-tempest-py27-integration/run.yaml @@ -43,7 +43,8 @@ export DEVSTACK_GATE_USE_PYTHON3=False fi - export DEVSTACK_GATE_TEMPEST_REGEX="senlin.tests.tempest.integration" + export SENLIN_TEST_TYPE="integration" + export DEVSTACK_GATE_TEMPEST_REGEX="senlin_tempest_plugin.tests.${SENLIN_TEST_TYPE}" services=rabbit,mysql,dstat,key,tempest services+=,g-api,g-reg @@ -58,7 +59,7 @@ export PROJECTS="openstack/senlin $PROJECTS" export DEVSTACK_LOCAL_CONFIG="enable_plugin senlin https://git.openstack.org/openstack/senlin" - if [ "integration" == "api" ]||[ "integration" == "functional" ]; then + if [ "${SENLIN_TEST_TYPE}" == "api" ]||[ "${SENLIN_TEST_TYPE}" == "functional" ]; then export SENLIN_BACKEND="openstack_test" else export SENLIN_BACKEND="openstack" @@ -75,8 +76,14 @@ export PROJECTS="openstack/python-zaqarclient $PROJECTS" export PROJECTS="openstack/zaqar-ui $PROJECTS" export DEVSTACK_LOCAL_CONFIG+=$'\n'"enable_plugin zaqar git://git.openstack.org/openstack/zaqar" + export PROJECTS="openstack/zaqar-tempest-plugin $PROJECTS" + export DEVSTACK_LOCAL_CONFIG+=$'\n'"TEMPEST_PLUGINS+=' /opt/stack/new/zaqar-tempest-plugin'" fi + # use senlin-tempest-plugin + export PROJECTS="openstack/senlin-tempest-plugin $PROJECTS" + export DEVSTACK_LOCAL_CONFIG+=$'\n'"TEMPEST_PLUGINS+=' /opt/stack/new/senlin-tempest-plugin'" + export OVERRIDE_ENABLED_SERVICES=$services if [ "$BRANCH_OVERRIDE" != "default" ] ; then @@ -91,7 +98,7 @@ function post_test_hook { cd /opt/stack/new/senlin/senlin/tests/tempest/ - ./post_test_hook.sh + ./post_test_hook.sh senlin_tempest_plugin.tests.${SENLIN_TEST_TYPE} } export -f post_test_hook diff --git a/playbooks/legacy/senlin-dsvm-tempest-py35-api/run.yaml b/playbooks/legacy/senlin-dsvm-tempest-py35-api/run.yaml index 02684194f..b82b5ad7b 100644 --- a/playbooks/legacy/senlin-dsvm-tempest-py35-api/run.yaml +++ b/playbooks/legacy/senlin-dsvm-tempest-py35-api/run.yaml @@ -31,10 +31,10 @@ export PYTHONUNBUFFERED=True export DEVSTACK_GATE_NEUTRON=1 export DEVSTACK_GATE_TEMPEST=1 + export KEEP_LOCALRC=1 export DEVSTACK_GATE_TEMPEST_NOTESTS=1 export DEVSTACK_GATE_EXERCISES=0 export DEVSTACK_GATE_INSTALL_TESTONLY=1 - export KEEP_LOCALRC=1 if [ "py35" == "py35" ]; then export DEVSTACK_GATE_USE_PYTHON3=True @@ -42,7 +42,8 @@ export DEVSTACK_GATE_USE_PYTHON3=False fi - export DEVSTACK_GATE_TEMPEST_REGEX="senlin.tests.tempest.api" + export SENLIN_TEST_TYPE="api" + export DEVSTACK_GATE_TEMPEST_REGEX="senlin_tempest_plugin.tests.${SENLIN_TEST_TYPE}" services=rabbit,mysql,dstat,key,tempest services+=,g-api,g-reg @@ -57,7 +58,7 @@ export PROJECTS="openstack/senlin $PROJECTS" export DEVSTACK_LOCAL_CONFIG="enable_plugin senlin https://git.openstack.org/openstack/senlin" - if [ "api" == "api" ]||[ "api" == "functional" ]; then + if [ "${SENLIN_TEST_TYPE}" == "api" ]||[ "${SENLIN_TEST_TYPE}" == "functional" ]; then export SENLIN_BACKEND="openstack_test" else export SENLIN_BACKEND="openstack" @@ -76,6 +77,10 @@ export DEVSTACK_LOCAL_CONFIG+=$'\n'"enable_plugin zaqar git://git.openstack.org/openstack/zaqar" fi + # use senlin-tempest-plugin + export PROJECTS="openstack/senlin-tempest-plugin $PROJECTS" + export DEVSTACK_LOCAL_CONFIG+=$'\n'"TEMPEST_PLUGINS+=' /opt/stack/new/senlin-tempest-plugin'" + export OVERRIDE_ENABLED_SERVICES=$services if [ "$BRANCH_OVERRIDE" != "default" ] ; then @@ -90,7 +95,7 @@ function post_test_hook { cd /opt/stack/new/senlin/senlin/tests/tempest/ - ./post_test_hook.sh + ./post_test_hook.sh senlin_tempest_plugin.tests.${SENLIN_TEST_TYPE} } export -f post_test_hook diff --git a/playbooks/legacy/senlin-dsvm-tempest-py35-functional/run.yaml b/playbooks/legacy/senlin-dsvm-tempest-py35-functional/run.yaml index ae6f147f6..37ce4d700 100644 --- a/playbooks/legacy/senlin-dsvm-tempest-py35-functional/run.yaml +++ b/playbooks/legacy/senlin-dsvm-tempest-py35-functional/run.yaml @@ -43,7 +43,8 @@ export DEVSTACK_GATE_USE_PYTHON3=False fi - export DEVSTACK_GATE_TEMPEST_REGEX="senlin.tests.tempest.functional" + export SENLIN_TEST_TYPE="functional" + export DEVSTACK_GATE_TEMPEST_REGEX="senlin_tempest_plugin.tests.${SENLIN_TEST_TYPE}" services=rabbit,mysql,dstat,key,tempest services+=,g-api,g-reg @@ -58,7 +59,7 @@ export PROJECTS="openstack/senlin $PROJECTS" export DEVSTACK_LOCAL_CONFIG="enable_plugin senlin https://git.openstack.org/openstack/senlin" - if [ "functional" == "api" ]||[ "functional" == "functional" ]; then + if [ "${SENLIN_TEST_TYPE}" == "api" ]||[ "${SENLIN_TEST_TYPE}" == "functional" ]; then export SENLIN_BACKEND="openstack_test" else export SENLIN_BACKEND="openstack" @@ -77,6 +78,10 @@ export DEVSTACK_LOCAL_CONFIG+=$'\n'"enable_plugin zaqar git://git.openstack.org/openstack/zaqar" fi + # use senlin-tempest-plugin + export PROJECTS="openstack/senlin-tempest-plugin $PROJECTS" + export DEVSTACK_LOCAL_CONFIG+=$'\n'"TEMPEST_PLUGINS+=' /opt/stack/new/senlin-tempest-plugin'" + export OVERRIDE_ENABLED_SERVICES=$services if [ "$BRANCH_OVERRIDE" != "default" ] ; then @@ -91,7 +96,7 @@ function post_test_hook { cd /opt/stack/new/senlin/senlin/tests/tempest/ - ./post_test_hook.sh + ./post_test_hook.sh senlin_tempest_plugin.tests.${SENLIN_TEST_TYPE} } export -f post_test_hook diff --git a/playbooks/legacy/senlin-dsvm-tempest-py35-integration/run.yaml b/playbooks/legacy/senlin-dsvm-tempest-py35-integration/run.yaml index 0b45469c6..d5d04edfa 100644 --- a/playbooks/legacy/senlin-dsvm-tempest-py35-integration/run.yaml +++ b/playbooks/legacy/senlin-dsvm-tempest-py35-integration/run.yaml @@ -43,7 +43,8 @@ export DEVSTACK_GATE_USE_PYTHON3=False fi - export DEVSTACK_GATE_TEMPEST_REGEX="senlin.tests.tempest.integration" + export SENLIN_TEST_TYPE="integration" + export DEVSTACK_GATE_TEMPEST_REGEX="senlin_tempest_plugin.tests.${SENLIN_TEST_TYPE}" services=rabbit,mysql,dstat,key,tempest services+=,g-api,g-reg @@ -58,7 +59,7 @@ export PROJECTS="openstack/senlin $PROJECTS" export DEVSTACK_LOCAL_CONFIG="enable_plugin senlin https://git.openstack.org/openstack/senlin" - if [ "integration" == "api" ]||[ "integration" == "functional" ]; then + if [ "${SENLIN_TEST_TYPE}" == "api" ]||[ "${SENLIN_TEST_TYPE}" == "functional" ]; then export SENLIN_BACKEND="openstack_test" else export SENLIN_BACKEND="openstack" @@ -75,8 +76,14 @@ export PROJECTS="openstack/python-zaqarclient $PROJECTS" export PROJECTS="openstack/zaqar-ui $PROJECTS" export DEVSTACK_LOCAL_CONFIG+=$'\n'"enable_plugin zaqar git://git.openstack.org/openstack/zaqar" + export PROJECTS="openstack/zaqar-tempest-plugin $PROJECTS" + export DEVSTACK_LOCAL_CONFIG+=$'\n'"TEMPEST_PLUGINS+=' /opt/stack/new/zaqar-tempest-plugin'" fi + # use senlin-tempest-plugin + export PROJECTS="openstack/senlin-tempest-plugin $PROJECTS" + export DEVSTACK_LOCAL_CONFIG+=$'\n'"TEMPEST_PLUGINS+=' /opt/stack/new/senlin-tempest-plugin'" + export OVERRIDE_ENABLED_SERVICES=$services if [ "$BRANCH_OVERRIDE" != "default" ] ; then @@ -91,7 +98,7 @@ function post_test_hook { cd /opt/stack/new/senlin/senlin/tests/tempest/ - ./post_test_hook.sh + ./post_test_hook.sh senlin_tempest_plugin.tests.${SENLIN_TEST_TYPE} } export -f post_test_hook diff --git a/senlin/api/openstack/v1/clusters.py b/senlin/api/openstack/v1/clusters.py index d9f7a5f43..bfad64629 100644 --- a/senlin/api/openstack/v1/clusters.py +++ b/senlin/api/openstack/v1/clusters.py @@ -302,15 +302,16 @@ class ClusterController(wsgi.Controller): @util.policy_enforce def delete(self, req, cluster_id, body=None): - if body: + if req.params.get('force') is not None: + force = util.parse_bool_param(consts.CLUSTER_DELETE_FORCE, + req.params.get('force')) + elif body: force = body.get('force') + if force is None: + force = False else: force = False - if force is not None: - force = util.parse_bool_param(consts.CLUSTER_DELETE_FORCE, - force) - params = {'identity': cluster_id, 'force': force} obj = util.parse_request('ClusterDeleteRequest', req, params) res = self.rpc_client.call(req.context, 'cluster_delete', obj) diff --git a/senlin/api/openstack/v1/nodes.py b/senlin/api/openstack/v1/nodes.py index b8d1a59b2..c8f2b02e8 100644 --- a/senlin/api/openstack/v1/nodes.py +++ b/senlin/api/openstack/v1/nodes.py @@ -126,8 +126,7 @@ class NodeController(wsgi.Controller): force = False if force is not None: - force = util.parse_bool_param(consts.NODE_DELETE_FORCE, - force) + force = util.parse_bool_param(consts.NODE_DELETE_FORCE, force) params = {'identity': node_id, 'force': force} diff --git a/senlin/objects/fields.py b/senlin/objects/fields.py index 6302f61a6..a761c1a1a 100644 --- a/senlin/objects/fields.py +++ b/senlin/objects/fields.py @@ -34,7 +34,6 @@ DateTimeField = fields.DateTimeField DictOfStringsField = fields.DictOfStringsField ListOfStringsField = fields.ListOfStringsField ListOfEnumField = fields.ListOfEnumField -ObjectField = fields.ObjectField class Boolean(fields.FieldType): @@ -78,6 +77,18 @@ class NonNegativeInteger(fields.FieldType): } +# Senlin has a stricter field checking for object fields. +class Object(fields.Object): + + def get_schema(self): + schema = super(Object, self).get_schema() + # we are not checking whether self._obj_name is registered, an + # exception will be raised anyway if it is not registered. + data_key = 'senlin_object.data' + schema['properties'][data_key]['additionalProperties'] = False + return schema + + class UUID(fields.FieldType): _PATTERN = (r'^[a-fA-F0-9]{8}-?[a-fA-F0-9]{4}-?[a-fA-F0-9]{4}-?[a-fA-F0-9]' @@ -393,6 +404,16 @@ class BooleanField(fields.AutoTypedField): AUTO_TYPE = Boolean() +# An override to the oslo.versionedobjects version so that we are using +# our own Object definition. +class ObjectField(fields.AutoTypedField): + + def __init__(self, objtype, subclasses=False, **kwargs): + self.AUTO_TYPE = Object(objtype, subclasses) + self.objname = objtype + super(ObjectField, self).__init__(**kwargs) + + class JsonField(fields.AutoTypedField): AUTO_TYPE = Json() diff --git a/senlin/profiles/os/nova/server.py b/senlin/profiles/os/nova/server.py index 03928bb40..740a37d01 100644 --- a/senlin/profiles/os/nova/server.py +++ b/senlin/profiles/os/nova/server.py @@ -1279,7 +1279,8 @@ class ServerProfile(base.Profile): else: image_id = server_data['image'] attached_volumes = [] - if len(server_data['attached_volumes']) > 0: + if ('attached_volumes' in server_data and + len(server_data['attached_volumes']) > 0): for volume in server_data['attached_volumes']: attached_volumes.append(volume['id']) details = { diff --git a/senlin/tests/drivers/openstack/__init__.py b/senlin/tests/drivers/openstack/__init__.py index 75c3e6564..a9b5f7725 100644 --- a/senlin/tests/drivers/openstack/__init__.py +++ b/senlin/tests/drivers/openstack/__init__.py @@ -19,6 +19,7 @@ from senlin.tests.drivers.openstack import lbaas from senlin.tests.drivers.openstack import mistral_v2 from senlin.tests.drivers.openstack import neutron_v2 from senlin.tests.drivers.openstack import nova_v2 +from senlin.tests.drivers.openstack import octavia_v2 compute = nova_v2.NovaClient @@ -26,6 +27,7 @@ identity = keystone_v3.KeystoneClient loadbalancing = lbaas.LoadBalancerDriver message = zaqar_v2.ZaqarClient network = neutron_v2.NeutronClient +octavia = octavia_v2.OctaviaClient orchestration = heat_v1.HeatClient telemetry = ceilometer_v2.CeilometerClient workflow = mistral_v2.MistralClient diff --git a/senlin/tests/drivers/openstack/neutron_v2.py b/senlin/tests/drivers/openstack/neutron_v2.py index f599201ae..3092bceae 100644 --- a/senlin/tests/drivers/openstack/neutron_v2.py +++ b/senlin/tests/drivers/openstack/neutron_v2.py @@ -32,6 +32,33 @@ class NeutronClient(base.DriverBase): "port_security_enabled": True, "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22" } + self.fake_port = { + "ip_address": "10.0.1.10", + "fixed_ips": [ + "172.17.1.129" + ], + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", + "status": "ACTIVE", + "subnet_id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0b", + "id": "60f65938-3ebb-451d-a3a3-a0918d345469", + "security_group_ids": [ + "45aa2abc-47f0-4008-8d67-606b41cabb7a" + ] + } + self.fake_subnet = { + "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", + "subnet_pool_id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0b", + "id": "60f65938-3ebb-451d-a3a3-a0918d345469" + } def network_get(self, value, ignore_missing=False): return sdk.FakeResourceObject(self.fake_network) + + def port_create(self, **attr): + return sdk.FakeResourceObject(self.fake_port) + + def port_delete(self, port, ignore_missing=True): + return None + + def subnet_get(self, name_or_id, ignore_missing=False): + return sdk.FakeResourceObject(self.fake_subnet) diff --git a/senlin/tests/drivers/openstack/octavia_v2.py b/senlin/tests/drivers/openstack/octavia_v2.py new file mode 100644 index 000000000..70d4ba9db --- /dev/null +++ b/senlin/tests/drivers/openstack/octavia_v2.py @@ -0,0 +1,26 @@ +# 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. + +from senlin.drivers import base + + +class OctaviaClient(base.DriverBase): + def __init__(self, params): + self.lb_result = { + "loadbalancer": "a36c20d0-18e9-42ce-88fd-82a35977ee8c", + "vip_address": "192.168.1.100", + "listener": "35cb8516-1173-4035-8dae-0dae3453f37f", + "pool": "4c0a0a5f-cf8f-44b7-b912-957daa8ce5e5", + "healthmonitor": "0a9ac99d-0a09-4b18-8499-a0796850279a" + } + + self.member_id = "9a7aff27-fd41-4ec1-ba4c-3eb92c629313" diff --git a/senlin/tests/tempest/README.rst b/senlin/tests/tempest/README.rst index 7d2a96aa8..054b446d1 100644 --- a/senlin/tests/tempest/README.rst +++ b/senlin/tests/tempest/README.rst @@ -1,21 +1,5 @@ -==================== -Tempest Integration -==================== +===== +MOVED +===== -This directory contains Tempest tests to cover senlin project. - -To list all senlin tempest cases, go to tempest directory, then run:: - - $ testr list-tests senlin - -To run only these tests in tempest, go to tempest directory, then run:: - - $ ./run_tempest.sh -N -- senlin - -To run a single test case, go to tempest directory, then run with test case name, e.g.:: - - $ ./run_tempest.sh -N -- senlin.tests.tempest.api.test_cluster_basic.TestClusterBasic.test_cluster_create_delete - -If you can't find run_tempest.sh script in tempest directory, that means the script has been removed in a certain version. -Then you can use "nosetests -v" to replace "./run_tempest.sh -N" in above command. -More information about running tempest test can be found here: https://docs.openstack.org/tempest/latest/ +The senlin tempest plugin has moved to http://git.openstack.org/cgit/openstack/senlin-tempest-plugin diff --git a/senlin/tests/tempest/__init__.py b/senlin/tests/tempest/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/api/__init__.py b/senlin/tests/tempest/api/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/api/actions/__init__.py b/senlin/tests/tempest/api/actions/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/api/actions/test_action_list.py b/senlin/tests/tempest/api/actions/test_action_list.py deleted file mode 100644 index 125e4a140..000000000 --- a/senlin/tests/tempest/api/actions/test_action_list.py +++ /dev/null @@ -1,44 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestActionList(base.BaseSenlinAPITest): - - def setUp(self): - super(TestActionList, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, cluster_id) - - @decorators.idempotent_id('2e47639b-7f58-4fb4-a147-a8c6bf184e97') - def test_action_list(self): - res = self.client.list_objs('actions') - - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - - actions = res['body'] - for action in actions: - for key in ['action', 'cause', 'created_at', 'data', - 'depended_by', 'depends_on', 'end_time', 'id', - 'inputs', 'interval', 'name', 'outputs', 'owner', - 'start_time', 'status', 'status_reason', 'target', - 'timeout', 'updated_at']: - self.assertIn(key, action) diff --git a/senlin/tests/tempest/api/actions/test_action_list_negative.py b/senlin/tests/tempest/api/actions/test_action_list_negative.py deleted file mode 100644 index c7ee08c62..000000000 --- a/senlin/tests/tempest/api/actions/test_action_list_negative.py +++ /dev/null @@ -1,86 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestActionListNegativeBadRequest(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('2f857bee-99a8-4881-bde9-5909e3ff121a') - def test_action_list_invalid_params(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'actions', {'bogus': 'foo'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Invalid parameter bogus", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('6b93221e-ca14-443b-be54-4423a636672a') - def test_action_list_limit_not_int(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'actions', {'limit': 'not-int'}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The value for limit must be an integer: 'not-int'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('d13e3011-32b5-4f9d-bb57-3532c4c46228') - def test_action_list_global_project_false(self): - ex = self.assertRaises(exceptions.Forbidden, - self.client.list_objs, - 'actions', {'global_project': 'True'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("You are not authorized to complete this operation.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('d7804b5e-6efd-4084-adec-531d0a8399dc') - def test_action_list_global_project_not_bool(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'actions', {'global_project': 'not-bool'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Invalid value 'not-bool' specified for " - "'global_project'", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('6ca48051-6030-4333-9483-074e03da5ba0') - def test_action_list_invalid_sort(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'actions', {'sort': 'bad-sort'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Unsupported sort key 'bad-sort' for 'sort'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('588517ed-bfcf-4d92-9d7c-5ed11fc2c2ee') - def test_action_list_invalid_marker(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'actions', {'marker': 'bad-marker'}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The value for marker is not a valid UUID: 'bad-marker'.", - str(message)) diff --git a/senlin/tests/tempest/api/actions/test_action_show.py b/senlin/tests/tempest/api/actions/test_action_show.py deleted file mode 100644 index 793fc7792..000000000 --- a/senlin/tests/tempest/api/actions/test_action_show.py +++ /dev/null @@ -1,57 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestActionShow(base.BaseSenlinAPITest): - - def setUp(self): - super(TestActionShow, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - params = { - 'cluster': { - 'profile_id': profile_id, - 'desired_capacity': 0, - 'min_size': 0, - 'max_size': -1, - 'timeout': None, - 'metadata': {}, - 'name': 'test-cluster-action-show' - } - } - res = self.client.create_obj('clusters', params) - self.action_id = res['location'].split('/actions/')[1] - self.addCleanup(utils.delete_a_cluster, self, res['body']['id']) - - self.client.wait_for_status('actions', self.action_id, 'SUCCEEDED') - - @decorators.idempotent_id('c6376f60-8f52-4384-8b6d-57df264f2e23') - def test_action_show(self): - res = self.client.get_obj('actions', self.action_id) - - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - - action = res['body'] - for key in ['action', 'cause', 'created_at', 'data', - 'depended_by', 'depends_on', 'end_time', 'id', - 'inputs', 'interval', 'name', 'outputs', 'owner', - 'start_time', 'status', 'status_reason', 'target', - 'timeout', 'updated_at']: - self.assertIn(key, action) diff --git a/senlin/tests/tempest/api/actions/test_action_show_negative.py b/senlin/tests/tempest/api/actions/test_action_show_negative.py deleted file mode 100644 index 9a4a68988..000000000 --- a/senlin/tests/tempest/api/actions/test_action_show_negative.py +++ /dev/null @@ -1,31 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestActionShowNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('26cb0f3a-4e6c-49f6-8475-7cb472933bff') - def test_action_show_not_found(self): - ex = self.assertRaises( - exceptions.NotFound, self.client.get_obj, - 'actions', '26cb0f3a-4e6c-49f6-8475-7cb472933bff') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The action '26cb0f3a-4e6c-49f6-8475-7cb472933bff' could " - "not be found.", str(message)) diff --git a/senlin/tests/tempest/api/api_versions/__init__.py b/senlin/tests/tempest/api/api_versions/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/api/api_versions/test_api_version_show.py b/senlin/tests/tempest/api/api_versions/test_api_version_show.py deleted file mode 100644 index e6d81c607..000000000 --- a/senlin/tests/tempest/api/api_versions/test_api_version_show.py +++ /dev/null @@ -1,31 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base - - -class TestAPIVersionShow(base.BaseSenlinAPITest): - - @decorators.idempotent_id('4a270caa-9917-4acd-98ef-6636f9618037') - def test_API_version_show(self): - resp, body = self.client.request('GET', '/v1/') - res = self.client.get_resp(resp, body) - - # Verify resp of API version show - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - version = res['body'] - for key in ['id', 'links', 'media-types', 'status', 'updated']: - self.assertIn(key, version) - self.assertEqual('1.0', version['id']) diff --git a/senlin/tests/tempest/api/api_versions/test_api_version_show_negative.py b/senlin/tests/tempest/api/api_versions/test_api_version_show_negative.py deleted file mode 100644 index 49ca9f3d0..000000000 --- a/senlin/tests/tempest/api/api_versions/test_api_version_show_negative.py +++ /dev/null @@ -1,26 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestAPIVersionShowNegative(base.BaseSenlinAPITest): - - @decorators.idempotent_id('a3b02638-2459-41ab-a70b-a6f1a269914e') - def test_API_version_show_invalid_version(self): - resp, body = self.client.request('GET', '/v1/') - self.assertRaises(exceptions.NotFound, - self.client.request, - 'GET', '/vx') diff --git a/senlin/tests/tempest/api/api_versions/test_api_versions_list.py b/senlin/tests/tempest/api/api_versions/test_api_versions_list.py deleted file mode 100644 index 2ef398d03..000000000 --- a/senlin/tests/tempest/api/api_versions/test_api_versions_list.py +++ /dev/null @@ -1,35 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base - - -class TestAPIVersions(base.BaseSenlinAPITest): - - @decorators.idempotent_id('c7378a80-9a82-4148-937d-25e046c6316f') - def test_API_versions_list(self): - resp, body = self.client.request('GET', '/') - res = self.client.get_resp(resp, body) - - # Verify resp of API versions list - self.assertEqual(300, res['status']) - self.assertIsNotNone(res['body']) - versions = res['body'] - for version in versions: - for key in ['id', 'links', 'max_version', 'media-types', - 'min_version', 'status', 'updated']: - self.assertIn(key, version) - # Only version 1.0 API is now supported - self.assertEqual(1, len(versions)) - self.assertEqual('1.0', versions[0]['id']) diff --git a/senlin/tests/tempest/api/base.py b/senlin/tests/tempest/api/base.py deleted file mode 100644 index bbcad05bf..000000000 --- a/senlin/tests/tempest/api/base.py +++ /dev/null @@ -1,55 +0,0 @@ -# -# 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. - -from tempest import config - -from senlin.tests.tempest import base -from senlin.tests.tempest.common import clustering_client -from senlin.tests.tempest.common import compute_client -from senlin.tests.tempest.common import network_client - -CONF = config.CONF - - -class BaseSenlinAPITest(base.BaseSenlinTest): - - @classmethod - def setup_credentials(cls): - # Set no network resources for test accounts - cls.set_network_resources() - super(BaseSenlinAPITest, cls).setup_credentials() - - @classmethod - def setup_clients(cls): - super(BaseSenlinAPITest, cls).setup_clients() - cls.client = clustering_client.ClusteringAPIClient( - cls.os_primary.auth_provider, - CONF.clustering.catalog_type, - CONF.identity.region, - **cls.default_params_with_timeout_values - ) - - cls.compute_client = compute_client.V21ComputeClient( - cls.os_primary.auth_provider, - CONF.compute.catalog_type, - CONF.identity.region, - **cls.default_params_with_timeout_values - ) - - cls.network_client = network_client.NetworkClient( - cls.os_primary.auth_provider, - CONF.network.catalog_type, - CONF.identity.region, - **cls.default_params_with_timeout_values - ) diff --git a/senlin/tests/tempest/api/build_info/__init__.py b/senlin/tests/tempest/api/build_info/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/api/build_info/test_build_info.py b/senlin/tests/tempest/api/build_info/test_build_info.py deleted file mode 100644 index 9e94f2968..000000000 --- a/senlin/tests/tempest/api/build_info/test_build_info.py +++ /dev/null @@ -1,29 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base - - -class TestBuildInfo(base.BaseSenlinAPITest): - - @decorators.idempotent_id('bf7a8bdf-d896-49ff-a7a8-7c8fdbfc3667') - def test_build_info_get(self): - uri = '{0}/build-info'.format(self.client.version) - resp, info = self.client.get(uri) - - # Verify resp of get build-info API - self.assertEqual(200, int(resp['status'])) - self.assertIsNotNone(info) - for key in ['api', 'engine']: - self.assertIn(key, info) diff --git a/senlin/tests/tempest/api/cluster_policies/__init__.py b/senlin/tests/tempest/api/cluster_policies/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/api/cluster_policies/test_cluster_policy_list.py b/senlin/tests/tempest/api/cluster_policies/test_cluster_policy_list.py deleted file mode 100644 index 887df28b7..000000000 --- a/senlin/tests/tempest/api/cluster_policies/test_cluster_policy_list.py +++ /dev/null @@ -1,49 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterPolicyList(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterPolicyList, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - self.policy_id = utils.create_a_policy(self) - self.addCleanup(utils.delete_a_policy, self, self.policy_id) - - utils.cluster_attach_policy(self, self.cluster_id, self.policy_id) - self.addCleanup(utils.cluster_detach_policy, self, self.cluster_id, - self.policy_id) - - @decorators.idempotent_id('ebaeedcb-7198-4997-9b9c-a8f1eccfc2a6') - def test_cluster_policy_list(self): - res = self.client.list_cluster_policies(self.cluster_id) - - # Verify resp of cluster policy list API - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - policies = res['body'] - self.assertEqual(1, len(policies)) - for key in ['cluster_id', 'cluster_name', 'enabled', 'id', - 'policy_id', 'policy_name', 'policy_type']: - self.assertIn(key, policies[0]) - self.assertEqual(self.policy_id, policies[0]['policy_id']) diff --git a/senlin/tests/tempest/api/cluster_policies/test_cluster_policy_list_negative.py b/senlin/tests/tempest/api/cluster_policies/test_cluster_policy_list_negative.py deleted file mode 100644 index 1fbdb3ef5..000000000 --- a/senlin/tests/tempest/api/cluster_policies/test_cluster_policy_list_negative.py +++ /dev/null @@ -1,66 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestClusterPolicyListNegativeBadRequest(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('7f23de64-60c4-456e-9e24-db86ac89480c') - def test_cluster_policy_list_invalid_params(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_cluster_policies, - '7f23de64-60c4-456e-9e24-db86ac89480c', - {'bogus': 'foo'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Invalid parameter bogus", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('0259cbac-0fb3-480b-8f23-1ec59616f3af') - def test_cluster_policy_list_cluster_not_found(self): - ex = self.assertRaises(exceptions.NotFound, - self.client.list_cluster_policies, - '0259cbac-0fb3-480b-8f23-1ec59616f3af') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster '0259cbac-0fb3-480b-8f23-1ec59616f3af' " - "could not be found.", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('958c6fd2-a647-4b5a-8133-8b4232267b40') - def test_cluster_policy_list_invalid_sort(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_cluster_policies, - '958c6fd2-a647-4b5a-8133-8b4232267b40', - {'sort': 'bad-sort'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Unsupported sort key 'bad-sort' for 'sort'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('0e59c1c7-7477-45ee-8f12-7e5b87373bf7') - def test_cluster_policy_list_enabled_not_bool(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_cluster_policies, - '0e59c1c7-7477-45ee-8f12-7e5b87373bf7', - {'enabled': 'bad-enabled'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Invalid value 'bad-enabled' specified for 'enabled'", - str(message)) diff --git a/senlin/tests/tempest/api/cluster_policies/test_cluster_policy_show.py b/senlin/tests/tempest/api/cluster_policies/test_cluster_policy_show.py deleted file mode 100644 index 78f3f7aed..000000000 --- a/senlin/tests/tempest/api/cluster_policies/test_cluster_policy_show.py +++ /dev/null @@ -1,48 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterPolicyShow(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterPolicyShow, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - self.policy_id = utils.create_a_policy(self) - self.addCleanup(utils.delete_a_policy, self, self.policy_id) - - utils.cluster_attach_policy(self, self.cluster_id, self.policy_id) - self.addCleanup(utils.cluster_detach_policy, self, self.cluster_id, - self.policy_id) - - @decorators.idempotent_id('fdf4dbf9-fcc6-4eb0-96c1-d8e8caa90f6d') - def test_cluster_policy_show(self): - res = self.client.get_cluster_policy(self.cluster_id, self.policy_id) - - # Verify resp of cluster policy show API - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - policy = res['body'] - for key in ['cluster_id', 'cluster_name', 'id', 'policy_id', - 'policy_name', 'policy_type', 'enabled']: - self.assertIn(key, policy) - self.assertEqual(self.policy_id, policy['policy_id']) diff --git a/senlin/tests/tempest/api/cluster_policies/test_cluster_policy_show_negative.py b/senlin/tests/tempest/api/cluster_policies/test_cluster_policy_show_negative.py deleted file mode 100644 index d9338f812..000000000 --- a/senlin/tests/tempest/api/cluster_policies/test_cluster_policy_show_negative.py +++ /dev/null @@ -1,117 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterPolicyShowNegativeClusterNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('965d7324-e3f7-4d77-8e7f-44c862b851f7') - def test_cluster_policy_show_cluster_not_found(self): - ex = self.assertRaises(exceptions.NotFound, - self.client.get_cluster_policy, - '965d7324-e3f7-4d77-8e7f-44c862b851f7', - 'POLICY_ID') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster '965d7324-e3f7-4d77-8e7f-44c862b851f7' " - "could not be found.", str(message)) - - -class TestClusterPolicyShowNegativePolicyNotFound(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterPolicyShowNegativePolicyNotFound, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('e3e24058-ed07-42b6-b47c-a972c6047509') - def test_cluster_policy_show_policy_not_found(self): - ex = self.assertRaises(exceptions.NotFound, - self.client.get_cluster_policy, - self.cluster_id, - 'fake_policy') - - message = ex.resp_body['error']['message'] - self.assertEqual("The policy 'fake_policy' could not be found.", - str(message)) - - -class TestClusterPolicyShowNegativeNoPolicyBinding(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterPolicyShowNegativeNoPolicyBinding, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - self.policy_id = utils.create_a_policy(self) - self.addCleanup(utils.delete_a_policy, self, self.policy_id) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('9c9e01fc-dfb9-4a27-9a06-f4d6de2b2d1c') - def test_cluster_policy_show_no_policy_binding(self): - ex = self.assertRaises(exceptions.NotFound, - self.client.get_cluster_policy, - self.cluster_id, self.policy_id) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The policy '%s' is not found attached to the specified cluster " - "'%s'." % (self.policy_id, self.cluster_id), str(message)) - - -class TestClusterPolicyShowNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterPolicyShowNegativeBadRequest, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - self.policy_id1 = utils.create_a_policy(self, name='test-policy') - self.addCleanup(utils.delete_a_policy, self, self.policy_id1) - self.policy_id2 = utils.create_a_policy(self, name='test-policy') - self.addCleanup(utils.delete_a_policy, self, self.policy_id2) - - utils.cluster_attach_policy(self, self.cluster_id, self.policy_id1) - self.addCleanup(utils.cluster_detach_policy, self, self.cluster_id, - self.policy_id1) - utils.cluster_attach_policy(self, self.cluster_id, self.policy_id2) - self.addCleanup(utils.cluster_detach_policy, self, self.cluster_id, - self.policy_id2) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('3faaaf65-0606-4853-a660-2bb04f10485b') - def test_cluster_policy_show_multiple_choice(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.get_cluster_policy, - self.cluster_id, 'test-policy') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Multiple results found matching the query criteria " - "'test-policy'. Please be more specific.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/__init__.py b/senlin/tests/tempest/api/clusters/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/api/clusters/test_cluster_action_negative.py b/senlin/tests/tempest/api/clusters/test_cluster_action_negative.py deleted file mode 100644 index c21a56ce1..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_action_negative.py +++ /dev/null @@ -1,64 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestClusterActionNegativeCommon(base.BaseSenlinAPITest): - - @decorators.idempotent_id('9c972d49-81bd-4448-9afc-b93053aa835d') - def test_cluster_action_no_action_specified(self): - # No action is specified - params = {} - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("No action specified", str(message)) - - @decorators.idempotent_id('997d2e19-7914-4883-9b6a-86e907898d3b') - def test_cluster_action_multiple_action_specified(self): - # Multiple actions are specified - params = { - 'resize': {}, - 'check': {} - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Multiple actions specified", str(message)) - - @decorators.idempotent_id('43e142ac-9579-40d9-845a-b8190691b91a') - def test_cluster_action_unrecognized_action(self): - # Unrecognized action is specified - params = { - 'bogus': {} - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Unrecognized action 'bogus' specified", - str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_add_nodes.py b/senlin/tests/tempest/api/clusters/test_cluster_add_nodes.py deleted file mode 100644 index 1a957f1c9..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_add_nodes.py +++ /dev/null @@ -1,270 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants -from senlin.tests.tempest.common import utils - - -class TestClusterActionAddNodes(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterActionAddNodes, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.node_id = utils.create_a_node(self, self.profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @decorators.idempotent_id('db0faadf-9cd2-457f-b434-4891b77938ab') - def test_cluster_action_add_nodes(self): - params = { - "add_nodes": { - "nodes": [ - self.node_id - ] - } - } - # Trigger cluster action - res = self.client.trigger_action('clusters', self.cluster_id, - params=params) - - # Verify resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - -class TestClusterAddNodesNegativeInvalidNodesParams(base.BaseSenlinAPITest): - - @decorators.idempotent_id('912bb24d-73e1-4801-a6de-bdd453cbbdbf') - def test_cluster_add_nodes_missing_nodes_params(self): - params = { - 'add_nodes': { - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Value for 'nodes' must have at least 1 item(s).", - str(message)) - - @decorators.idempotent_id('6cb029f7-9b72-4f10-a28b-3ed5bd3ed7b0') - def test_cluster_add_nodes_params_not_list(self): - params = { - 'add_nodes': { - 'nodes': 'node_id' - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Items for 'nodes' must be unique", str(message)) - - @decorators.idempotent_id('b8ae9b5f-967f-48a6-8e31-c77f86ba06aa') - def test_cluster_add_nodes_params_empty_list(self): - params = { - 'add_nodes': { - 'nodes': [] - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Value for 'nodes' must have at least 1 item(s).", - str(message)) - - @decorators.idempotent_id('a97f1712-46ba-43c1-abd6-12c209c9d640') - def test_cluster_add_mult_node_with_same_name(self): - params = { - 'add_nodes': { - 'nodes': ['id1', 'id1'] - } - } - - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Items for 'nodes' must be unique", - str(message)) - - -class TestClusterAddNodesNegativeNodeNotFound(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterAddNodesNegativeNodeNotFound, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('5ddf7e5a-3f67-4f1e-af1e-c5a7da319dc0') - def test_cluster_add_nodes_node_not_found(self): - params = { - 'add_nodes': { - 'nodes': ['5ddf7e5a-3f67-4f1e-af1e-c5a7da319dc0'] - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Nodes not found: [u'5ddf7e5a-3f67-4f1e-af1e-c5a7da319dc0'].", - str(message)) - - -class TestClusterAddNodesNegativeNodeNotOrphan(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterAddNodesNegativeNodeNotOrphan, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - self.cluster_id2 = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id2) - self.node_id = utils.create_a_node(self, self.profile_id, - cluster_id=self.cluster_id2) - - @decorators.idempotent_id('08e1271c-025e-4670-a20e-4a96fa179dca') - def test_cluster_add_nodes_node_not_orphan(self): - params = { - 'add_nodes': { - 'nodes': [self.node_id] - } - } - - # Verify conflict exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Nodes ['%s'] already owned by some cluster." % self.node_id, - str(message)) - - -class TestClusterAddNodesNegativeProfileTypeUnmatch(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterAddNodesNegativeProfileTypeUnmatch, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - self.profile_id2 = utils.create_a_profile( - self, spec=constants.spec_heat_stack) - self.addCleanup(utils.delete_a_profile, self, self.profile_id2) - self.node_id = utils.create_a_node(self, self.profile_id2) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @decorators.idempotent_id('7a27c697-6d29-46f0-8b2a-3a7282c15b33') - def test_cluster_add_nodes_profile_type_unmatch(self): - params = { - 'add_nodes': { - 'nodes': [ - self.node_id - ] - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Profile type of nodes ['%s'] does not match that of the " - "cluster." % self.node_id, str(message)) - - -class TestClusterAddNodesNegativeSizeCheckFailed(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterAddNodesNegativeSizeCheckFailed, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id, - desired_capacity=1, - max_size=1) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.node_id = utils.create_a_node(self, self.profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @decorators.idempotent_id('3b485352-53e3-481d-b471-9a042c76d758') - def test_cluster_add_nodes_cluster_size_check_failed(self): - params = { - 'add_nodes': { - 'nodes': [ - self.node_id - ] - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The target capacity (2) is greater than the cluster's " - "max_size (1).", str(message)) - - -class TestClusterAddNodesNegativeClusterNotFound(base.BaseSenlinAPITest): - - @decorators.idempotent_id('22f10d36-c29a-4cde-a975-af262a5775a1') - def test_cluster_add_nodes_cluster_not_found(self): - params = { - 'add_nodes': { - 'nodes': ['node_id'] - } - } - - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.trigger_action, 'clusters', - 'db0faadf-9cd2-457f-b434-4891b77938ab', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster 'db0faadf-9cd2-457f-b434-4891b77938ab' " - "could not be found.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_check.py b/senlin/tests/tempest/api/clusters/test_cluster_check.py deleted file mode 100644 index 6758f7ab7..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_check.py +++ /dev/null @@ -1,79 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterActionCheck(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterActionCheck, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id, - desired_capacity=1) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('0d2063a8-b3d3-489d-b949-e2c61a0997ee') - def test_cluster_action_check(self): - params = { - "check": {} - } - # Trigger cluster action - res = self.client.trigger_action('clusters', self.cluster_id, - params=params) - - # Verify resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - -class TestClusterCheckNegativeInvalidParams(base.BaseSenlinAPITest): - - @decorators.idempotent_id('9a305b4f-2f05-4aa9-95ae-e08fd24b0593') - def test_cluster_check_params_not_dict(self): - params = { - 'check': ['k1', 'v1'] - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("The data provided is not a map", str(message)) - - -class TestClusterCheckNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.idempotent_id('bbbe3feb-8482-4ae4-9c29-b4732efce931') - def test_cluster_check_cluster_not_found(self): - params = { - 'check': {'k1': 'v1'} - } - - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.trigger_action, 'clusters', - 'bbbe3feb-8482-4ae4-9c29-b4732efce931', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("The cluster 'bbbe3feb-8482-4ae4-9c29-b4732efce931' " - "could not be found.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_collect.py b/senlin/tests/tempest/api/clusters/test_cluster_collect.py deleted file mode 100644 index 7cd7676d3..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_collect.py +++ /dev/null @@ -1,96 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterCollect(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterCollect, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.node1 = utils.create_a_node(self, profile_id, name='N01', - cluster_id=self.cluster_id) - self.addCleanup(utils.delete_a_node, self, self.node1) - self.node2 = utils.create_a_node(self, profile_id, name='N02', - cluster_id=self.cluster_id) - self.addCleanup(utils.delete_a_node, self, self.node2) - - @utils.api_microversion('1.2') - @decorators.idempotent_id('00c389f8-3e83-4171-bd72-2202f1f3954d') - def test_cluster_collect(self): - # Collect on a basic path - res = self.client.cluster_collect(self.cluster_id, path='name') - - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - self.assertIn({u'id': self.node1, u'value': u'N01'}, res['body']) - self.assertIn({u'id': self.node2, u'value': u'N02'}, res['body']) - - @utils.api_microversion('1.2') - @decorators.idempotent_id('1ec4ca67-20db-43eb-95af-1301aa2b1948') - def test_cluster_collect_details(self): - # Collect on a basic path - res = self.client.cluster_collect(self.cluster_id, - path='details.status') - - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - self.assertIn({u'id': self.node1, u'value': u'ACTIVE'}, res['body']) - self.assertIn({u'id': self.node2, u'value': u'ACTIVE'}, res['body']) - - -class TestClusterCollectNegative(base.BaseSenlinAPITest): - - @utils.api_microversion('1.1') - @decorators.idempotent_id('88fff27d-27eb-4a4d-906b-b3a9761072ba') - def test_cluster_collect_failed_api_version(self): - # Collect on a basic path - ex = self.assertRaises(exceptions.BadRequest, - self.client.cluster_collect, - 'FAKE_CLUSTER', path='name') - - message = ex.resp_body['error']['message'] - self.assertEqual("API version '1.1' is not supported on this method.", - str(message)) - - @utils.api_microversion('1.2') - @decorators.idempotent_id('a3d59666-93be-47ee-a484-c248ed2f49fe') - def test_cluster_collect_failed_path(self): - # Collect on a basic path - ex = self.assertRaises(exceptions.BadRequest, - self.client.cluster_collect, - 'FAKE_CLUSTER', path='None') - - message = ex.resp_body['error']['message'] - self.assertEqual("Required path attribute is missing.", - str(message)) - - @utils.api_microversion('1.2') - @decorators.idempotent_id('a3d59666-93be-47ee-a484-c248ed2f49fe') - def test_cluster_collect_cluster_not_found(self): - # Collect on a basic path - ex = self.assertRaises(exceptions.NotFound, - self.client.cluster_collect, - 'a3d59666-93be-47ee-a484-c248ed2f49fe', - path='name') - - message = ex.resp_body['error']['message'] - self.assertEqual("The cluster 'a3d59666-93be-47ee-a484-c248ed2f49fe' " - "could not be found.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_create.py b/senlin/tests/tempest/api/clusters/test_cluster_create.py deleted file mode 100644 index aa02717ab..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_create.py +++ /dev/null @@ -1,70 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterCreate(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterCreate, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.profile_id = profile_id - - @decorators.idempotent_id('61cbe340-937a-40d5-9d2f-067f2c7cafcc') - def test_cluster_create_all_attrs_defined(self): - # Create cluster - name = 'test-cluster' - desired_capacity = 2 - min_size = 1 - max_size = 3 - metadata = {'k1': 'v1'} - timeout = 120 - params = { - 'cluster': { - 'profile_id': self.profile_id, - 'desired_capacity': desired_capacity, - 'min_size': min_size, - 'max_size': max_size, - 'timeout': timeout, - 'metadata': {'k1': 'v1'}, - 'name': name - } - } - res = self.client.create_obj('clusters', params) - - # Verify resp of cluster create API - self.assertEqual(202, res['status']) - self.assertIsNotNone(res['body']) - self.assertIn('actions', res['location']) - cluster = res['body'] - for key in ['created_at', 'data', 'domain', 'id', 'init_at', 'nodes', - 'policies', 'profile_id', 'profile_name', 'project', - 'status', 'status_reason', 'updated_at', 'user']: - self.assertIn(key, cluster) - self.assertIn(name, cluster['name']) - self.assertEqual(desired_capacity, cluster['desired_capacity']) - self.assertEqual(min_size, cluster['min_size']) - self.assertEqual(max_size, cluster['max_size']) - self.assertEqual(metadata, cluster['metadata']) - self.assertEqual(timeout, cluster['timeout']) - - # Wait cluster to be active before moving on - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - self.addCleanup(utils.delete_a_cluster, self, cluster['id']) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_create_negative.py b/senlin/tests/tempest/api/clusters/test_cluster_create_negative.py deleted file mode 100644 index ef4e84436..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_create_negative.py +++ /dev/null @@ -1,111 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterCreateNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterCreateNegativeBadRequest, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.profile_id = profile_id - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('498a06eb-8c5f-4d9e-852f-87ac295f1a96') - def test_cluster_create_cluster_data_not_specified(self): - # cluster key is missing in request data - params = { - 'bad': { - 'profile_id': self.profile_id, - 'name': 'test-cluster' - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'clusters', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Request body missing 'cluster' key.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('3aced30b-ccb2-4e40-90c2-7b6aa205e3d6') - def test_cluster_create_profile_invalid(self): - # Invalid profile_id is provided - params = { - 'cluster': { - 'profile_id': '3aced30b-ccb2-4e40-90c2-7b6aa205e3d6', - 'name': 'test-cluster' - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'clusters', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified profile '3aced30b-ccb2-4e40-90c2-7b6aa205e3d6' " - "could not be found.", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('61b190bb-ef5a-47b3-acbe-6467fbb44439') - def test_cluster_create_miss_profile(self): - # Invalid profile_id is provided - params = { - 'cluster': { - 'name': 'test-cluster' - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'clusters', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("'profile_id' is a required property", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('7eaf60c3-f33d-403b-a4ee-0276ae90928c') - def test_cluster_create_size_constraint_illegal(self): - # Invalid size limitation is defined: min_size > max_size - desired_capacity = 2 - min_size = 5 - max_size = 3 - params = { - 'cluster': { - 'profile_id': self.profile_id, - 'desired_capacity': desired_capacity, - 'min_size': min_size, - 'max_size': max_size, - 'name': 'test-cluster' - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'clusters', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("The target capacity (2) is less than the " - "specified min_size (5).", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_del_nodes.py b/senlin/tests/tempest/api/clusters/test_cluster_del_nodes.py deleted file mode 100644 index 8977d4ceb..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_del_nodes.py +++ /dev/null @@ -1,265 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterActionDelNodes(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterActionDelNodes, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.node_id = utils.create_a_node(self, profile_id, - cluster_id=self.cluster_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @decorators.idempotent_id('ab4e0738-98f9-4521-a4a9-81ed151b4c71') - def test_cluster_action_del_nodes(self): - params = { - "del_nodes": { - "nodes": [ - self.node_id - ] - } - } - # Trigger cluster action - res = self.client.trigger_action('clusters', self.cluster_id, - params=params) - - # Verify resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - -class TestClusterDelNodesNegativeInvalidNodesParams(base.BaseSenlinAPITest): - - @decorators.idempotent_id('89af1e6f-17b4-4c6f-ae5f-91a2da784c05') - def test_cluster_del_nodes_missing_nodes_params(self): - params = { - 'del_nodes': { - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Value for 'nodes' must have at least 1 item(s).", - str(message)) - - @decorators.idempotent_id('c15c387c-3c3c-4005-8818-8fc0cdbfe679') - def test_cluster_del_nodes_params_not_list(self): - params = { - 'del_nodes': { - 'nodes': 'node_id' - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Items for 'nodes' must be unique", - str(message)) - - @decorators.idempotent_id('662c548d-a89a-40e3-a238-72b2193e5dc2') - def test_cluster_del_nodes_params_empty_list(self): - params = { - 'del_nodes': { - 'nodes': [] - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Value for 'nodes' must have at least 1 item(s).", - str(message)) - - @decorators.idempotent_id('26479afe-b8bf-4389-85b2-cccf6b83d2b7') - def test_cluster_del_nodes_destroy_not_bool(self): - params = { - 'del_nodes': { - 'nodes': ['fake_id'], - 'destroy_after_deletion': 'not_bool' - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Unrecognized value 'not_bool', acceptable values are: '0', '1', " - "'f', 'false', 'n', 'no', 'off', 'on', 't', 'true', 'y', 'yes'", - str(message)) - - -class TestClusterDelNodesNegativeNodeNotFound(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterDelNodesNegativeNodeNotFound, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('e896948b-44c0-4dfa-9466-407391504833') - def test_cluster_del_nodes_node_not_found(self): - params = { - 'del_nodes': { - 'nodes': ['e896948b-44c0-4dfa-9466-407391504833'] - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Nodes not found: [u'e896948b-44c0-4dfa-9466-407391504833'].", - str(message)) - - -class TestClusterDelNodesNegativeOrphanNode(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterDelNodesNegativeOrphanNode, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.node_id = utils.create_a_node(self, self.profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @decorators.idempotent_id('d7e77bd2-2a80-4995-b2e8-e4e9c58b3de5') - def test_cluster_del_nodes_orphan_node(self): - params = { - 'del_nodes': { - 'nodes': [self.node_id] - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Nodes not members of specified cluster: " - "['%s']." % self.node_id, str(message)) - - -class TestClusterDelNodesNegativeNodeOfOtherCluster(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterDelNodesNegativeNodeOfOtherCluster, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.cluster_id2 = utils.create_a_cluster(self, self.profile_id) - self.node_id = utils.create_a_node(self, self.profile_id, - cluster_id=self.cluster_id2) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id2) - - @decorators.idempotent_id('e83135af-1d42-4a80-a039-7e78cbc7e3f4') - def test_cluster_del_nodes_node_of_other_cluster(self): - params = { - 'del_nodes': { - 'nodes': [self.node_id] - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Nodes not members of specified cluster: " - "['%s']." % self.node_id, str(message)) - - -class TestClusterDelNodesNegativeSizeCheckFailed(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterDelNodesNegativeSizeCheckFailed, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id, - desired_capacity=1, - min_size=1) - self.cluster = utils.get_a_cluster(self, self.cluster_id) - self.node_id = self.cluster['nodes'][0] - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('b83bdeac-8d23-46ec-9c50-8c47140982a4') - def test_cluster_del_nodes_cluster_size_check_failed(self): - params = { - 'del_nodes': { - 'nodes': [ - self.node_id - ] - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual("The target capacity (0) is less than the cluster's " - "min_size (1).", str(message)) - - -class TestClusterDelNodesNegativeClusterNotFound(base.BaseSenlinAPITest): - - @decorators.idempotent_id('dc8f106a-10b7-47a3-8494-c86035207351') - def test_cluster_del_nodes_cluster_not_found(self): - params = { - 'del_nodes': { - 'nodes': ['node_id'] - } - } - - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.trigger_action, 'clusters', - 'dc8f106a-10b7-47a3-8494-c86035207351', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster 'dc8f106a-10b7-47a3-8494-c86035207351' could not " - "be found.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_delete.py b/senlin/tests/tempest/api/clusters/test_cluster_delete.py deleted file mode 100644 index 38a760e80..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_delete.py +++ /dev/null @@ -1,39 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterDelete(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterDelete, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - # cluster will be deleted by test case - self.cluster_id = utils.create_a_cluster(self, profile_id) - - @decorators.idempotent_id('33d7426e-0138-42c9-9ab4-ba796a7d1fdc') - def test_cluster_delete_in_active_status(self): - res = self.client.delete_obj('clusters', self.cluster_id) - - # Verify resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIsNone(res['body']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') diff --git a/senlin/tests/tempest/api/clusters/test_cluster_delete_negative.py b/senlin/tests/tempest/api/clusters/test_cluster_delete_negative.py deleted file mode 100644 index 85079c3b0..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_delete_negative.py +++ /dev/null @@ -1,124 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterDeleteNegativePolicyConflict(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterDeleteNegativePolicyConflict, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - policy_id = utils.create_a_policy(self) - self.addCleanup(utils.delete_a_policy, self, policy_id) - - utils.cluster_attach_policy(self, self.cluster_id, policy_id) - self.addCleanup(utils.cluster_detach_policy, self, self.cluster_id, - policy_id) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('0de81427-2b2f-4821-9462-c893d35fb212') - def test_cluster_delete_policy_conflict(self): - # Verify conflict exception(409) is raised. - ex = self.assertRaises(exceptions.Conflict, - self.client.delete_obj, - 'clusters', self.cluster_id) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster '%s' cannot be deleted: there is still " - "policy(s) attached to it." % self.cluster_id, - str(message)) - - -class TestClusterDeleteNegativeReceiverConflict(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterDeleteNegativeReceiverConflict, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - self.receiver_id = utils.create_a_receiver( - self, self.cluster_id, 'CLUSTER_SCALE_OUT', 'webhook', - 'fake', params={'count': '1'}) - self.addCleanup(utils.delete_a_receiver, self, self.receiver_id) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('0de81427-2b2f-4821-9462-c893d35fb212') - def test_cluster_delete_receiver_conflict(self): - # Verify conflict exception(409) is raised. - ex = self.assertRaises(exceptions.Conflict, - self.client.delete_obj, - 'clusters', self.cluster_id) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster '%s' cannot be deleted: there is still " - "receiver(s) associated with it." % self.cluster_id, - str(message)) - - -class TestClusterDeleteNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('8a583b8e-eeaa-4920-a6f5-2880b070624f') - def test_cluster_delete_not_found(self): - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.delete_obj, - 'clusters', - '8a583b8e-eeaa-4920-a6f5-2880b070624f') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster '8a583b8e-eeaa-4920-a6f5-2880b070624f' could " - "not be found.", str(message)) - - -class TestClusterDeleteNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterDeleteNegativeBadRequest, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.cluster_id1 = utils.create_a_cluster(self, profile_id, - name='c-01') - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id1) - self.cluster_id2 = utils.create_a_cluster(self, profile_id, - name='c-01') - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id2) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('3d8b73db-e2d2-42c2-952c-936048d36f21') - def test_cluster_delete_multiple_choice(self): - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.delete_obj, - 'clusters', 'c-01') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Multiple results found matching the query criteria 'c-01'. " - "Please be more specific.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_list.py b/senlin/tests/tempest/api/clusters/test_cluster_list.py deleted file mode 100644 index 0c5f1959c..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_list.py +++ /dev/null @@ -1,48 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterList(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterList, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('943cdc02-81bd-4200-a08d-bc1932d932f7') - def test_cluster_list(self): - res = self.client.list_objs('clusters') - - # Verify resp of cluster list API - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - clusters = res['body'] - cluster_ids = [] - for cluster in clusters: - for key in ['created_at', 'data', 'desired_capacity', 'domain', - 'id', 'init_at', 'max_size', 'metadata', 'min_size', - 'name', 'nodes', 'policies', 'profile_id', - 'profile_name', 'project', 'status', 'status_reason', - 'timeout', 'updated_at', 'user']: - self.assertIn(key, cluster) - cluster_ids.append(cluster['id']) - - self.assertIn(self.cluster_id, cluster_ids) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_list_negative.py b/senlin/tests/tempest/api/clusters/test_cluster_list_negative.py deleted file mode 100644 index 4cb539bdd..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_list_negative.py +++ /dev/null @@ -1,96 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestClusterListNegativeBadRequest(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('b18c2b98-0dcf-489f-8245-080db10298d8') - def test_cluster_list_invalid_params(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'clusters', {'bogus': 'foo'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Invalid parameter 'bogus'", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('f6687ce2-288c-42fa-8132-e0faec813129') - def test_cluster_list_limit_not_int(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'clusters', {'limit': 'not-int'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("The value for limit must be an integer: 'not-int'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('32a9f3ad-0284-4fe7-b6e8-d98915637c7f') - def test_cluster_list_global_project_false(self): - ex = self.assertRaises(exceptions.Forbidden, - self.client.list_objs, - 'clusters', {'global_project': 'True'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("You are not authorized to complete this operation.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('2944d7dd-72d5-4dd0-9f3e-6f5c6ead8b30') - def test_cluster_list_global_project_not_bool(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'clusters', {'global_project': 'not-bool'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Invalid value 'not-bool' specified for " - "'global_project'", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('dc4194f1-6487-47c4-8ad7-da6ca0e88ca2') - def test_cluster_list_invalid_sort(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'clusters', {'sort': 'bad-sort'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Unsupported sort key 'bad-sort' for 'sort'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('91489f49-686d-470d-9b74-c5e8f46eaae5') - def test_cluster_list_invalid_marker(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'clusters', {'marker': 'bad-marker'}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The value for marker is not a valid UUID: 'bad-marker'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('d13ff32f-aa8a-4704-824a-54d52a160874') - def test_cluster_list_unsupported_status(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'clusters', {'status': ['bad-status']}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Field value ['bad-status'] is invalid", - str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_policy_attach.py b/senlin/tests/tempest/api/clusters/test_cluster_policy_attach.py deleted file mode 100644 index 2a58ea86e..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_policy_attach.py +++ /dev/null @@ -1,153 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterActionPolicyAttach(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterActionPolicyAttach, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.policy_id = utils.create_a_policy(self) - self.addCleanup(utils.delete_a_policy, self, self.policy_id) - self.addCleanup(utils.cluster_detach_policy, self, self.cluster_id, - self.policy_id) - - @decorators.idempotent_id('214c48f8-cca9-4512-a904-2985743a1155') - def test_cluster_action_policy_attach(self): - params = { - "policy_attach": { - "enabled": True, - "policy_id": self.policy_id - } - } - # Trigger cluster action - res = self.client.trigger_action('clusters', self.cluster_id, - params=params) - - # Verify resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - -class TestClusterPolicyAttachNegativeInvalidParams(base.BaseSenlinAPITest): - - @decorators.idempotent_id('76dcdc8d-7680-4e27-bccd-26ad9d697528') - def test_cluster_policy_attach_params_not_dict(self): - params = { - 'policy_attach': 'POLICY_ID' - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("The data provided is not a map", - str(message)) - - @decorators.idempotent_id('34f6ceec-bde2-4013-87fe-db704ada5987') - def test_cluster_policy_attach_missing_policy_id_param(self): - params = { - 'policy_attach': {} - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("'policy_id' is a required property", - str(message)) - - @decorators.idempotent_id('5f5c42be-8ef4-4150-93cf-1e6b2515a293') - def test_cluster_policy_attach_invalid_enabled_param(self): - params = { - 'policy_attach': { - 'policy_id': 'POLICY_ID', - 'enabled': 'not-bool' - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Unrecognized value 'not-bool', acceptable values are: '0', '1', " - "'f', 'false', 'n', 'no', 'off', 'on', 't', 'true', 'y', 'yes'", - str(message)) - - -class TestClusterPolicyAttachNegativePolicyNotFound(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterPolicyAttachNegativePolicyNotFound, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('7ee49643-a5a0-4567-b9d0-0210b05a6138') - def test_cluster_policy_attach_policy_not_found(self): - params = { - 'policy_attach': { - 'poilicy_id': '7ee49643-a5a0-4567-b9d0-0210b05a6138' - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Additional properties are not allowed (u'poilicy_id' " - "was unexpected)", str(message)) - - -class TestClusterPolicyAttachNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.idempotent_id('29e66d49-9ffa-47c9-bbe3-e0cf9c3370ee') - def test_cluster_policy_attach_cluster_not_found(self): - params = { - 'policy_attach': { - 'policy_id': 'POLICY_ID' - } - } - - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.trigger_action, 'clusters', - '29e66d49-9ffa-47c9-bbe3-e0cf9c3370ee', - params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster '29e66d49-9ffa-47c9-bbe3-e0cf9c3370ee' could " - "not be found.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_policy_detach.py b/senlin/tests/tempest/api/clusters/test_cluster_policy_detach.py deleted file mode 100644 index 878b035d4..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_policy_detach.py +++ /dev/null @@ -1,161 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterActionPolicyDetach(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterActionPolicyDetach, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.policy_id = utils.create_a_policy(self) - self.addCleanup(utils.delete_a_policy, self, self.policy_id) - utils.cluster_attach_policy(self, self.cluster_id, self.policy_id) - - @decorators.idempotent_id('8643245e-ee32-41bb-a736-e33c9e77202a') - def test_cluster_action_policy_detach(self): - params = { - "policy_detach": { - "policy_id": self.policy_id - } - } - # Trigger cluster action - res = self.client.trigger_action('clusters', self.cluster_id, - params=params) - - # Verify resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - -class TestClusterPolicyDetachNegativeInvalidParams(base.BaseSenlinAPITest): - - @decorators.idempotent_id('832c3c2d-0434-4d8d-bbe4-6552528d8647') - def test_cluster_policy_detach_param_not_dict(self): - params = { - 'policy_detach': 'fake_policy' - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("The data provided is not a map", - str(message)) - - @decorators.idempotent_id('815a1c5a-f27b-4620-8711-bbef46507447') - def test_cluster_policy_detach_missing_profile_id_param(self): - params = { - 'policy_detach': {} - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("'policy_id' is a required property", - str(message)) - - -class TestClusterPolicyDetachNegativePolicyNotFound(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterPolicyDetachNegativePolicyNotFound, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('d8edc8bd-530c-4495-94ea-52d844633335') - def test_cluster_policy_detach_policy_not_found(self): - params = { - 'policy_detach': { - 'policy_id': '7ee49643-a5a0-4567-b9d0-0210b05a6138' - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified policy '7ee49643-a5a0-4567-b9d0-0210b05a6138' " - "could not be found.", str(message)) - - -class TestClusterPolicyDetachNegativeUnattached(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterPolicyDetachNegativeUnattached, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.policy_id = utils.create_a_policy(self) - self.addCleanup(utils.delete_a_policy, self, self.policy_id) - - @decorators.idempotent_id('f302142c-3536-4524-8ce2-da86306731cb') - def test_cluster_policy_detach_policy_unattached(self): - params = { - 'policy_detach': { - 'policy_id': self.policy_id - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The policy '%s' is not attached to the specified cluster " - "'%s'." % (self.policy_id, self.cluster_id), str(message)) - - -class TestClusterPolicyDetachNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.idempotent_id('11ff0486-a022-4b28-9def-9b2d78d47fab') - def test_cluster_policy_detach_cluster_not_found(self): - params = { - 'policy_detach': { - 'policy_id': 'POLICY_ID' - } - } - - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.trigger_action, 'clusters', - '11ff0486-a022-4b28-9def-9b2d78d47fab', - params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster '11ff0486-a022-4b28-9def-9b2d78d47fab' could " - "not be found.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_policy_update.py b/senlin/tests/tempest/api/clusters/test_cluster_policy_update.py deleted file mode 100644 index 198b96f82..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_policy_update.py +++ /dev/null @@ -1,185 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterActionPolicyUpdate(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterActionPolicyUpdate, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.policy_id = utils.create_a_policy(self) - self.addCleanup(utils.delete_a_policy, self, self.policy_id) - utils.cluster_attach_policy(self, self.cluster_id, self.policy_id) - self.addCleanup(utils.cluster_detach_policy, self, self.cluster_id, - self.policy_id) - - @decorators.idempotent_id('0b9efe3e-0abf-4230-a278-b282578df111') - def test_cluster_action_policy_update(self): - params = { - "policy_update": { - "enabled": False, - "policy_id": self.policy_id - } - } - # Trigger cluster action - res = self.client.trigger_action('clusters', self.cluster_id, - params=params) - - # Verify resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - -class TestClusterPolicyUpdateNegativeInvalidParams(base.BaseSenlinAPITest): - - @decorators.idempotent_id('653d8ea9-9c7e-48f2-b568-6167bb7f8666') - def test_cluster_policy_update_params_not_dict(self): - params = { - 'policy_update': 'POLICY_ID' - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("The data provided is not a map", - str(message)) - - @decorators.idempotent_id('b47dff55-3ff0-4303-b86e-c4ab5f9a0878') - def test_cluster_policy_update_missing_profile_id_param(self): - params = { - 'policy_update': {} - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("'policy_id' is a required property", - str(message)) - - @decorators.idempotent_id('4adb03f4-35e6-40eb-b867-d75315ca8a89') - def test_cluster_policy_update_invalid_enabled_param(self): - params = { - 'policy_update': { - 'policy_id': 'POLICY_ID', - 'enabled': 'not-bool' - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Unrecognized value 'not-bool', acceptable values are: '0', '1', " - "'f', 'false', 'n', 'no', 'off', 'on', 't', 'true', 'y', 'yes'", - str(message)) - - -class TestClusterPolicyUpdateNegativePolicyNotFound(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterPolicyUpdateNegativePolicyNotFound, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('7528bfa5-2106-459a-9ece-f201498b3ace') - def test_cluster_policy_update_policy_not_found(self): - params = { - 'policy_update': { - 'policy_id': '7528bfa5-2106-459a-9ece-f201498b3ace' - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified policy '7528bfa5-2106-459a-9ece-f201498b3ace' " - "could not be found.", str(message)) - - -class TestClusterPolicyUpdateNegativeUnattached(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterPolicyUpdateNegativeUnattached, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.policy_id = utils.create_a_policy(self) - self.addCleanup(utils.delete_a_policy, self, self.policy_id) - - @decorators.idempotent_id('81931b14-0a4c-43e5-a5eb-fdfd5386627e') - def test_cluster_policy_update_policy_unattached(self): - params = { - 'policy_update': { - 'policy_id': self.policy_id - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The policy '%s' is not attached to the specified cluster " - "'%s'." % (self.policy_id, self.cluster_id), str(message)) - - -class TestClusterPolicyUpdateNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.idempotent_id('c7605959-3bc9-41e2-9685-7e11fa03b9e6') - def test_cluster_policy_update_cluster_not_found(self): - params = { - 'policy_update': { - 'policy_id': 'POLICY_ID', - 'enabled': False - } - } - - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.trigger_action, 'clusters', - 'c7605959-3bc9-41e2-9685-7e11fa03b9e6', - params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster 'c7605959-3bc9-41e2-9685-7e11fa03b9e6' could " - "not be found.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_recover.py b/senlin/tests/tempest/api/clusters/test_cluster_recover.py deleted file mode 100644 index 155fa1d6a..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_recover.py +++ /dev/null @@ -1,85 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterActionRecover(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterActionRecover, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id, - desired_capacity=1) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('9020bc7e-db2a-47d0-9f78-7e6a3d231fad') - def test_cluster_action_recover(self): - params = { - "recover": { - "operation": "rebuild" - } - } - # Trigger cluster action - res = self.client.trigger_action('clusters', self.cluster_id, - params=params) - - # Verify resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - -class TestClusterRecoverNegativeInvalidParams(base.BaseSenlinAPITest): - - @decorators.idempotent_id('1f93e909-b271-4e46-acd8-8cb621b27546') - def test_cluster_recover_params_not_dict(self): - params = { - 'recover': ['k1', 'v1'] - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The data provided is not a map", - str(message)) - - -class TestClusterRecoverNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.idempotent_id('e6e522f4-34d4-42f7-b7f1-45004e06f3d9') - def test_cluster_recover_cluster_not_found(self): - params = { - 'recover': {'k1': 'v1'} - } - - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.trigger_action, 'clusters', - 'e6e522f4-34d4-42f7-b7f1-45004e06f3d9', - params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster 'e6e522f4-34d4-42f7-b7f1-45004e06f3d9' " - "could not be found.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_replace_nodes.py b/senlin/tests/tempest/api/clusters/test_cluster_replace_nodes.py deleted file mode 100644 index c0cac5a8b..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_replace_nodes.py +++ /dev/null @@ -1,337 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants -from senlin.tests.tempest.common import utils - - -class TestClusterActionReplaceNodes(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterActionReplaceNodes, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.origin_node = utils.create_a_node( - self, profile_id, cluster_id=self.cluster_id) - self.addCleanup(utils.delete_a_node, self, self.origin_node) - self.replace_node = utils.create_a_node(self, profile_id) - - @utils.api_microversion('1.3') - @decorators.idempotent_id('a17c2bff-eab7-4d02-a49f-9388eb53aa14') - def test_cluster_action_replace(self): - params = { - "replace_nodes": { - 'nodes': { - self.origin_node: self.replace_node - } - } - } - # Trigger cluster action - res = self.client.cluster_replace_nodes('clusters', self.cluster_id, - params=params) - - # Verify resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIn('action', res['location']) - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - -class TestClusterReplaceNodesNegativeInvalidParams(base.BaseSenlinAPITest): - - @utils.api_microversion('1.3') - @decorators.idempotent_id('fbfb0819-6a15-4926-a21f-44fda6960bed') - def test_cluster_replace_nodes_params_not_map(self): - params = { - 'replace_nodes': { - 'nodes': [] - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.cluster_replace_nodes, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("The data provided is not a map", - str(message)) - - @utils.api_microversion('1.3') - @decorators.idempotent_id('600baf2f-e74f-467d-9883-3dcf1c357b57') - def test_cluster_replace_nodes_params_empty_map(self): - params = { - 'replace_nodes': { - 'nodes': {} - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.cluster_replace_nodes, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("The data provided is not a map", - str(message)) - - @utils.api_microversion('1.3') - @decorators.idempotent_id('3e227f8f-7da3-4dc1-b647-68ed8fbdd111') - def test_cluster_replace_nodes_missing_new_node(self): - params = { - 'replace_nodes': { - 'nodes': { - 'old_node': None - } - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.cluster_replace_nodes, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Field `nodes[old_node]' cannot be None", - str(message)) - - @utils.api_microversion('1.3') - @decorators.idempotent_id('82ebbd5a-47fc-4d32-be3c-7bf3262dd574') - def test_cluster_replace_nodes_duplicated_node(self): - params = { - 'replace_nodes': { - 'nodes': { - 'old_node1': 'new_node', - 'old_node2': 'new_node' - } - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.cluster_replace_nodes, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Map contains duplicated values", - str(message)) - - -class TestClusterReplaceNodesNegativeOldNotFound(base.BaseSenlinAPITest): - def setUp(self): - super(TestClusterReplaceNodesNegativeOldNotFound, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.new_node = utils.create_a_node(self, self.profile_id) - self.addCleanup(utils.delete_a_node, self, self.new_node) - - @utils.api_microversion('1.3') - @decorators.idempotent_id('911d6e85-220f-4208-9a0b-b91e83c5e787') - def test_cluster_replace_nodes_old_node_not_found(self): - params = { - 'replace_nodes': { - 'nodes': { - 'old_node': self.new_node - } - } - } - - # Verify not found badrequest is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.cluster_replace_nodes, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Original nodes not found: [u'old_node'].", - str(message)) - - -class TestClusterReplaceNodesNegativeNewNotFound(base.BaseSenlinAPITest): - def setUp(self): - super(TestClusterReplaceNodesNegativeNewNotFound, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.old_node = utils.create_a_node(self, self.profile_id, - cluster_id=self.cluster_id) - self.addCleanup(utils.delete_a_node, self, self.old_node) - - @utils.api_microversion('1.3') - @decorators.idempotent_id('1282c521-c479-42f3-b375-8d6d62b1d5dc') - def test_cluster_replace_nodes_old_node_not_found(self): - params = { - 'replace_nodes': { - 'nodes': { - self.old_node: 'new_node' - } - } - } - - # Verify badrequest exception is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.cluster_replace_nodes, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Replacement nodes not found: [u'new_node'].", - str(message)) - - -class TestClusterReplaceNodesNegativeNewNotOrphan(base.BaseSenlinAPITest): - def setUp(self): - super(TestClusterReplaceNodesNegativeNewNotOrphan, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.old_node = utils.create_a_node(self, self.profile_id, - cluster_id=self.cluster_id) - self.addCleanup(utils.delete_a_node, self, self.old_node) - - self.cluster_id2 = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id2) - self.new_node = utils.create_a_node(self, self.profile_id, - self.cluster_id2) - self.addCleanup(utils.delete_a_node, self, self.new_node) - - @utils.api_microversion('1.3') - @decorators.idempotent_id('e001ba28-f7ad-4af5-a281-5652ca040c65') - def test_cluster_replace_nodes_new_node_not_orphan(self): - params = { - 'replace_nodes': { - 'nodes': { - self.old_node: self.new_node - } - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.cluster_replace_nodes, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Nodes [u'%s'] already member of a cluster." % self.new_node, - str(message)) - - -class TestClusterReplaceNodeNegativeProfileUnmatch(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterReplaceNodeNegativeProfileUnmatch, self).setUp() - self.profile_id = utils.create_a_profile( - self, spec=constants.spec_nova_server) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.old_node = utils.create_a_node(self, self.profile_id, - self.cluster_id) - self.addCleanup(utils.delete_a_node, self, self.old_node) - - self.profile_id2 = utils.create_a_profile( - self, spec=constants.spec_heat_stack) - self.addCleanup(utils.delete_a_profile, self, self.profile_id2) - self.new_node = utils.create_a_node(self, self.profile_id2) - self.addCleanup(utils.delete_a_node, self, self.new_node) - - @utils.api_microversion('1.3') - @decorators.idempotent_id('d1cb2068-b23c-4023-ad25-271f8e5b1bfa') - def test_cluster_replace_nodes_profile_type_unmatch(self): - params = { - 'replace_nodes': { - 'nodes': { - self.old_node: self.new_node - } - } - } - - # Verify badrequest exception is raised - ex = self.assertRaises(exceptions.BadRequest, - self.client.cluster_replace_nodes, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Profile type of nodes [u'%s'] do not match that of the " - "cluster." % self.new_node, str(message)) - - -class TestClusterReplaceNodeNegativeOldOrphan(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterReplaceNodeNegativeOldOrphan, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - self.old_node = utils.create_a_node(self, self.profile_id) - self.addCleanup(utils.delete_a_node, self, self.old_node) - self.new_node = utils.create_a_node(self, self.profile_id) - self.addCleanup(utils.delete_a_node, self, self.new_node) - - @utils.api_microversion('1.3') - @decorators.idempotent_id('ca0afe22-e758-477c-8ca5-cd1b686747dc') - def test_cluster_replace_nodes_old_node_orphan(self): - params = { - 'replace_nodes': { - 'nodes': { - self.old_node: self.new_node - } - } - } - - # Versify badrequest exeception is raised - ex = self.assertRaises(exceptions.BadRequest, - self.client.cluster_replace_nodes, 'clusters', - self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified nodes [u'%s'] to be replaced are not members " - "of the cluster %s." % (self.old_node, self.cluster_id), - str(message)) - - -class TestClusterReplaceNodeNegativeClusterNotFound(base.BaseSenlinAPITest): - - @utils.api_microversion('1.3') - @decorators.idempotent_id('086c0657-f7a1-4722-a585-ac281725bcfc') - def test_cluster_replace_nodes_cluster_not_found(self): - params = { - 'replace_nodes': { - 'nodes': { - 'old_node': 'new_node' - } - } - } - - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.cluster_replace_nodes, 'clusters', - 'db0faadf-9cd2-457f-b434-4891b77938ab', - params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster 'db0faadf-9cd2-457f-b434-4891b77938ab' could " - "not be found.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_resize.py b/senlin/tests/tempest/api/clusters/test_cluster_resize.py deleted file mode 100644 index dec4a9263..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_resize.py +++ /dev/null @@ -1,352 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterActionResize(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterActionResize, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('f5f75882-df3d-481f-bd05-019e4d08af65') - def test_cluster_action_resize(self): - params = { - "resize": { - "adjustment_type": "CHANGE_IN_CAPACITY", - "max_size": 20, - "min_step": 1, - "min_size": 5, - "number": 20, - } - } - # Trigger cluster action - res = self.client.trigger_action('clusters', self.cluster_id, - params=params) - - # Verify resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - -class TestClusterResizeNegativeInvalidResizeParams(base.BaseSenlinAPITest): - - @decorators.idempotent_id('57bc61a2-df38-4bf5-a26a-d23d2cc67ca3') - def test_cluster_resize_invalid_adj_type(self): - params = { - "resize": { - "adjustment_type": "bogus", - "max_size": 20, - "min_size": 5, - "number": 5 - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Value 'bogus' is not acceptable for field " - "'adjustment_type'.", str(message)) - - @decorators.idempotent_id('cef85ed4-9dd3-4f9f-91fe-4372d9aa8956') - def test_cluster_resize_missing_adj_type(self): - params = { - "resize": { - "max_size": 20, - "min_size": 5, - "number": 5 - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Missing adjustment_type value for size adjustment.", - str(message)) - - @decorators.idempotent_id('e42dd7e1-aa36-4e46-8b5b-2571d00574c9') - def test_cluster_resize_missing_adj_number(self): - params = { - "resize": { - "adjustment_type": "CHANGE_IN_CAPACITY", - "max_size": 20, - "min_size": 5 - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Missing number value for size adjustment.", - str(message)) - - @decorators.idempotent_id('7e669b3e-8fbd-4820-a281-7cc4b29c6020') - def test_cluster_resize_invalid_adj_number(self): - params = { - "resize": { - "adjustment_type": "EXACT_CAPACITY", - "max_size": 20, - "min_size": 5, - "number": -1 - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The 'number' must be positive integer for adjustment " - "type 'EXACT_CAPACITY'.", str(message)) - - @decorators.idempotent_id('5a069782-d6d8-4389-a68c-beb32375a39e') - def test_cluster_resize_min_size_over_max_size(self): - params = { - "resize": { - "adjustment_type": "CHANGE_IN_CAPACITY", - "max_size": 10, - "min_size": 20, - "number": 5 - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'cluster_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified min_size (20) is greater than the " - "specified max_size (10).", str(message)) - - -class TestClusterResizeNegativeClusterNotFound(base.BaseSenlinAPITest): - @decorators.idempotent_id('087ef694-55d2-4616-a58b-1073cacb2bcd') - def test_cluster_resize_cluster_not_found(self): - params = { - "resize": { - "adjustment_type": "CHANGE_IN_CAPACITY", - "max_size": 20, - "min_size": 5, - "number": 5 - } - } - - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.trigger_action, 'clusters', - '087ef694-55d2-4616-a58b-1073cacb2bcd', - params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster '087ef694-55d2-4616-a58b-1073cacb2bcd' could " - "not be found.", str(message)) - - -class TestClusterResizeNegativeSizeCheckFailed(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterResizeNegativeSizeCheckFailed, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id, - min_size=2, max_size=5, - desired_capacity=3) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('92e7d3c8-2d38-4766-86c3-41dc14bf89a1') - def test_cluster_resize_break_upper_limit(self): - # New desired_capacity will be greater than max_size - params = { - "resize": { - "adjustment_type": "CHANGE_IN_CAPACITY", - "number": 3, - "strict": True - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The target capacity (6) is greater than the cluster's " - "max_size (5).", str(message)) - - @decorators.idempotent_id('9dcac577-d768-44d1-b119-02d27202ef08') - def test_cluster_resize_break_lower_limit(self): - # New desired_capacity will be less than min_size - params = { - "resize": { - "adjustment_type": "CHANGE_IN_CAPACITY", - "number": -2, - "strict": True - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The target capacity (1) is less than the cluster's " - "min_size (2).", str(message)) - - @decorators.idempotent_id('d7a96d95-2944-4749-be34-cfe39a5dbcb4') - def test_cluster_resize_max_size_under_current_desired_capacity(self): - # New max_size is less than current desired_capacity of cluster - params = { - "resize": { - "max_size": 2, - "strict": True - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified max_size (2) is less than the current " - "desired_capacity (3) of the cluster.", str(message)) - - @decorators.idempotent_id('3b35938f-a73a-4096-bf13-af3709aed47f') - def test_cluster_resize_max_size_under_current_min_size(self): - # New max_size is less than current min_size of cluster - # with strict set to False - params = { - "resize": { - "max_size": 1, - "strict": False - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified max_size (1) is less than the current " - "min_size (2) of the cluster.", str(message)) - # New max_size is less than current min_size of cluster - # with strict set to True - params = { - "resize": { - "max_size": 1, - "strict": True - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified max_size (1) is less than the current min_size " - "(2) of the cluster.", str(message)) - - @decorators.idempotent_id('1d7595a4-a7a8-42a4-9f90-7501a4bbb7e5') - def test_cluster_resize_min_size_over_current_desired_capacity(self): - # New min_size is greater than current desired_capacity of cluster - params = { - "resize": { - "min_size": 4, - "strict": True - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified min_size (4) is greater than the current " - "desired_capacity (3) of the cluster.", str(message)) - - @decorators.idempotent_id('606e5d3f-0857-4bfe-b52d-2ea1ad0cec16') - def test_cluster_resize_min_size_over_current_max_size(self): - # New min_size is greater than current max_size of cluster - # with strict set to False - params = { - "resize": { - "min_size": 6, - "strict": False - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified min_size (6) is greater than the current " - "max_size (5) of the cluster.", str(message)) - - # New min_size is greater than current max_size of cluster - # with strict set to True - params = { - "resize": { - "min_size": 6, - "strict": True - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified min_size (6) is greater than the current " - "max_size (5) of the cluster.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_scale_in.py b/senlin/tests/tempest/api/clusters/test_cluster_scale_in.py deleted file mode 100644 index b264844fd..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_scale_in.py +++ /dev/null @@ -1,118 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterActionScaleIn(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterActionScaleIn, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id, - desired_capacity=1) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('a579cd01-8096-4bee-9978-d095025f605c') - def test_cluster_action_scale_in(self): - params = { - "scale_in": { - "count": "1" - } - } - # Trigger cluster action - res = self.client.trigger_action('clusters', self.cluster_id, - params=params) - - # Verify resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - -class TestClusterScaleInInvalidRequest(base.BaseSenlinAPITest): - - @decorators.idempotent_id('d826dc0f-ef1c-47ee-b31f-3042aaa8ec54') - def test_cluster_scale_in_invalid_count(self): - params = { - "scale_in": { - "count": "bad-count" - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'fake', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The value for count must be an integer: 'bad-count'.", - str(message)) - - -class TestClusterScaleInNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterScaleInNegativeBadRequest, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id, - min_size=0, max_size=5, - desired_capacity=1) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('337a8a8f-a368-4d4f-949a-8b116dbb6a75') - def test_cluster_scale_in_invalid_count(self): - params = { - "scale_in": { - "count": -1 - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Value must be >= 0 for field 'count'.", - str(message)) - - -class TestClusterScaleInNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.idempotent_id('0124c7de-66d0-4a84-9c8f-80bc4d246b79') - def test_cluster_scale_in_cluster_not_found(self): - params = { - "scale_in": { - "count": 1 - } - } - - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.trigger_action, 'clusters', - '0124c7de-66d0-4a84-9c8f-80bc4d246b79', - params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster '0124c7de-66d0-4a84-9c8f-80bc4d246b79' could " - "not be found.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_scale_out.py b/senlin/tests/tempest/api/clusters/test_cluster_scale_out.py deleted file mode 100644 index 17bb9caa9..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_scale_out.py +++ /dev/null @@ -1,117 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterActionScaleOut(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterActionScaleOut, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('f15ff8cc-4be3-4c93-9979-6be428e83cd7') - def test_cluster_action_scale_out(self): - params = { - "scale_out": { - "count": "1" - } - } - # Trigger cluster action - res = self.client.trigger_action('clusters', self.cluster_id, - params=params) - - # Verify resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - -class TestClusterScaleOutNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterScaleOutNegativeBadRequest, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id, - min_size=0, max_size=5, - desired_capacity=1) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('2bbf6e0c-a8cc-4b29-8060-83652ffd6cd2') - def test_cluster_scale_out_invalid_count(self): - params = { - "scale_out": { - "count": -1 - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Value must be >= 0 for field 'count'.", - str(message)) - - -class TestClusterScaleOutInvalidRequest(base.BaseSenlinAPITest): - - @decorators.idempotent_id('7aa3fd0c-c092-4a54-8dae-3814492101b0') - def test_cluster_scale_out_invalid_count(self): - params = { - "scale_out": { - "count": "bad-count" - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'clusters', 'fake', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The value for count must be an integer: 'bad-count'.", - str(message)) - - -class TestClusterScaleOutNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.idempotent_id('b7038d95-204c-455f-a866-94dc535dd840') - def test_cluster_scale_out_cluster_not_found(self): - params = { - "scale_out": { - "count": 1 - } - } - - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.trigger_action, 'clusters', - 'b7038d95-204c-455f-a866-94dc535dd840', - params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster 'b7038d95-204c-455f-a866-94dc535dd840' could " - "not be found.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_show.py b/senlin/tests/tempest/api/clusters/test_cluster_show.py deleted file mode 100644 index a4b639776..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_show.py +++ /dev/null @@ -1,43 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterShow(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterShow, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('45f56c9a-4589-48dd-9256-9b368727dd6c') - def test_cluster_show(self): - res = self.client.get_obj('clusters', self.cluster_id) - - # Verify resp of cluster get API - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - cluster = res['body'] - for key in ['created_at', 'data', 'desired_capacity', 'domain', - 'id', 'init_at', 'max_size', 'metadata', 'min_size', - 'name', 'nodes', 'policies', 'profile_id', 'profile_name', - 'project', 'status', 'status_reason', 'timeout', - 'updated_at', 'user']: - self.assertIn(key, cluster) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_show_negative.py b/senlin/tests/tempest/api/clusters/test_cluster_show_negative.py deleted file mode 100644 index 5aa43d590..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_show_negative.py +++ /dev/null @@ -1,58 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterShowNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterShowNegativeBadRequest, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id1 = utils.create_a_cluster(self, profile_id, - name='c-01') - self.cluster_id2 = utils.create_a_cluster(self, profile_id, - name='c-01') - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id1) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id2) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('3365dca5-8895-4dc3-befe-fd15b17c824c') - def test_cluster_show_multiple_choice(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.get_obj, - 'clusters', 'c-01') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Multiple results found matching the query criteria " - "'c-01'. Please be more specific.", str(message)) - - -class TestClusterShowNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.idempotent_id('4706516e-002d-42b2-9805-69058178cd9c') - def test_cluster_show_cluster_not_found(self): - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.get_obj, - 'clusters', 'c-01') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster 'c-01' could " - "not be found.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_update.py b/senlin/tests/tempest/api/clusters/test_cluster_update.py deleted file mode 100644 index 4a3b08592..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_update.py +++ /dev/null @@ -1,55 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestClusterUpdate(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterUpdate, self).setUp() - - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('ba8514b2-b3c4-47a4-9176-7fe9bb2781ae') - def test_cluster_update_basic_properties(self): - # Update basic properties of cluster - params = { - 'cluster': { - 'timeout': 240, - 'metadata': {'k2': 'v2'}, - 'name': 'cluster_new_name' - } - } - res = self.client.update_obj('clusters', self.cluster_id, params) - - # Verify resp of cluster update API - self.assertEqual(202, res['status']) - self.assertIsNotNone(res['body']) - self.assertIn('actions', res['location']) - cluster = res['body'] - for key in ['created_at', 'data', 'domain', 'id', 'init_at', - 'metadata', 'name', 'nodes', 'policies', 'profile_id', - 'profile_name', 'project', 'status', 'status_reason', - 'timeout', 'updated_at', 'user']: - self.assertIn(key, cluster) - - # Wait for cluster update to be done before moving on - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') diff --git a/senlin/tests/tempest/api/clusters/test_cluster_update_negative.py b/senlin/tests/tempest/api/clusters/test_cluster_update_negative.py deleted file mode 100644 index c4d1c0b36..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_update_negative.py +++ /dev/null @@ -1,205 +0,0 @@ -# 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. - -import copy -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants -from senlin.tests.tempest.common import utils - - -class TestClusterUpdateNegativeInvalidParam(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('7bddd411-b890-4a36-a523-3e49b87cb645') - def test_cluster_update_cluster_invalid_param(self): - params = { - 'cluster': { - 'bad': 'invalid' - } - } - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, 'clusters', - 'f7a97fce-f495-44a8-b41a-7408139adacf', - params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Additional properties are not allowed (u'bad' was " - "unexpected)", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('80cd0acd-772f-482f-8c6d-90843d986eb1') - def test_cluster_update_cluster_empty_param(self): - params = {} - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, 'clusters', - '80cd0acd-772f-482f-8c6d-90843d986eb1', - params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Malformed request data, missing 'cluster' key in " - "request body.", str(message)) - - -class TestClusterUpdateNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('f7a97fce-f495-44a8-b41a-7408139adacf') - def test_cluster_update_cluster_not_found(self): - ex = self.assertRaises(exceptions.NotFound, - self.client.update_obj, 'clusters', - 'f7a97fce-f495-44a8-b41a-7408139adacf', - {'cluster': {'name': 'new-name'}}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The cluster 'f7a97fce-f495-44a8-b41a-7408139adacf' could " - "not be found.", str(message)) - - -class TestClusterUpdateNegativeProfileNotFound(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterUpdateNegativeProfileNotFound, self).setUp() - # Create a profile - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.profile_id = profile_id - # Create a cluster - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('fb68921d-1fe8-4c14-be9a-51fa43d4f705') - def test_cluster_update_profile_not_found(self): - # Provided profile can not be found - params = { - 'cluster': { - 'profile_id': 'fb68921d-1fe8-4c14-be9a-51fa43d4f705', - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified profile 'fb68921d-1fe8-4c14-be9a-51fa43d4f705' " - "could not be found.", str(message)) - - -class TestClusterUpdateNegativeProfileMultichoices(base.BaseSenlinAPITest): - def setUp(self): - super(TestClusterUpdateNegativeProfileMultichoices, self).setUp() - # Create a profile - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.profile_id = profile_id - # Create a cluster - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - # Create two new profiles of the same type with the same name - new_spec = copy.deepcopy(constants.spec_nova_server) - new_spec['properties']['flavor'] = 'new_flavor' - new_profile_id1 = utils.create_a_profile(self, new_spec, name='p-nova') - new_profile_id2 = utils.create_a_profile(self, new_spec, name='p-nova') - self.addCleanup(utils.delete_a_profile, self, new_profile_id1) - self.addCleanup(utils.delete_a_profile, self, new_profile_id2) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('6a3eb86c-4b5c-4cfc-891c-7b0be17715f2') - def test_cluster_update_profile_multichoices(self): - # Multiple profiles are found for given name - params = { - 'cluster': { - 'profile_id': 'p-nova', - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Multiple results found matching the query criteria 'p-nova'. " - "Please be more specific.", str(message)) - - -class TestClusterUpdateNegativeProfileTypeUnmatch(base.BaseSenlinAPITest): - def setUp(self): - super(TestClusterUpdateNegativeProfileTypeUnmatch, self).setUp() - # Create a profile - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.profile_id = profile_id - # Create a cluster - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - # Create a new profile of different type - self.new_profile_id = utils.create_a_profile( - self, spec=constants.spec_heat_stack) - self.addCleanup(utils.delete_a_profile, self, self.new_profile_id) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('c28e1bc0-fadb-4394-b2d0-67ad8b87ac04') - def test_cluster_update_profile_type_unmatch(self): - # New profile type is different from original cone - params = { - 'cluster': { - 'profile_id': self.new_profile_id, - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Cannot update a cluster to a different profile type, " - "operation aborted.", str(message)) - - -class TestClusterUpdateNegativeNoPropertyUpdated(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterUpdateNegativeNoPropertyUpdated, self).setUp() - # Create a profile - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.profile_id = profile_id - # Create a cluster - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('0fbd8fd9-7789-47da-b806-d91631a28556') - def test_cluster_update_no_property_updated(self): - # No any property is updated - params = { - 'cluster': {} - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, - 'clusters', self.cluster_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual("No property needs an update.", str(message)) diff --git a/senlin/tests/tempest/api/clusters/test_cluster_update_profile.py b/senlin/tests/tempest/api/clusters/test_cluster_update_profile.py deleted file mode 100644 index a2e5fbbd0..000000000 --- a/senlin/tests/tempest/api/clusters/test_cluster_update_profile.py +++ /dev/null @@ -1,124 +0,0 @@ -# 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. - -import copy -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants -from senlin.tests.tempest.common import utils - - -class TestClusterUpdateProfile(base.BaseSenlinAPITest): - - def setUp(self): - super(TestClusterUpdateProfile, self).setUp() - - self.old_profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.old_profile_id) - - # create a new profile - new_spec = copy.deepcopy(constants.spec_nova_server) - new_spec['properties']['flavor'] = 'new_flavor' - new_spec['properties']['image'] = 'new_image' - self.new_profile_id = utils.create_a_profile(self, new_spec) - self.addCleanup(utils.delete_a_profile, self, self.new_profile_id) - - self.cluster_id = utils.create_a_cluster(self, self.old_profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - self.node1_id = utils.create_a_node( - self, self.old_profile_id, name='N01', cluster_id=self.cluster_id) - self.addCleanup(utils.delete_a_node, self, self.node1_id) - - @decorators.idempotent_id('abff7891-21af-4c37-a8df-5bc7379ce349') - def test_cluster_update_profile(self): - # Update cluster with new profile - params = { - 'cluster': { - 'profile_id': self.new_profile_id - } - } - res = self.client.update_obj('clusters', self.cluster_id, params) - - # Verify resp of cluster update API - self.assertEqual(202, res['status']) - self.assertIsNotNone(res['body']) - self.assertIn('actions', res['location']) - cluster = res['body'] - for key in ['created_at', 'data', 'domain', 'id', 'init_at', - 'metadata', 'name', 'nodes', 'policies', 'profile_id', - 'profile_name', 'project', 'status', 'status_reason', - 'timeout', 'updated_at', 'user']: - self.assertIn(key, cluster) - - # Wait for cluster update to be done before moving on - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - @utils.api_microversion('1.6') - @decorators.idempotent_id('686cd38a-16eb-4364-b495-367fc7c8bb26') - def test_cluster_update_profile_profile_only(self): - # Update cluster with new profile - params = { - 'cluster': { - 'profile_id': self.new_profile_id, - 'profile_only': True - } - } - res = self.client.update_obj('clusters', self.cluster_id, params) - - # Verify resp of cluster update API - self.assertEqual(202, res['status']) - self.assertIsNotNone(res['body']) - self.assertIn('actions', res['location']) - - # Wait for cluster update to be done before moving on - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - # verify cluster profile id changed - res = self.client.get_obj('clusters', self.cluster_id) - self.assertEqual(self.new_profile_id, res['body']['profile_id']) - - # verify node profile id not changed. - res = self.client.get_obj('nodes', self.node1_id) - self.assertEqual(self.old_profile_id, res['body']['profile_id']) - - @utils.api_microversion('1.5') - @decorators.idempotent_id('8a67876f-e9ea-4cbe-807a-73eefe482536') - def test_cluster_update_profile_profile_only_backward(self): - # Update cluster with new profile - params = { - 'cluster': { - 'profile_id': self.new_profile_id, - 'profile_only': True - } - } - res = self.client.update_obj('clusters', self.cluster_id, params) - - # Verify resp of cluster update API - self.assertEqual(202, res['status']) - self.assertIsNotNone(res['body']) - self.assertIn('actions', res['location']) - - # Wait for cluster update to be done before moving on - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - # verify cluster profile id changed - res = self.client.get_obj('clusters', self.cluster_id) - self.assertEqual(self.new_profile_id, res['body']['profile_id']) - - # verify node profile id not changed. - res = self.client.get_obj('nodes', self.node1_id) - self.assertEqual(self.new_profile_id, res['body']['profile_id']) diff --git a/senlin/tests/tempest/api/events/__init__.py b/senlin/tests/tempest/api/events/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/api/events/test_event_list.py b/senlin/tests/tempest/api/events/test_event_list.py deleted file mode 100644 index 931c33a95..000000000 --- a/senlin/tests/tempest/api/events/test_event_list.py +++ /dev/null @@ -1,41 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestEventList(base.BaseSenlinAPITest): - - def setup(self): - super(TestEventList, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, cluster_id) - - @decorators.idempotent_id('498a7e22-7ada-415b-a7cf-927b0ad3d9f6') - def test_event_list(self): - res = self.client.list_objs('events') - - # Verify resp of event list API - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - events = res['body'] - for event in events: - for key in ['action', 'cluster_id', 'id', 'level', 'oid', - 'oname', 'otype', 'project', 'status', - 'status_reason', 'timestamp', 'user']: - self.assertIn(key, event) diff --git a/senlin/tests/tempest/api/events/test_event_list_negative.py b/senlin/tests/tempest/api/events/test_event_list_negative.py deleted file mode 100644 index 86eafdbfd..000000000 --- a/senlin/tests/tempest/api/events/test_event_list_negative.py +++ /dev/null @@ -1,108 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestEventListNegativeBadRequest(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('ddbc0735-869c-4da4-ae1d-ec67984cca46') - def test_event_list_invalid_params(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'events', {'bogus': 'foo'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Invalid parameter bogus", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('fc3a5097-d332-42e5-8fb8-682cb248d9ad') - def test_event_list_limit_not_int(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'events', {'limit': 'not-int'}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The value for limit must be an integer: 'not-int'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('da0871d7-9eb4-4349-b1db-0287d444ff58') - def test_event_list_global_project_false(self): - ex = self.assertRaises(exceptions.Forbidden, - self.client.list_objs, - 'events', {'global_project': 'True'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("You are not authorized to complete this operation.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('bccbbec0-08e5-4594-8fa4-c874d4359033') - def test_event_list_global_project_not_bool(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'events', {'global_project': 'not-bool'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Invalid value 'not-bool' specified for " - "'global_project'", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('84d2d883-9402-4735-8be6-b726b0e0edbd') - def test_event_list_invalid_sort(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'events', {'sort': 'bad-sort'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Unsupported sort key 'bad-sort' for 'sort'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('c53500fc-0504-4f0f-b540-1f39e524db53') - def test_event_list_invalid_marker(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'events', {'marker': 'bad-marker'}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The value for marker is not a valid UUID: 'bad-marker'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('72e0fd48-2dc7-47ce-abad-299e508fabd4') - def test_event_list_unsupported_level(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'events', {'level': ['bad-level']}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Field value ['bad-level'] is invalid", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('72e0fd48-2dc7-47ce-abad-299e508fabd4') - def test_event_list_unsupported_action(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'events', {'action': ['bad-action']}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Field value ['bad-action'] is invalid", - str(message)) diff --git a/senlin/tests/tempest/api/events/test_event_show.py b/senlin/tests/tempest/api/events/test_event_show.py deleted file mode 100644 index 860612f8c..000000000 --- a/senlin/tests/tempest/api/events/test_event_show.py +++ /dev/null @@ -1,43 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestEventShow(base.BaseSenlinAPITest): - - def setUp(self): - super(TestEventShow, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('b23490a7-0ae2-44be-a1f9-9f2d82dfe6aa') - def test_event_show(self): - # Get cluster events - events = self.client.list_objs('events', - {'oid': self.cluster_id})['body'] - res = self.client.get_obj('events', events[0]['id']) - - # Verify resp of event list API - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - event = res['body'] - for key in ['action', 'cluster_id', 'id', 'level', 'oid', - 'oname', 'otype', 'project', 'status', - 'status_reason', 'timestamp', 'user']: - self.assertIn(key, event) diff --git a/senlin/tests/tempest/api/events/test_event_show_negative.py b/senlin/tests/tempest/api/events/test_event_show_negative.py deleted file mode 100644 index e013115b0..000000000 --- a/senlin/tests/tempest/api/events/test_event_show_negative.py +++ /dev/null @@ -1,31 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestEventShowNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('318ae275-ed68-48f5-9151-523085107112') - def test_event_show_not_found(self): - ex = self.assertRaises(exceptions.NotFound, - self.client.get_obj, 'events', - '318ae275-ed68-48f5-9151-523085107112') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The event '318ae275-ed68-48f5-9151-523085107112' could " - "not be found.", str(message)) diff --git a/senlin/tests/tempest/api/nodes/__init__.py b/senlin/tests/tempest/api/nodes/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/api/nodes/test_node_action_negative.py b/senlin/tests/tempest/api/nodes/test_node_action_negative.py deleted file mode 100644 index d6ac52a41..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_action_negative.py +++ /dev/null @@ -1,66 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestNodeActionNegativeBadRequest(base.BaseSenlinAPITest): - - @decorators.idempotent_id('9ab462e2-ea3a-49f8-bd78-5a056ae80a48') - def test_no_action_specified(self): - # No action is specified - params = {} - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'nodes', 'node_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("No action specified.", - str(message)) - - @decorators.idempotent_id('9e696e4f-1ec8-45d7-8461-81d275aae81d') - def test_multiple_action_specified(self): - # Multiple actions are specified - params = { - 'check': {}, - 'recover': {} - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'nodes', 'node_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Multiple actions specified.", - str(message)) - - @decorators.idempotent_id('4bd97c71-fbfc-421d-95ff-b3f4a212cc38') - def test_unrecognized_action(self): - # Unrecoginized action is specified - params = { - 'bogus': {} - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'nodes', 'node_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Unrecognized action 'bogus' specified", - str(message)) diff --git a/senlin/tests/tempest/api/nodes/test_node_check.py b/senlin/tests/tempest/api/nodes/test_node_check.py deleted file mode 100644 index 3d859906d..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_check.py +++ /dev/null @@ -1,80 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestNodeCheck(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeCheck, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.node_id = utils.create_a_node(self, profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @decorators.idempotent_id('ae124bfe-9fcf-4e87-91b7-319102efbdcc') - def test_check(self): - params = { - 'check': { - } - } - # Trigger node action - res = self.client.trigger_action('nodes', self.node_id, params=params) - - # Verfiy resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - -class TestNodeCheckNegative(base.BaseSenlinAPITest): - - @decorators.idempotent_id('723ea351-1bcb-4d45-bfe7-35c656d29761') - def test_param_is_not_map(self): - # Check action parameter is not a map - params = { - 'check': [] - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'nodes', 'node_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("The params provided is not a map.", - str(message)) - - @decorators.idempotent_id('90c46123-f992-4833-859a-46f6d2ccd8e9') - def test_node_not_found(self): - params = { - 'check': {} - } - - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.trigger_action, 'nodes', - '90c46123-f992-4833-859a-46f6d2ccd8e9', - params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The node '90c46123-f992-4833-859a-46f6d2ccd8e9' could " - "not be found.", str(message)) diff --git a/senlin/tests/tempest/api/nodes/test_node_create.py b/senlin/tests/tempest/api/nodes/test_node_create.py deleted file mode 100644 index 73c2049fe..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_create.py +++ /dev/null @@ -1,61 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestNodeCreate(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeCreate, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('14d06753-7f0a-4ad2-84be-37fce7114a8f') - def test_node_create_all_attrs_defined(self): - params = { - 'node': { - 'profile_id': self.profile_id, - 'cluster_id': self.cluster_id, - 'metadata': {'k1': 'v1'}, - 'role': 'member', - 'name': 'test-node' - } - } - res = self.client.create_obj('nodes', params) - - # Verify resp of node create API - self.assertEqual(202, res['status']) - self.assertIsNotNone(res['body']) - self.assertIn('actions', res['location']) - node = res['body'] - self.addCleanup(utils.delete_a_node, self, node['id']) - for key in ['cluster_id', 'created_at', 'data', 'domain', 'id', - 'index', 'init_at', 'metadata', 'name', 'physical_id', - 'profile_id', 'profile_name', 'project', 'role', - 'status', 'status_reason', 'updated_at', 'user']: - self.assertIn(key, node) - self.assertIn('test-node', node['name']) - self.assertEqual(self.profile_id, node['profile_id']) - self.assertEqual(self.cluster_id, node['cluster_id']) - self.assertEqual({'k1': 'v1'}, node['metadata']) - self.assertEqual('member', node['role']) - self.assertEqual('test-node', node['name']) - - # Wait node to be active before moving on - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') diff --git a/senlin/tests/tempest/api/nodes/test_node_create_negative.py b/senlin/tests/tempest/api/nodes/test_node_create_negative.py deleted file mode 100644 index 215309f2c..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_create_negative.py +++ /dev/null @@ -1,170 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants -from senlin.tests.tempest.common import utils - - -class TestNodeCreateNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeCreateNegativeBadRequest, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.profile_id2 = utils.create_a_profile( - self, spec=constants.spec_heat_stack) - self.addCleanup(utils.delete_a_profile, self, self.profile_id2) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('cbe7827a-60ca-42c0-99d2-38167cb4f46d') - def test_node_create_profile_invalid(self): - # Invalid profile_id is provided - params = { - 'node': { - 'profile_id': 'cbe7827a-60ca-42c0-99d2-38167cb4f46d', - 'cluster_id': self.cluster_id, - 'metadata': {'k1': 'v1'}, - 'role': 'member', - 'name': 'test-node' - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'nodes', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified profile 'cbe7827a-60ca-42c0-99d2-38167cb4f46d' " - "could not be found.", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('960cd427-2487-4c83-b679-1b5e1f9dd985') - def test_node_create_cluster_invalid(self): - # Invalid cluster_id is provided - params = { - 'node': { - 'profile_id': self.profile_id, - 'cluster_id': '960cd427-2487-4c83-b679-1b5e1f9dd985', - 'metadata': {'k1': 'v1'}, - 'role': 'member', - 'name': 'test-node' - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'nodes', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified cluster '960cd427-2487-4c83-b679-1b5e1f9dd985' " - "could not be found.", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('8ddf45a5-f45f-4cc8-813d-2bff75498576') - def test_node_create_profile_type_unmatch(self): - # Node profile type is different from cluster profile type - params = { - 'node': { - 'profile_id': self.profile_id2, - 'cluster_id': self.cluster_id, - 'metadata': {'k1': 'v1'}, - 'role': 'member', - 'name': 'test-node' - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'nodes', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Node and cluster have different profile type, " - "operation aborted.", str(message)) - - -class TestNodeCreateNegativeInvalidRequest(base.BaseSenlinAPITest): - - @decorators.idempotent_id('b109aa66-2a54-493e-8a07-1ea6f20e17ce') - def test_node_create_empty_param(self): - params = {} - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'nodes', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Request body missing 'node' key.", - str(message)) - - @decorators.idempotent_id('080946ef-a9e0-46b4-add7-da70d05391d6') - def test_node_create_unsupported_param(self): - params = { - 'node': { - 'profile_id': 'fake_profile', - 'name': 'fake_name', - 'boo': 'foo' - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'nodes', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Additional properties are not allowed (u'boo' " - "was unexpected)", str(message)) - - @decorators.idempotent_id('0ac2a77e-082c-47d2-8156-92e7fb43689c') - def test_node_create_miss_name(self): - params = { - 'node': { - 'profile_id': 'fake_profile', - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'nodes', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("'name' is a required property", - str(message)) - - @decorators.idempotent_id('39eb68ed-7808-4a73-85b1-83faca124546') - def test_node_create_miss_profile(self): - params = { - 'node': { - 'name': 'fake', - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'nodes', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("'profile_id' is a required property", - str(message)) diff --git a/senlin/tests/tempest/api/nodes/test_node_delete.py b/senlin/tests/tempest/api/nodes/test_node_delete.py deleted file mode 100644 index 0c53cc656..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_delete.py +++ /dev/null @@ -1,39 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestNodeDelete(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeDelete, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.node_id = utils.create_a_node(self, profile_id) - - @decorators.idempotent_id('29b18f65-2e0e-4a61-b00a-e5803365525b') - def test_node_delete(self): - # Delete test node - res = self.client.delete_obj('nodes', self.node_id) - - # Verify resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIsNone(res['body']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') diff --git a/senlin/tests/tempest/api/nodes/test_node_delete_negative.py b/senlin/tests/tempest/api/nodes/test_node_delete_negative.py deleted file mode 100644 index 2a580c654..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_delete_negative.py +++ /dev/null @@ -1,59 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestNodeDeleteNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('86bd7425-cddd-457e-a467-78e290aceab9') - def test_node_delete_not_found(self): - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.delete_obj, 'nodes', - '86bd7425-cddd-457e-a467-78e290aceab9') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The node '86bd7425-cddd-457e-a467-78e290aceab9' could " - "not be found.", str(message)) - - -class TestNodeDeleteNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeDeleteNegativeBadRequest, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.node_id1 = utils.create_a_node(self, profile_id, name='n-01') - self.addCleanup(utils.delete_a_node, self, self.node_id1) - self.node_id2 = utils.create_a_node(self, profile_id, name='n-01') - self.addCleanup(utils.delete_a_node, self, self.node_id2) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('669203c5-6abd-4e0e-bc66-0bdd588c7b63') - def test_node_delete_multiple_choice(self): - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.delete_obj, - 'nodes', 'n-01') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Multiple results found matching the query criteria 'n-01'. " - "Please be more specific.", str(message)) diff --git a/senlin/tests/tempest/api/nodes/test_node_list.py b/senlin/tests/tempest/api/nodes/test_node_list.py deleted file mode 100644 index 12373149e..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_list.py +++ /dev/null @@ -1,48 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestNodeList(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeList, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.node_id = utils.create_a_node(self, profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @decorators.idempotent_id('cd086dcb-7509-4125-adfc-6beb63b10d0a') - def test_node_list(self): - res = self.client.list_objs('nodes') - - # Verify resp of node list API - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - nodes = res['body'] - node_ids = [] - for node in nodes: - for key in ['cluster_id', 'created_at', 'data', 'domain', - 'id', 'index', 'init_at', 'metadata', 'name', - 'physical_id', 'profile_id', 'profile_name', - 'project', 'role', 'status', 'status_reason', - 'updated_at', 'user']: - self.assertIn(key, node) - node_ids.append(node['id']) - - self.assertIn(self.node_id, node_ids) diff --git a/senlin/tests/tempest/api/nodes/test_node_list_negative.py b/senlin/tests/tempest/api/nodes/test_node_list_negative.py deleted file mode 100644 index 362a3d7b5..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_list_negative.py +++ /dev/null @@ -1,118 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestNodeListNegativeBadRequest(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('d27172ca-00ad-465d-b854-4fac7f1edc13') - def test_node_list_invalid_params(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'nodes', {'bogus': 'foo'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Invalid parameter bogus", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('bb668501-b48e-4355-8bf0-eb9b2e2a89fd') - def test_node_list_cluster_not_found(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'nodes', {'cluster_id': 'fake'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Cannot find the given cluster: fake.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('2e6677ad-8f0d-410e-bd30-baea7882c6fd') - def test_node_list_limit_negative(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'nodes', {'limit': '-5'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Value must be >= 0 for field 'limit'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('57e4fd0c-35ae-4270-a9a2-01e9f89fdaf3') - def test_node_list_limit_not_int(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'nodes', {'limit': 'not-int'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("The value for limit must be an integer: 'not-int'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('733b1812-0ce6-4b21-ab07-3e4dfda10273') - def test_node_list_global_project_false(self): - ex = self.assertRaises(exceptions.Forbidden, - self.client.list_objs, - 'nodes', {'global_project': 'True'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("You are not authorized to complete this operation.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('a9936950-0127-475f-bee6-700a553a7465') - def test_node_list_global_project_not_bool(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'nodes', {'global_project': 'not-bool'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Invalid value 'not-bool' specified for " - "'global_project'", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('688270f0-9f08-43fe-8ff3-4598aa637493') - def test_node_list_invalid_sort(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'nodes', {'sort': 'bad-sort'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Unsupported sort key 'bad-sort' for 'sort'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('0ae75360-4445-4c20-8d26-55a86770ad21') - def test_node_list_invalid_marker(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'nodes', {'marker': 'bad-marker'}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The value for marker is not a valid UUID: 'bad-marker'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('d8d7dd1e-afd8-4921-83b2-c4ce73b1cb22') - def test_node_list_unsupported_status(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'nodes', {'status': ['bad-status']}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Field value ['bad-status'] is invalid", - str(message)) diff --git a/senlin/tests/tempest/api/nodes/test_node_operation.py b/senlin/tests/tempest/api/nodes/test_node_operation.py deleted file mode 100644 index 64858c43c..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_operation.py +++ /dev/null @@ -1,141 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestNodeOperation(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeOperation, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.node_id = utils.create_a_node(self, profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @utils.api_microversion('1.4') - @decorators.idempotent_id('a824fe2c-b8cc-455d-9ec1-73ff9606f9cc') - def test_reboot(self): - params = { - 'reboot': { - 'type': 'SOFT' - } - } - # Trigger node action - res = self.client.trigger_operation('nodes', self.node_id, params) - - # Verfiy resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - -class TestNodeOperationNegative(base.BaseSenlinAPITest): - - @utils.api_microversion('1.3') - @decorators.idempotent_id('4b3fc5dd-507a-4414-859c-44c87a2879fc') - def test_bad_microversion(self): - params = {'reboot': {}} - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_operation, - 'nodes', 'FAKE_ID', params) - message = ex.resp_body['error']['message'] - self.assertEqual( - "API version '1.3' is not supported on this method.", - str(message)) - - @utils.api_microversion('1.4') - @decorators.idempotent_id('2b53a240-7ec6-4d92-bc2d-aaba2e63ee21') - def test_no_operation(self): - params = {} - - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_operation, - 'nodes', 'FAKE_ID', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("No operation specified.", - str(message)) - - @utils.api_microversion('1.4') - @decorators.idempotent_id('b1c3a00b-e00c-4829-ba4a-475f8d34d1d9') - def test_multiple_ops(self): - params = {'foo': {}, 'bar': {}} - - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_operation, - 'nodes', 'FAKE_ID', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Multiple operations specified.", - str(message)) - - -class TestNodeOperationNegativeEngineFailure(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeOperationNegativeEngineFailure, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.node_id = utils.create_a_node(self, profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @utils.api_microversion('1.4') - @decorators.idempotent_id('bbfbd693-4c46-4670-a9d3-5658a43eb0d5') - def test_node_not_found(self): - params = {'dance': {}} - - ex = self.assertRaises(exceptions.NotFound, - self.client.trigger_operation, 'nodes', - 'bbfbd693-4c46-4670-a9d3-5658a43eb0d5', - params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The node 'bbfbd693-4c46-4670-a9d3-5658a43eb0d5' could " - "not be found.", str(message)) - - @utils.api_microversion('1.4') - @decorators.idempotent_id('5c0a23c0-9efe-4d04-9208-0f11da690e79') - def test_operation_not_supported(self): - params = {'dance': {}} - - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_operation, - 'nodes', self.node_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The requested operation 'dance' is not supported by " - "the profile type 'os.nova.server-1.0'.", str(message)) - - @utils.api_microversion('1.4') - @decorators.idempotent_id('b00f1ef8-9ae6-4ed3-8622-566e7d0d3a75') - def test_operation_bad_params(self): - params = {'reboot': {'type': 'Unknown'}} - - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_operation, - 'nodes', self.node_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "'Unknown' must be one of the allowed values: SOFT, HARD.", - str(message)) diff --git a/senlin/tests/tempest/api/nodes/test_node_recover.py b/senlin/tests/tempest/api/nodes/test_node_recover.py deleted file mode 100644 index 3b7f284ae..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_recover.py +++ /dev/null @@ -1,81 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestNodeRecover(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeRecover, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.node_id = utils.create_a_node(self, profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @decorators.idempotent_id('217af65a-4029-40ce-a833-74faeac8c1f5') - def test_node_action_recover(self): - params = { - "recover": { - "operation": "REBUILD" - } - } - # Trigger node action - res = self.client.trigger_action('nodes', self.node_id, params=params) - - # Verfiy resp code, body and location in headers - self.assertEqual(202, res['status']) - self.assertIn('actions', res['location']) - - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - -class TestNodeRecoverNegative(base.BaseSenlinAPITest): - - @decorators.idempotent_id('60790d8a-fd9e-47d8-b9e2-c06aa7701c33') - def test_param_is_not_map(self): - # Recover action parameter is not a map - params = { - 'recover': [] - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.trigger_action, - 'nodes', 'node_id', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("The params provided is not a map.", - str(message)) - - @decorators.idempotent_id('694e59ce-551e-4e77-a684-e77781583e12') - def test_node_not_found(self): - params = { - 'recover': {} - } - - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.trigger_action, - 'nodes', '694e59ce-551e-4e77-a684-e77781583e12', - params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The node '694e59ce-551e-4e77-a684-e77781583e12' could " - "not be found.", str(message)) diff --git a/senlin/tests/tempest/api/nodes/test_node_show.py b/senlin/tests/tempest/api/nodes/test_node_show.py deleted file mode 100644 index 87b49905e..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_show.py +++ /dev/null @@ -1,43 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestNodeShow(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeShow, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.node_id = utils.create_a_node(self, profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @decorators.idempotent_id('302372e8-efa2-4348-88dd-8a1829e5e26c') - def test_node_show(self): - res = self.client.get_obj('nodes', self.node_id) - - # Verify resp of node get API - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - node = res['body'] - for key in ['cluster_id', 'created_at', 'data', 'domain', - 'id', 'index', 'init_at', 'metadata', 'name', - 'physical_id', 'profile_id', 'profile_name', - 'project', 'role', 'status', 'status_reason', - 'updated_at', 'user']: - self.assertIn(key, node) diff --git a/senlin/tests/tempest/api/nodes/test_node_show_negative.py b/senlin/tests/tempest/api/nodes/test_node_show_negative.py deleted file mode 100644 index 4842fd138..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_show_negative.py +++ /dev/null @@ -1,56 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestNodeShowNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('f7a2ed7e-bf92-452b-bc76-37a8bbde2169') - def test_node_show_not_found(self): - ex = self.assertRaises(exceptions.NotFound, - self.client.get_obj, 'nodes', - 'f7a2ed7e-bf92-452b-bc76-37a8bbde2169') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The node 'f7a2ed7e-bf92-452b-bc76-37a8bbde2169' could " - "not be found.", str(message)) - - -class TestNodeShowNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeShowNegativeBadRequest, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.node_id1 = utils.create_a_node(self, profile_id, name='n-01') - self.node_id2 = utils.create_a_node(self, profile_id, name='n-01') - self.addCleanup(utils.delete_a_node, self, self.node_id1) - self.addCleanup(utils.delete_a_node, self, self.node_id2) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('49db9d49-76f1-47a7-9bd2-5e67311c453c') - def test_node_show_multiple_choice(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.get_obj, - 'nodes', 'n-01') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Multiple results found matching the query criteria 'n-01'. " - "Please be more specific.", str(message)) diff --git a/senlin/tests/tempest/api/nodes/test_node_update.py b/senlin/tests/tempest/api/nodes/test_node_update.py deleted file mode 100644 index ce09468ee..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_update.py +++ /dev/null @@ -1,56 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestNodeUpdate(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeUpdate, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - self.node_id = utils.create_a_node(self, profile_id, name='node1', - metadata={'k1': 'v1'}, - role='member') - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @decorators.idempotent_id('bd8a39bf-eee0-4056-aec0-0d8f8706efea') - def test_node_update_basic_properties(self): - # Update basic properties of node - params = { - 'node': { - 'name': 'node_new_name', - 'role': 'admin', - 'metadata': {'k2': 'v2'} - } - } - res = self.client.update_obj('nodes', self.node_id, params) - - # Verify resp of node update API - self.assertEqual(202, res['status']) - self.assertIsNotNone(res['body']) - self.assertIn('actions', res['location']) - node = res['body'] - for key in ['cluster_id', 'created_at', 'data', 'domain', 'id', - 'index', 'init_at', 'metadata', 'name', 'physical_id', - 'profile_id', 'profile_name', 'project', 'role', 'status', - 'status_reason', 'updated_at', 'user']: - self.assertIn(key, node) - - # Wait for node update to be done before moving on - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') diff --git a/senlin/tests/tempest/api/nodes/test_node_update_negative.py b/senlin/tests/tempest/api/nodes/test_node_update_negative.py deleted file mode 100644 index ceec94fe2..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_update_negative.py +++ /dev/null @@ -1,171 +0,0 @@ -# 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. - -import copy -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants -from senlin.tests.tempest.common import utils - - -class TestNodeUpdateNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('608addc9-cbbe-45cd-a00a-495cae7db400') - def test_node_update_node_not_found(self): - ex = self.assertRaises(exceptions.NotFound, - self.client.update_obj, 'nodes', - '608addc9-cbbe-45cd-a00a-495cae7db400', - {'node': {'name': 'new-name'}}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The node '608addc9-cbbe-45cd-a00a-495cae7db400' could " - "not be found.", str(message)) - - -class TestNodeUpdateNegativeProfileNotFound(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeUpdateNegativeProfileNotFound, self).setUp() - # Create a profile - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.profile_id = profile_id - # Create a node - self.node_id = utils.create_a_node(self, profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('3243dd63-1008-4181-849a-0058af975800') - def test_node_update_profile_not_found(self): - # Provided profile can not be found - params = { - 'node': { - 'profile_id': '3243dd63-1008-4181-849a-0058af975800', - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, - 'nodes', self.node_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The specified profile '3243dd63-1008-4181-849a-0058af975800' " - "could not be found.", str(message)) - - -class TestNodeUpdateNegativeProfileMultichoices(base.BaseSenlinAPITest): - def setUp(self): - super(TestNodeUpdateNegativeProfileMultichoices, self).setUp() - # Create a profile - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.profile_id = profile_id - # Create a node - self.node_id = utils.create_a_node(self, profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - # Create two new profiles of the same type with the same name - new_spec = copy.deepcopy(constants.spec_nova_server) - new_spec['properties']['flavor'] = 'new_flavor' - new_profile_id1 = utils.create_a_profile(self, new_spec, name='p-nova') - new_profile_id2 = utils.create_a_profile(self, new_spec, name='p-nova') - self.addCleanup(utils.delete_a_profile, self, new_profile_id1) - self.addCleanup(utils.delete_a_profile, self, new_profile_id2) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('0d73eff6-1916-43e1-9518-31820fcfe01f') - def test_node_update_profile_multichoices(self): - # Multiple profiles are found for given name - params = { - 'node': { - 'profile_id': 'p-nova', - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, - 'nodes', self.node_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Multiple results found matching the query criteria 'p-nova'. " - "Please be more specific.", str(message)) - - -class TestNodeUpdateNegativeProfileTypeUnmatch(base.BaseSenlinAPITest): - def setUp(self): - super(TestNodeUpdateNegativeProfileTypeUnmatch, self).setUp() - # Create a profile - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.profile_id = profile_id - # Create a node - self.node_id = utils.create_a_node(self, profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - # Create a new profile of different type - self.new_profile_id = utils.create_a_profile( - self, spec=constants.spec_heat_stack) - self.addCleanup(utils.delete_a_profile, self, self.new_profile_id) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('ec5821d8-142e-4fff-a998-81428ecc239c') - def test_node_update_profile_type_unmatch(self): - # New profile type is different from original cone - params = { - 'node': { - 'profile_id': self.new_profile_id, - } - } - - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, - 'nodes', self.node_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Cannot update a node to a different profile type, " - "operation aborted.", str(message)) - - -class TestNodeUpdateNegativeNoPropertyUpdated(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeUpdateNegativeNoPropertyUpdated, self).setUp() - # Create a profile - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.profile_id = profile_id - # Create a node - self.node_id = utils.create_a_node(self, profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('ed6f385d-780b-4562-928d-3e00f27550d2') - def test_node_update_no_property_updated(self): - # Provided profile can not be found - params = { - 'node': {} - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, - 'nodes', self.node_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual("No property needs an update.", - str(message)) diff --git a/senlin/tests/tempest/api/nodes/test_node_update_profile.py b/senlin/tests/tempest/api/nodes/test_node_update_profile.py deleted file mode 100644 index 73d73948c..000000000 --- a/senlin/tests/tempest/api/nodes/test_node_update_profile.py +++ /dev/null @@ -1,60 +0,0 @@ -# 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. - -import copy -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants -from senlin.tests.tempest.common import utils - - -class TestNodeUpdateProfile(base.BaseSenlinAPITest): - - def setUp(self): - super(TestNodeUpdateProfile, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - new_spec = copy.deepcopy(constants.spec_nova_server) - new_spec['properties']['flavor'] = 'new_flavor' - new_spec['properties']['image'] = 'new_image' - self.new_profile_id = utils.create_a_profile(self, new_spec) - self.addCleanup(utils.delete_a_profile, self, self.new_profile_id) - - self.node_id = utils.create_a_node(self, profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @decorators.idempotent_id('de9465f2-95b4-41ce-81f5-b092967cb2b8') - def test_node_update_profile(self): - # Update node with new profile - params = { - 'node': { - 'profile_id': self.new_profile_id - } - } - res = self.client.update_obj('nodes', self.node_id, params) - - # Verify resp of node update API - self.assertEqual(202, res['status']) - self.assertIsNotNone(res['body']) - self.assertIn('actions', res['location']) - node = res['body'] - for key in ['cluster_id', 'created_at', 'data', 'domain', 'id', - 'index', 'init_at', 'metadata', 'name', 'physical_id', - 'profile_id', 'profile_name', 'project', 'role', 'status', - 'status_reason', 'updated_at', 'user']: - self.assertIn(key, node) - - # Wait for node update to be done before moving on - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') diff --git a/senlin/tests/tempest/api/policies/__init__.py b/senlin/tests/tempest/api/policies/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/api/policies/test_policy_create.py b/senlin/tests/tempest/api/policies/test_policy_create.py deleted file mode 100644 index 1dcb06c96..000000000 --- a/senlin/tests/tempest/api/policies/test_policy_create.py +++ /dev/null @@ -1,47 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants - - -class TestPolicyCreate(base.BaseSenlinAPITest): - - def setUp(self): - super(TestPolicyCreate, self).setUp() - self.policy_id = None - - @decorators.idempotent_id('f50648d9-f38c-479a-a82b-3c6909733496') - def test_policy_create(self): - params = { - 'policy': { - 'name': 'test-scaling-policy', - 'spec': constants.spec_scaling_policy, - } - } - res = self.client.create_obj('policies', params) - - # Verify resp of receiver create API - self.assertEqual(201, res['status']) - self.assertIsNotNone(res['body']) - policy = res['body'] - - self.addCleanup(self.client.delete_obj, 'policies', policy['id']) - - for key in ['created_at', 'data', 'domain', 'id', 'name', 'project', - 'spec', 'type', 'updated_at', 'user']: - self.assertIn(key, policy) - self.assertEqual('test-scaling-policy', policy['name']) - self.assertEqual('senlin.policy.scaling-1.0', policy['type']) - self.assertEqual(constants.spec_scaling_policy, policy['spec']) diff --git a/senlin/tests/tempest/api/policies/test_policy_create_negative.py b/senlin/tests/tempest/api/policies/test_policy_create_negative.py deleted file mode 100644 index 07ebe973a..000000000 --- a/senlin/tests/tempest/api/policies/test_policy_create_negative.py +++ /dev/null @@ -1,112 +0,0 @@ -# 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. - -import copy -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants - - -class TestPolicyCreateNegativeBadRequest(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('3fea4aa9-6dee-4202-8611-cf2d008a4d42') - def test_policy_create_policy_data_not_specified(self): - params = { - 'policy': { - 'name': 'test-policy' - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'policies', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("'spec' is a required property", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('4a4d6c83-f0fa-4c9e-914b-d89478903d95') - def test_policy_create_name_not_specified(self): - params = { - 'policy': { - 'spec': constants.spec_scaling_policy - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'policies', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("'name' is a required property", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('b898de6c-996a-4bc3-bdef-6490e62fb3b0') - def test_policy_create_invalid_param(self): - params = { - 'policy': { - 'boo': 'foo' - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'policies', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Additional properties are not allowed (u'boo' was " - "unexpected)", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('1c0ed145-bca6-4e53-b222-44fc6978eb1f') - def test_policy_create_policy_type_incorrect(self): - spec = copy.deepcopy(constants.spec_scaling_policy) - spec['type'] = 'senlin.policy.bogus' - params = { - 'policy': { - 'name': 'test-policy', - 'spec': spec - } - } - # Verify badrequest exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.create_obj, - 'policies', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The policy_type 'senlin.policy.bogus-1.0' could " - "not be found.", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('f55dc7eb-9863-49c2-b001-368d2057c53c') - def test_policy_create_spec_validation_failed(self): - spec = copy.deepcopy(constants.spec_scaling_policy) - spec['properties']['bogus'] = 'foo' - params = { - 'policy': { - 'name': 'test-policy', - 'spec': spec - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.ServerFault, - self.client.create_obj, - 'policies', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Unrecognizable spec item 'bogus'", - str(message)) diff --git a/senlin/tests/tempest/api/policies/test_policy_delete.py b/senlin/tests/tempest/api/policies/test_policy_delete.py deleted file mode 100644 index 381d926e1..000000000 --- a/senlin/tests/tempest/api/policies/test_policy_delete.py +++ /dev/null @@ -1,31 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestPolicyDelete(base.BaseSenlinAPITest): - - def setUp(self): - super(TestPolicyDelete, self).setUp() - self.policy_id = utils.create_a_policy(self) - - @decorators.idempotent_id('b707e4e3-3d42-4a9f-9a09-3e330959b498') - def test_policy_delete(self): - # Verify resp of policy delete API - res = self.client.delete_obj('policies', self.policy_id) - self.assertEqual(204, res['status']) - self.assertIsNone(res['body']) - self.assertEqual('0', res['content-length']) diff --git a/senlin/tests/tempest/api/policies/test_policy_delete_negative.py b/senlin/tests/tempest/api/policies/test_policy_delete_negative.py deleted file mode 100644 index 2a7dfbf0b..000000000 --- a/senlin/tests/tempest/api/policies/test_policy_delete_negative.py +++ /dev/null @@ -1,87 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestPolicyDeleteNegativeConflict(base.BaseSenlinAPITest): - - def setUp(self): - super(TestPolicyDeleteNegativeConflict, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, cluster_id) - - self.policy_id = utils.create_a_policy(self) - self.addCleanup(utils.delete_a_policy, self, self.policy_id) - - utils.cluster_attach_policy(self, cluster_id, self.policy_id) - self.addCleanup(utils.cluster_detach_policy, self, cluster_id, - self.policy_id) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('b8b8fca8-962f-4cad-bfca-76683df7b617') - def test_policy_delete_conflict(self): - # Verify conflict exception(409) is raised. - ex = self.assertRaises(exceptions.Conflict, - self.client.delete_obj, - 'policies', self.policy_id) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The policy '%s' cannot be deleted: still attached to some " - "clusters." % self.policy_id, str(message)) - - -class TestPolicyDeleteNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('5591416f-4646-46c2-83b4-231e72aa4bfe') - def test_policy_delete_not_found(self): - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.delete_obj, 'policies', - '5591416f-4646-46c2-83b4-231e72aa4bfe') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The policy '5591416f-4646-46c2-83b4-231e72aa4bfe' " - "could not be found.", str(message)) - - -class TestPolicyDeleteNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestPolicyDeleteNegativeBadRequest, self).setUp() - self.policy_id1 = utils.create_a_policy(self, name='p-01') - self.addCleanup(utils.delete_a_policy, self, self.policy_id1) - self.policy_id2 = utils.create_a_policy(self, name='p-01') - self.addCleanup(utils.delete_a_policy, self, self.policy_id2) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('d6f35043-2db5-49ff-8bc4-ba14a652f748') - def test_policy_delete_multiple_choice(self): - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.delete_obj, - 'policies', 'p-01') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Multiple results found matching the query criteria 'p-01'. " - "Please be more specific.", str(message)) diff --git a/senlin/tests/tempest/api/policies/test_policy_list.py b/senlin/tests/tempest/api/policies/test_policy_list.py deleted file mode 100644 index 5b5e542e5..000000000 --- a/senlin/tests/tempest/api/policies/test_policy_list.py +++ /dev/null @@ -1,41 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestPolicyList(base.BaseSenlinAPITest): - - def setUp(self): - super(TestPolicyList, self).setUp() - self.policy_id = utils.create_a_policy(self) - self.addCleanup(utils.delete_a_policy, self, self.policy_id) - - @decorators.idempotent_id('67ce5d15-c1fd-402f-bcd8-2974dbd93da8') - def test_policy_list(self): - res = self.client.list_objs('policies') - - # Verify resp of policy list API - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - policies = res['body'] - ids = [] - for policy in policies: - for key in ['created_at', 'data', 'domain', 'id', 'name', - 'project', 'spec', 'type', 'updated_at', 'user']: - self.assertIn(key, policy) - ids.append(policy['id']) - self.assertIn(self.policy_id, ids) diff --git a/senlin/tests/tempest/api/policies/test_policy_list_negative.py b/senlin/tests/tempest/api/policies/test_policy_list_negative.py deleted file mode 100644 index e3961295d..000000000 --- a/senlin/tests/tempest/api/policies/test_policy_list_negative.py +++ /dev/null @@ -1,85 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestPolicyListNegativeBadRequest(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('b936b936-f891-4389-bbeb-f81b7dc3c688') - def test_policy_list_invalid_params(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'policies', {'bogus': 'foo'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Invalid parameter bogus", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('04ce3766-acf9-4549-91c8-e6ffdf7bafbd') - def test_policy_list_limit_not_int(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'policies', {'limit': 'not-int'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("The value for limit must be an integer: 'not-int'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('cfd50d13-5ed8-48d9-b03f-95480ba06fad') - def test_policy_list_global_project_false(self): - ex = self.assertRaises(exceptions.Forbidden, - self.client.list_objs, - 'policies', {'global_project': 'True'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("You are not authorized to complete this operation.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('ab477cf8-6c37-4762-bd85-d55b46444d8f') - def test_policy_list_global_project_not_bool(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'policies', {'global_project': 'not-bool'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Invalid value 'not-bool' specified for " - "'global_project'", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('f5bd7807-2b3e-43b2-8ed6-7bdb5e9af46b') - def test_policy_list_invalid_sort(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'policies', {'sort': 'bad-sort'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Unsupported sort key 'bad-sort' for 'sort'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('077f39f0-bb2a-4de8-9568-2ed49e99b720') - def test_policy_list_invalid_marker(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'policies', {'marker': 'bad-marker'}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The value for marker is not a valid UUID: 'bad-marker'.", - str(message)) diff --git a/senlin/tests/tempest/api/policies/test_policy_show.py b/senlin/tests/tempest/api/policies/test_policy_show.py deleted file mode 100644 index 1075c80c0..000000000 --- a/senlin/tests/tempest/api/policies/test_policy_show.py +++ /dev/null @@ -1,37 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestPolicyShow(base.BaseSenlinAPITest): - - def setUp(self): - super(TestPolicyShow, self).setUp() - self.policy_id = utils.create_a_policy(self) - self.addCleanup(utils.delete_a_policy, self, self.policy_id) - - @decorators.idempotent_id('7ab18be1-e554-452d-91ac-9b5e5c87430b') - def test_policy_show(self): - res = self.client.get_obj('policies', self.policy_id) - - # Verify resp of policy show API - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - policy = res['body'] - for key in ['created_at', 'data', 'domain', 'id', 'name', 'project', - 'spec', 'type', 'updated_at', 'user']: - self.assertIn(key, policy) diff --git a/senlin/tests/tempest/api/policies/test_policy_show_negative.py b/senlin/tests/tempest/api/policies/test_policy_show_negative.py deleted file mode 100644 index e79b0f646..000000000 --- a/senlin/tests/tempest/api/policies/test_policy_show_negative.py +++ /dev/null @@ -1,54 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestPolicyShowNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('f1615466-7fca-4670-8c9a-66cb4bb24e54') - def test_policy_show_not_found(self): - ex = self.assertRaises(exceptions.NotFound, - self.client.get_obj, 'policies', - 'f1615466-7fca-4670-8c9a-66cb4bb24e54') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The policy 'f1615466-7fca-4670-8c9a-66cb4bb24e54' " - "could not be found.", str(message)) - - -class TestPolicyShowNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestPolicyShowNegativeBadRequest, self).setUp() - self.policy_id1 = utils.create_a_policy(self, name='p-01') - self.policy_id2 = utils.create_a_policy(self, name='p-01') - self.addCleanup(utils.delete_a_policy, self, self.policy_id1) - self.addCleanup(utils.delete_a_policy, self, self.policy_id2) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('c2eadbae-29b7-4d12-a407-259f387286f5') - def test_policy_show_multiple_choice(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.get_obj, - 'policies', 'p-01') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Multiple results found matching the query criteria 'p-01'. " - "Please be more specific.", str(message)) diff --git a/senlin/tests/tempest/api/policies/test_policy_update.py b/senlin/tests/tempest/api/policies/test_policy_update.py deleted file mode 100644 index ce78f0f90..000000000 --- a/senlin/tests/tempest/api/policies/test_policy_update.py +++ /dev/null @@ -1,42 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestPolicyUpdate(base.BaseSenlinAPITest): - - def setUp(self): - super(TestPolicyUpdate, self).setUp() - self.policy_id = utils.create_a_policy(self) - self.addCleanup(utils.delete_a_policy, self, self.policy_id) - - @decorators.idempotent_id('dbe9c6a6-882c-41cf-b862-7f648804db24') - def test_policy_update(self): - params = { - 'policy': { - 'name': 'updated-policy-name' - } - } - res = self.client.update_obj('policies', self.policy_id, params) - - # Verify resp of policy update API - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - policy = res['body'] - for key in ['created_at', 'data', 'domain', 'id', 'name', 'project', - 'spec', 'type', 'updated_at', 'user']: - self.assertIn(key, policy) - self.assertEqual('updated-policy-name', policy['name']) diff --git a/senlin/tests/tempest/api/policies/test_policy_update_negative.py b/senlin/tests/tempest/api/policies/test_policy_update_negative.py deleted file mode 100644 index aafd09167..000000000 --- a/senlin/tests/tempest/api/policies/test_policy_update_negative.py +++ /dev/null @@ -1,107 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestPolicyUpdateNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('5df90d82-9889-4c6f-824c-30272bcfa767') - def test_policy_update_policy_not_found(self): - ex = self.assertRaises(exceptions.NotFound, - self.client.update_obj, 'policies', - '5df90d82-9889-4c6f-824c-30272bcfa767', - {'policy': {'name': 'new-name'}}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The policy '5df90d82-9889-4c6f-824c-30272bcfa767' " - "could not be found.", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('29414add-9cba-4b72-a7bb-36718671dcab') - def test_policy_update_policy_invalid_param(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, 'policies', - '5df90d82-9889-4c6f-824c-30272bcfa767', - {'policy': {'boo': 'foo'}}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Additional properties are not allowed (u'boo' was " - "unexpected)", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('bf26ed1e-1d26-4472-b4c8-0bcca1c0a838') - def test_policy_update_policy_empty_param(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, 'policies', - '5df90d82-9889-4c6f-824c-30272bcfa767', - {}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Malformed request data, missing 'policy' key in " - "request body.", str(message)) - - -class TestPolicyUpdateNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestPolicyUpdateNegativeBadRequest, self).setUp() - # Create a policy - policy_id = utils.create_a_policy(self) - self.addCleanup(utils.delete_a_policy, self, policy_id) - self.policy_id = policy_id - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('31242de5-55ac-4589-87a1-a9940e4beca2') - def test_policy_update_no_property_updated(self): - # No property is updated. - params = { - 'policy': {} - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, - 'policies', self.policy_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "'name' is a required property", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('d2ca7de6-0069-48c9-b3de-ee975a2428dc') - def test_policy_update_spec_not_updatable(self): - # Try to update spec of policy. - # Note: name is the only property that can be updated - # after policy is created. - params = { - 'policy': { - 'name': 'new-name', - 'spec': {'k1': 'v1'} - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, - 'policies', self.policy_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Additional properties are not allowed (u'spec' was " - "unexpected)", str(message)) diff --git a/senlin/tests/tempest/api/policies/test_policy_validate.py b/senlin/tests/tempest/api/policies/test_policy_validate.py deleted file mode 100644 index 4b3cca3dc..000000000 --- a/senlin/tests/tempest/api/policies/test_policy_validate.py +++ /dev/null @@ -1,44 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants - - -class TestPolicyValidate(base.BaseSenlinAPITest): - - def setUp(self): - super(TestPolicyValidate, self).setUp() - self.policy_id = None - - @decorators.idempotent_id('a3f5ad0d-4f3d-4b40-b473-1cfc562cfcee') - def test_policy_validate(self): - params = { - 'policy': { - 'spec': constants.spec_scaling_policy, - } - } - res = self.client.validate_obj('policies', params) - - # Verify resp of policy validate API - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - policy = res['body'] - - for key in ['created_at', 'data', 'domain', 'id', 'name', 'project', - 'spec', 'type', 'updated_at', 'user']: - self.assertIn(key, policy) - self.assertEqual('validated_policy', policy['name']) - self.assertEqual('senlin.policy.scaling-1.0', policy['type']) - self.assertEqual(constants.spec_scaling_policy, policy['spec']) diff --git a/senlin/tests/tempest/api/policies/test_policy_validate_negative.py b/senlin/tests/tempest/api/policies/test_policy_validate_negative.py deleted file mode 100644 index 258337ef1..000000000 --- a/senlin/tests/tempest/api/policies/test_policy_validate_negative.py +++ /dev/null @@ -1,106 +0,0 @@ -# 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. - -import copy -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants - - -class TestPolicyValidateNegativeBadRequest(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('4b55bb3e-12d6-4728-9b53-9db5094ac8b5') - def test_policy_validate_with_empty_body(self): - params = {} - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.validate_obj, - 'policies', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Request body missing 'policy' key.", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('4c9f26cc-f4f3-4303-9f29-f30fae400843') - def test_policy_validate_invalid_param(self): - params = { - 'policy': { - 'name': 'fake' - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.validate_obj, - 'policies', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Additional properties are not allowed (u'name' " - "was unexpected)", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('a1c35d93-2d19-4a72-919f-cfd70f5cbf06') - def test_policy_validate_no_spec(self): - params = { - 'policy': {} - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.validate_obj, - 'policies', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "'spec' is a required property", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('6073da36-ee3e-4925-bce1-6c9a158e710d') - def test_policy_validate_policy_type_incorrect(self): - spec = copy.deepcopy(constants.spec_scaling_policy) - spec['type'] = 'senlin.policy.bogus' - params = { - 'policy': { - 'spec': spec - } - } - # Verify badrequest exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.validate_obj, - 'policies', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The policy_type 'senlin.policy.bogus-1.0' could " - "not be found.", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('1e1833ea-4a67-4ac1-b6e2-f9afff51c945') - def test_policy_validate_spec_validation_failed(self): - spec = copy.deepcopy(constants.spec_scaling_policy) - spec['properties']['bogus'] = 'foo' - params = { - 'policy': { - 'spec': spec - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.ServerFault, - self.client.validate_obj, - 'policies', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Unrecognizable spec item 'bogus'", str(message)) diff --git a/senlin/tests/tempest/api/policy_types/__init__.py b/senlin/tests/tempest/api/policy_types/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/api/policy_types/test_policy_type_list.py b/senlin/tests/tempest/api/policy_types/test_policy_type_list.py deleted file mode 100644 index d32bf0300..000000000 --- a/senlin/tests/tempest/api/policy_types/test_policy_type_list.py +++ /dev/null @@ -1,55 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestPolicyTypeList(base.BaseSenlinAPITest): - - @utils.api_microversion('1.4') - @decorators.idempotent_id('72cc0347-3eab-4cf6-b1ee-531b11f20550') - def test_policy_type_list(self): - res = self.client.list_objs('policy-types') - - # Verify resp of policy type list API - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - policy_types = res['body'] - for policy_type in policy_types: - self.assertIn('name', policy_type) - - @utils.api_microversion('1.5') - @decorators.idempotent_id('1900b22a-012d-41f0-85a2-8aa6b65ec2ca') - def test_policy_type_list_v1_5(self): - res = self.client.list_objs('policy-types') - - # Verify resp of policy type list API - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - policy_types = res['body'] - expected_names = [ - 'senlin.policy.affinity', - 'senlin.policy.batch', - 'senlin.policy.deletion', - 'senlin.policy.health', - 'senlin.policy.loadbalance', - 'senlin.policy.region_placement', - 'senlin.policy.scaling', - 'senlin.policy.zone_placement', - ] - for t in policy_types: - self.assertIn(t['name'], expected_names) - self.assertIsNotNone(t['support_status']) - self.assertIsNotNone(t['version']) diff --git a/senlin/tests/tempest/api/policy_types/test_policy_type_show.py b/senlin/tests/tempest/api/policy_types/test_policy_type_show.py deleted file mode 100644 index 640d65fd6..000000000 --- a/senlin/tests/tempest/api/policy_types/test_policy_type_show.py +++ /dev/null @@ -1,46 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestPolicyTypeShow(base.BaseSenlinAPITest): - - @utils.api_microversion('1.4') - @decorators.idempotent_id('57791ed7-7f57-4369-ba6e-7e039169ebdc') - def test_policy_type_show(self): - res = self.client.get_obj('policy-types', 'senlin.policy.deletion-1.0') - - # Verify resp of policy type show API - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - policy_type = res['body'] - for key in ['name', 'schema']: - self.assertIn(key, policy_type) - self.assertEqual('senlin.policy.deletion-1.0', policy_type['name']) - - @utils.api_microversion('1.5') - @decorators.idempotent_id('1900b22a-012d-41f0-85a2-8aa6b65ec2ca') - def test_policy_type_show_v1_5(self): - res = self.client.get_obj('policy-types', 'senlin.policy.deletion-1.0') - - # Verify resp of policy type show API - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - policy_type = res['body'] - for key in ['name', 'schema', 'support_status']: - self.assertIn(key, policy_type) - self.assertEqual('senlin.policy.deletion-1.0', policy_type['name']) - self.assertIsNotNone(policy_type['support_status']) diff --git a/senlin/tests/tempest/api/policy_types/test_policy_type_show_negative.py b/senlin/tests/tempest/api/policy_types/test_policy_type_show_negative.py deleted file mode 100644 index 6edae3551..000000000 --- a/senlin/tests/tempest/api/policy_types/test_policy_type_show_negative.py +++ /dev/null @@ -1,32 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestPolicyTypeShowNegative(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('13d70be3-5998-412b-ab75-da72a2f84c75') - def test_policy_type_show_not_found(self): - ex = self.assertRaises(exceptions.NotFound, - self.client.get_obj, - 'policy-types', - '13d70be3-5998-412b-ab75-da72a2f84c75') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The policy_type '13d70be3-5998-412b-ab75-da72a2f84c75' " - "could not be found.", str(message)) diff --git a/senlin/tests/tempest/api/profile_types/__init__.py b/senlin/tests/tempest/api/profile_types/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/api/profile_types/test_profile_type_list.py b/senlin/tests/tempest/api/profile_types/test_profile_type_list.py deleted file mode 100644 index 34d8a8f32..000000000 --- a/senlin/tests/tempest/api/profile_types/test_profile_type_list.py +++ /dev/null @@ -1,55 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestProfileTypeList(base.BaseSenlinAPITest): - - @utils.api_microversion('1.4') - @decorators.idempotent_id('fa0cf9e3-5b75-4d4d-9a0f-1748772b65d3') - def test_profile_type_list(self): - res = self.client.list_objs('profile-types') - - # Verify resp of profile type list API - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - profile_types = res['body'] - expected_profile_types = [ - {'name': 'os.nova.server-1.0'}, - {'name': 'os.heat.stack-1.0'}, - {'name': 'container.dockerinc.docker-1.0'} - ] - for profile_type in expected_profile_types: - self.assertIn(profile_type, profile_types) - - @utils.api_microversion('1.5') - @decorators.idempotent_id('778d41df-0ce0-421f-98e5-2efdcec6d995') - def test_profile_type_list_v1_5(self): - res = self.client.list_objs('profile-types') - - # Verify resp of profile type list API - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - profile_types = res['body'] - expected_names = [ - 'os.nova.server', - 'os.heat.stack', - 'container.dockerinc.docker' - ] - for t in profile_types: - self.assertIn(t['name'], expected_names) - self.assertIsNotNone(t['support_status']) - self.assertIsNotNone(t['version']) diff --git a/senlin/tests/tempest/api/profile_types/test_profile_type_show.py b/senlin/tests/tempest/api/profile_types/test_profile_type_show.py deleted file mode 100644 index 57e47da5f..000000000 --- a/senlin/tests/tempest/api/profile_types/test_profile_type_show.py +++ /dev/null @@ -1,46 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestProfileTypeShow(base.BaseSenlinAPITest): - - @utils.api_microversion('1.4') - @decorators.idempotent_id('198165b3-1c1f-4801-8918-90c1adbf57c8') - def test_profile_type_show(self): - res = self.client.get_obj('profile-types', 'os.nova.server-1.0') - - # Verify resp of profile type show API - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - profile_type = res['body'] - for key in ['name', 'schema']: - self.assertIn(key, profile_type) - self.assertEqual('os.nova.server-1.0', profile_type['name']) - - @utils.api_microversion('1.5') - @decorators.idempotent_id('778d41df-0ce0-421f-98e5-2efdcec6d995') - def test_profile_type_show_v1_5(self): - res = self.client.get_obj('profile-types', 'os.nova.server-1.0') - - # Verify resp of profile type show API - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - profile_type = res['body'] - for key in ['name', 'schema', 'support_status']: - self.assertIn(key, profile_type) - self.assertEqual('os.nova.server-1.0', profile_type['name']) - self.assertIsNotNone(profile_type['support_status']) diff --git a/senlin/tests/tempest/api/profile_types/test_profile_type_show_negative.py b/senlin/tests/tempest/api/profile_types/test_profile_type_show_negative.py deleted file mode 100644 index 026afc687..000000000 --- a/senlin/tests/tempest/api/profile_types/test_profile_type_show_negative.py +++ /dev/null @@ -1,32 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestProfileTypeShowNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('58181c56-3166-4478-8981-e1d476065f2b') - def test_profile_type_show_not_found(self): - ex = self.assertRaises(exceptions.NotFound, - self.client.get_obj, - 'profile-types', - '58181c56-3166-4478-8981-e1d476065f2b') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The profile_type '58181c56-3166-4478-8981-e1d476065f2b' " - "could not be found.", str(message)) diff --git a/senlin/tests/tempest/api/profiles/__init__.py b/senlin/tests/tempest/api/profiles/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/api/profiles/test_profile_create.py b/senlin/tests/tempest/api/profiles/test_profile_create.py deleted file mode 100644 index b8acba82b..000000000 --- a/senlin/tests/tempest/api/profiles/test_profile_create.py +++ /dev/null @@ -1,45 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants -from senlin.tests.tempest.common import utils - - -class TestProfileCreate(base.BaseSenlinAPITest): - - @decorators.idempotent_id('76216581-e78a-42f5-bf1d-65d83bd206fc') - def test_profile_create(self): - params = { - 'profile': { - 'name': 'test-profile', - 'spec': constants.spec_nova_server, - 'metadata': {'foo': 'bar'} - } - } - res = self.client.create_obj('profiles', params) - - # Verify resp of profile create API - self.assertEqual(201, res['status']) - self.assertIsNotNone(res['body']) - profile = res['body'] - self.addCleanup(utils.delete_a_profile, self, profile['id']) - - for key in ['created_at', 'domain', 'id', 'metadata', 'name', - 'project', 'spec', 'type', 'updated_at', 'user']: - self.assertIn(key, profile) - self.assertEqual('test-profile', profile['name']) - self.assertEqual('os.nova.server-1.0', profile['type']) - self.assertEqual(constants.spec_nova_server, profile['spec']) - self.assertEqual({'foo': 'bar'}, profile['metadata']) diff --git a/senlin/tests/tempest/api/profiles/test_profile_create_negative.py b/senlin/tests/tempest/api/profiles/test_profile_create_negative.py deleted file mode 100644 index 33232a03d..000000000 --- a/senlin/tests/tempest/api/profiles/test_profile_create_negative.py +++ /dev/null @@ -1,130 +0,0 @@ -# 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. - -import copy -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants - - -class TestProfileCreateNegativeBadRequest(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('0f0183b8-0f5e-4367-993d-863ff1f30d49') - def test_profile_create_profile_data_not_specified(self): - params = { - 'profile': { - 'name': 'test-profile' - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'profiles', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Request body missing 'profile' key.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('c341f22d-833b-4676-8b66-e6cdb0b77abd') - def test_profile_create_name_not_specified(self): - params = { - 'profile': { - 'spec': constants.spec_nova_server - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'profiles', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("'name' is a required property", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('5e644149-a7e6-4e93-8220-4a32f98d6e25') - def test_profile_create_spec_not_specified(self): - params = { - 'profile': { - 'name': 'test-profile' - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'profiles', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("'spec' is a required property", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('e2da6964-2cd2-402e-9004-ca6b7e3e63f1') - def test_profile_create_invalid_param(self): - params = { - 'profile': { - 'boo': 'foo' - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'profiles', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Additional properties are not allowed (u'boo' was " - "unexpected)", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('591f3670-3fec-4645-bae2-4f6dec28d70c') - def test_profile_create_profile_type_incorrect(self): - spec = copy.deepcopy(constants.spec_nova_server) - spec['type'] = 'senlin.profile.bogus' - params = { - 'profile': { - 'name': 'test-profile', - 'spec': spec - } - } - # Verify badrequest exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.create_obj, - 'profiles', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The profile_type 'senlin.profile.bogus-1.0' could " - "not be found.", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('66977f7a-5d30-481c-a5ec-a445e80a7c0f') - def test_profile_create_spec_validation_failed(self): - spec = copy.deepcopy(constants.spec_nova_server) - spec['properties']['bogus'] = 'foo' - params = { - 'profile': { - 'name': 'test-profile', - 'spec': spec - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'profiles', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Failed in creating profile test-profile: " - "Unrecognizable spec item 'bogus'", str(message)) diff --git a/senlin/tests/tempest/api/profiles/test_profile_delete.py b/senlin/tests/tempest/api/profiles/test_profile_delete.py deleted file mode 100644 index 916e520a6..000000000 --- a/senlin/tests/tempest/api/profiles/test_profile_delete.py +++ /dev/null @@ -1,31 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestProfileDelete(base.BaseSenlinAPITest): - - def setUp(self): - super(TestProfileDelete, self).setUp() - self.profile_id = utils.create_a_profile(self) - - @decorators.idempotent_id('ea3c1b9e-5ed7-4d63-84ce-2032c3bc6d27') - def test_profile_delete(self): - # Verify resp of profile delete API - res = self.client.delete_obj('profiles', self.profile_id) - self.assertEqual(204, res['status']) - self.assertIsNone(res['body']) - self.assertEqual('0', res['content-length']) diff --git a/senlin/tests/tempest/api/profiles/test_profile_delete_negative.py b/senlin/tests/tempest/api/profiles/test_profile_delete_negative.py deleted file mode 100644 index bbea93800..000000000 --- a/senlin/tests/tempest/api/profiles/test_profile_delete_negative.py +++ /dev/null @@ -1,79 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestProfileDeleteNegativeConflict(base.BaseSenlinAPITest): - - def setUp(self): - super(TestProfileDeleteNegativeConflict, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, cluster_id) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('8e5e8414-b757-41f4-b633-e0fa83d72ea2') - def test_profile_delete_conflict(self): - # Verify conflict exception(409) is raised. - ex = self.assertRaises(exceptions.Conflict, - self.client.delete_obj, - 'profiles', self.profile_id) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The profile '%s' cannot be deleted: still referenced by " - "some clusters and/or nodes." % self.profile_id, str(message)) - - -class TestProfileDeleteNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('b6e7911d-5f65-4ec6-a08b-b88809fe2b9e') - def test_profile_delete_not_found(self): - # Verify notfound exception(404) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.delete_obj, 'profiles', - 'b6e7911d-5f65-4ec6-a08b-b88809fe2b9e') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The profile 'b6e7911d-5f65-4ec6-a08b-b88809fe2b9e' " - "could not be found.", str(message)) - - -class TestProfileDeleteNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestProfileDeleteNegativeBadRequest, self).setUp() - self.profile_id1 = utils.create_a_profile(self, name='p-01') - self.addCleanup(utils.delete_a_profile, self, self.profile_id1) - self.profile_id2 = utils.create_a_profile(self, name='p-01') - self.addCleanup(utils.delete_a_profile, self, self.profile_id2) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('b6e7911d-5f65-4ec6-a08b-b88809fe2b9e') - def test_profile_delete_multiple_choice(self): - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.delete_obj, - 'profiles', 'p-01') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Multiple results found matching the query criteria 'p-01'. " - "Please be more specific.", str(message)) diff --git a/senlin/tests/tempest/api/profiles/test_profile_list.py b/senlin/tests/tempest/api/profiles/test_profile_list.py deleted file mode 100644 index 158cc543f..000000000 --- a/senlin/tests/tempest/api/profiles/test_profile_list.py +++ /dev/null @@ -1,41 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestProfileList(base.BaseSenlinAPITest): - - def setUp(self): - super(TestProfileList, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - - @decorators.idempotent_id('329d3026-12f7-4369-845b-05914e2a8678') - def test_profile_list(self): - res = self.client.list_objs('profiles') - - # Verify resp of profile list API - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - profiles = res['body'] - ids = [] - for profile in profiles: - for key in ['created_at', 'domain', 'id', 'metadata', 'name', - 'project', 'spec', 'type', 'updated_at', 'user']: - self.assertIn(key, profile) - ids.append(profile['id']) - self.assertIn(self.profile_id, ids) diff --git a/senlin/tests/tempest/api/profiles/test_profile_list_negative.py b/senlin/tests/tempest/api/profiles/test_profile_list_negative.py deleted file mode 100644 index c1dd1fa63..000000000 --- a/senlin/tests/tempest/api/profiles/test_profile_list_negative.py +++ /dev/null @@ -1,82 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestProfileListNegativeBadRequest(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('b936b936-f891-4389-bbeb-f81b7dc3c688') - def test_profile_list_invalid_params(self): - self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'profiles', {'bogus': 'foo'}) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('04ce3766-acf9-4549-91c8-e6ffdf7bafbd') - def test_profile_list_limit_not_int(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'profiles', {'limit': 'not-int'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("The value for limit must be an integer: 'not-int'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('cfd50d13-5ed8-48d9-b03f-95480ba06fad') - def test_profile_list_global_project_false(self): - ex = self.assertRaises(exceptions.Forbidden, - self.client.list_objs, - 'profiles', {'global_project': 'True'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("You are not authorized to complete this operation.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('ab477cf8-6c37-4762-bd85-d55b46444d8f') - def test_profile_list_global_project_not_bool(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'profiles', {'global_project': 'not-bool'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Invalid value 'not-bool' specified for " - "'global_project'", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('f5bd7807-2b3e-43b2-8ed6-7bdb5e9af46b') - def test_profile_list_invalid_sort(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'profiles', {'sort': 'bad-sort'}) - - message = ex.resp_body['error']['message'] - self.assertEqual("Unsupported sort key 'bad-sort' for 'sort'.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('077f39f0-bb2a-4de8-9568-2ed49e99b720') - def test_profile_list_invalid_marker(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'profiles', {'marker': 'bad-marker'}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The value for marker is not a valid UUID: 'bad-marker'.", - str(message)) diff --git a/senlin/tests/tempest/api/profiles/test_profile_show.py b/senlin/tests/tempest/api/profiles/test_profile_show.py deleted file mode 100644 index 5136db251..000000000 --- a/senlin/tests/tempest/api/profiles/test_profile_show.py +++ /dev/null @@ -1,37 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestProfileShow(base.BaseSenlinAPITest): - - def setUp(self): - super(TestProfileShow, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - - @decorators.idempotent_id('36206711-0676-4e4f-8f5d-7029912ecade') - def test_profile_show(self): - res = self.client.get_obj('profiles', self.profile_id) - - # Verify resp of profile show API - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - profile = res['body'] - for key in ['created_at', 'domain', 'id', 'metadata', 'name', - 'project', 'spec', 'type', 'updated_at', 'user']: - self.assertIn(key, profile) diff --git a/senlin/tests/tempest/api/profiles/test_profile_show_negative.py b/senlin/tests/tempest/api/profiles/test_profile_show_negative.py deleted file mode 100644 index 05127642b..000000000 --- a/senlin/tests/tempest/api/profiles/test_profile_show_negative.py +++ /dev/null @@ -1,54 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestProfileShowNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('887aa1a5-e623-4b49-bdba-e62366b8b636') - def test_profile_show_not_found(self): - ex = self.assertRaises(exceptions.NotFound, - self.client.get_obj, 'profiles', - '887aa1a5-e623-4b49-bdba-e62366b8b636') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The profile '887aa1a5-e623-4b49-bdba-e62366b8b636' " - "could not be found.", str(message)) - - -class TestProfileShowNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestProfileShowNegativeBadRequest, self).setUp() - profile_id1 = utils.create_a_profile(self, name='p-01') - profile_id2 = utils.create_a_profile(self, name='p-01') - self.addCleanup(utils.delete_a_profile, self, profile_id1) - self.addCleanup(utils.delete_a_profile, self, profile_id2) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('f0ea4ff1-81f9-49e1-ba1b-40964677f7da') - def test_profile_show_multiple_choice(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.get_obj, - 'profiles', 'p-01') - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Multiple results found matching the query criteria " - "'p-01'. Please be more specific.", str(message)) diff --git a/senlin/tests/tempest/api/profiles/test_profile_update.py b/senlin/tests/tempest/api/profiles/test_profile_update.py deleted file mode 100644 index 2d1bbaff5..000000000 --- a/senlin/tests/tempest/api/profiles/test_profile_update.py +++ /dev/null @@ -1,44 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestProfileUpdate(base.BaseSenlinAPITest): - - def setUp(self): - super(TestProfileUpdate, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - - @decorators.idempotent_id('d7efdd92-1687-444e-afcc-b7f9c7e37478') - def test_profile_update(self): - params = { - 'profile': { - 'name': 'updated-profile-name', - 'metadata': {'bar': 'foo'} - } - } - res = self.client.update_obj('profiles', self.profile_id, params) - - # Verify resp of profile update API - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - profile = res['body'] - for key in ['created_at', 'domain', 'id', 'metadata', 'name', - 'project', 'spec', 'type', 'updated_at', 'user']: - self.assertIn(key, profile) - self.assertEqual('updated-profile-name', profile['name']) - self.assertEqual({'bar': 'foo'}, profile['metadata']) diff --git a/senlin/tests/tempest/api/profiles/test_profile_update_negative.py b/senlin/tests/tempest/api/profiles/test_profile_update_negative.py deleted file mode 100644 index 244e15307..000000000 --- a/senlin/tests/tempest/api/profiles/test_profile_update_negative.py +++ /dev/null @@ -1,92 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestProfileUpdateNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('5fe90195-aaed-4c1f-a73a-806b3f044bf8') - def test_profile_update_profile_not_found(self): - ex = self.assertRaises(exceptions.NotFound, - self.client.update_obj, 'profiles', - '5fe90195-aaed-4c1f-a73a-806b3f044bf8', - {'profile': {'name': 'new-name'}}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The profile '5fe90195-aaed-4c1f-a73a-806b3f044bf8' " - "could not be found.", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('5fe90195-aaed-4c1f-a73a-806b3f044bf8') - def test_profile_update_profile_no_param(self): - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, 'profiles', - '5fe90195-aaed-4c1f-a73a-806b3f044bf8', - {}) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Malformed request data, missing 'profile' key in " - "request body.", str(message)) - - -class TestProfileUpdateNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestProfileUpdateNegativeBadRequest, self).setUp() - # Create a profile - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - self.profile_id = profile_id - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('31242de5-55ac-4589-87a1-a9940e4beca2') - def test_profile_update_no_property_updated(self): - # No property is updated - params = { - 'profile': {} - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, - 'profiles', self.profile_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual("No property needs an update.", - str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('d2ca7de6-0069-48c9-b3de-ee975a2428dc') - def test_profile_update_spec_not_updatable(self): - # Try to update spec of profile which is not allowed. - params = { - 'profile': { - 'name': 'new-name', - 'spec': {'k1': 'v1'} - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.update_obj, - 'profiles', self.profile_id, params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "Additional properties are not allowed (u'spec' was " - "unexpected)", str(message)) diff --git a/senlin/tests/tempest/api/profiles/test_profile_validate.py b/senlin/tests/tempest/api/profiles/test_profile_validate.py deleted file mode 100644 index bac244770..000000000 --- a/senlin/tests/tempest/api/profiles/test_profile_validate.py +++ /dev/null @@ -1,39 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants - - -class TestProfileValidate(base.BaseSenlinAPITest): - - @decorators.idempotent_id('ff678e2d-60d0-43da-808f-cb70a3926112') - def test_profile_validate(self): - params = { - 'profile': { - 'spec': constants.spec_nova_server, - } - } - res = self.client.validate_obj('profiles', params) - - # Verify resp of validate create API - self.assertEqual(200, res['status']) - self.assertIsNotNone(res['body']) - profile = res['body'] - for key in ['created_at', 'domain', 'id', 'metadata', 'name', - 'project', 'spec', 'type', 'updated_at', 'user']: - self.assertIn(key, profile) - self.assertEqual('validated_profile', profile['name']) - self.assertEqual('os.nova.server-1.0', profile['type']) - self.assertEqual(constants.spec_nova_server, profile['spec']) diff --git a/senlin/tests/tempest/api/profiles/test_profile_validate_negative.py b/senlin/tests/tempest/api/profiles/test_profile_validate_negative.py deleted file mode 100644 index 2723b2eb4..000000000 --- a/senlin/tests/tempest/api/profiles/test_profile_validate_negative.py +++ /dev/null @@ -1,85 +0,0 @@ -# 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. - -import copy -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import constants - - -class TestProfileValidateNegativeBadRequest(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('d128781c-808f-4dee-b8b6-abe4def40eb1') - def test_profile_validate_empty_body(self): - params = {} - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.validate_obj, - 'profiles', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Request body missing 'profile' key.", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('7c66eaa1-a78c-4b60-9b0f-c6fa91f28778') - def test_profile_validate_no_spec(self): - params = { - 'profile': {} - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.validate_obj, - 'profiles', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("'spec' is a required property", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('d661c452-3752-4196-9649-4b44ac9c55a6') - def test_profile_validate_profile_type_incorrect(self): - spec = copy.deepcopy(constants.spec_nova_server) - spec['type'] = 'senlin.profile.bogus' - params = { - 'profile': { - 'spec': spec - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.NotFound, - self.client.validate_obj, - 'profiles', params) - - message = ex.resp_body['error']['message'] - self.assertEqual( - "The profile_type 'senlin.profile.bogus-1.0' could " - "not be found.", str(message)) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('c0fe55cf-608c-4e89-bf85-4561805fc867') - def test_profile_validate_spec_validation_failed(self): - spec = copy.deepcopy(constants.spec_nova_server) - spec['properties']['bogus'] = 'foo' - params = { - 'profile': { - 'spec': spec - } - } - # Verify badrequest exception(400) is raised. - ex = self.assertRaises(exceptions.BadRequest, - self.client.validate_obj, - 'profiles', params) - - message = ex.resp_body['error']['message'] - self.assertEqual("Unrecognizable spec item 'bogus'", str(message)) diff --git a/senlin/tests/tempest/api/receivers/__init__.py b/senlin/tests/tempest/api/receivers/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/api/receivers/test_receiver_create.py b/senlin/tests/tempest/api/receivers/test_receiver_create.py deleted file mode 100644 index 893aa310b..000000000 --- a/senlin/tests/tempest/api/receivers/test_receiver_create.py +++ /dev/null @@ -1,55 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestReceiverCreate(base.BaseSenlinAPITest): - - def setUp(self): - super(TestReceiverCreate, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.idempotent_id('55f06733-af40-4fa8-a1de-3cb2a0c700d7') - def test_receiver_create(self): - params = { - 'receiver': { - 'name': 'test-receiver', - 'cluster_id': self.cluster_id, - 'type': 'webhook', - 'action': 'CLUSTER_SCALE_IN', - 'params': {"count": 5} - } - } - res = self.client.create_obj('receivers', params) - - # Verify resp of receiver create API - self.assertEqual(201, res['status']) - self.assertIsNotNone(res['body']) - recv = res['body'] - self.receiver_id = recv['id'] - self.addCleanup(utils.delete_a_receiver, self, self.receiver_id) - - for key in ['action', 'actor', 'channel', 'cluster_id', 'created_at', - 'domain', 'id', 'name', 'params', 'project', 'type', - 'updated_at', 'user']: - self.assertIn(key, recv) - self.assertEqual('test-receiver', recv['name']) - self.assertEqual(self.cluster_id, recv['cluster_id']) - self.assertEqual('webhook', recv['type']) - self.assertEqual({"count": 5}, recv['params']) diff --git a/senlin/tests/tempest/api/receivers/test_receiver_create_negative.py b/senlin/tests/tempest/api/receivers/test_receiver_create_negative.py deleted file mode 100644 index 806e4f275..000000000 --- a/senlin/tests/tempest/api/receivers/test_receiver_create_negative.py +++ /dev/null @@ -1,102 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestReceiverCreateNegativeBadRequest(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('b55d204c-8ba2-43fd-bde4-d7d9d0e54c29') - def test_receiver_create_receiver_data_not_specified(self): - # receiver key is missing in request data - params = { - 'receive': { - 'name': 'test-receiver', - 'cluster_id': 'CLUSTER_ID', - 'type': 'webhook', - 'action': 'CLUSTER_SCALE_IN', - 'params': {"count": 5} - } - } - # Verify badrequest exception(400) is raised. - self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'receivers', params) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('0e5cadcf-d9b7-4617-a83f-49557765f9bf') - def test_receiver_create_unsupported_receiver_type(self): - # Unsupported receiver type is specified - params = { - 'receiver': { - 'name': 'test-receiver', - 'cluster_id': 'CLUSTER_ID', - 'type': 'bogus', - 'action': 'CLUSTER_SCALE_IN', - 'params': {"count": 5} - } - } - # Verify badrequest exception(400) is raised. - self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'receivers', params) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('e281873f-0dff-4be6-8795-f781efe7cc14') - def test_receiver_create_target_cluster_not_found(self): - # Target cluster cannot be found - params = { - 'receiver': { - 'name': 'test-receiver', - 'cluster_id': 'e281873f-0dff-4be6-8795-f781efe7cc14', - 'type': 'webhook', - 'action': 'CLUSTER_SCALE_IN', - 'params': {"count": 5} - } - } - # Verify badrequest exception(400) is raised. - self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'receivers', params) - - -class TestReceiverCreateNegativeInvalidAction(base.BaseSenlinAPITest): - - def setUp(self): - super(TestReceiverCreateNegativeInvalidAction, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('80e16a56-7d56-4038-b5f4-6d1ccd76c3f2') - def test_receiver_create_invalid_action(self): - # Target action type is illegal - params = { - 'receiver': { - 'name': 'test-receiver', - 'cluster_id': self.cluster_id, - 'type': 'webhook', - 'action': 'ILLEGAL_ACTION', - 'params': {"count": 5} - } - } - # Verify badrequest exception(400) is raised. - self.assertRaises(exceptions.BadRequest, - self.client.create_obj, - 'receivers', params) diff --git a/senlin/tests/tempest/api/receivers/test_receiver_delete.py b/senlin/tests/tempest/api/receivers/test_receiver_delete.py deleted file mode 100644 index a4475eae0..000000000 --- a/senlin/tests/tempest/api/receivers/test_receiver_delete.py +++ /dev/null @@ -1,38 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestReceiverDelete(base.BaseSenlinAPITest): - - def setUp(self): - super(TestReceiverDelete, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, cluster_id) - - self.receiver_id = utils.create_a_receiver(self, cluster_id, - 'CLUSTER_RESIZE') - - @decorators.idempotent_id('c67cf6c3-2339-4f10-9631-fb7e9f47170f') - def test_receiver_delete(self): - # Verify resp of receiver delete API - res = self.client.delete_obj('receivers', self.receiver_id) - self.assertEqual(204, res['status']) - self.assertIsNone(res['body']) - self.assertEqual('0', res['content-length']) diff --git a/senlin/tests/tempest/api/receivers/test_receiver_delete_negative.py b/senlin/tests/tempest/api/receivers/test_receiver_delete_negative.py deleted file mode 100644 index bf5d35327..000000000 --- a/senlin/tests/tempest/api/receivers/test_receiver_delete_negative.py +++ /dev/null @@ -1,55 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestReceiverDeleteNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('799395ff-8bb5-49d6-9e3b-0d2d4428e8c1') - def test_receiver_delete_not_found(self): - # Verify notfound exception(404) is raised. - self.assertRaises(exceptions.NotFound, - self.client.delete_obj, - 'receivers', '799395ff-8bb5-49d6-9e3b-0d2d4428e8c1') - - -class TestReceiverDeleteNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestReceiverDeleteNegativeBadRequest, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, cluster_id) - - self.receiver_id1 = utils.create_a_receiver(self, cluster_id, - 'CLUSTER_RESIZE', - name='r-01') - self.addCleanup(utils.delete_a_receiver, self, self.receiver_id1) - self.receiver_id2 = utils.create_a_receiver(self, cluster_id, - 'CLUSTER_RESIZE', - name='r-01') - self.addCleanup(utils.delete_a_receiver, self, self.receiver_id2) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('f6f2377c-f125-4c35-be5f-42f94ba81a0e') - def test_receiver_delete_multiple_choice(self): - # Verify badrequest exception(400) is raised. - self.assertRaises(exceptions.BadRequest, - self.client.delete_obj, - 'receivers', 'r-01') diff --git a/senlin/tests/tempest/api/receivers/test_receiver_list.py b/senlin/tests/tempest/api/receivers/test_receiver_list.py deleted file mode 100644 index 2746d7bb8..000000000 --- a/senlin/tests/tempest/api/receivers/test_receiver_list.py +++ /dev/null @@ -1,48 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestReceiverList(base.BaseSenlinAPITest): - - def setUp(self): - super(TestReceiverList, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, cluster_id) - - self.receiver_id = utils.create_a_receiver(self, cluster_id, - 'CLUSTER_RESIZE') - self.addCleanup(self.client.delete_obj, 'receivers', self.receiver_id) - - @decorators.idempotent_id('e5cedce0-9240-45ea-90d7-692be5058aac') - def test_receiver_list(self): - res = self.client.list_objs('receivers') - - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - receivers = res['body'] - ids = [] - for receiver in receivers: - for key in ['action', 'actor', 'channel', 'cluster_id', - 'created_at', 'domain', 'id', 'name', 'params', - 'project', 'type', 'updated_at', 'user']: - self.assertIn(key, receiver) - ids.append(receiver['id']) - self.assertIn(self.receiver_id, ids) diff --git a/senlin/tests/tempest/api/receivers/test_receiver_list_negative.py b/senlin/tests/tempest/api/receivers/test_receiver_list_negative.py deleted file mode 100644 index c334612a2..000000000 --- a/senlin/tests/tempest/api/receivers/test_receiver_list_negative.py +++ /dev/null @@ -1,26 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base - - -class TestReceiverListNegativeBadRequest(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('5c2e7114-dab9-41c7-aecb-8e0c272a529d') - def test_receiver_list_invalid_params(self): - self.assertRaises(exceptions.BadRequest, - self.client.list_objs, - 'receivers', {'bogus': 'foo'}) diff --git a/senlin/tests/tempest/api/receivers/test_receiver_show.py b/senlin/tests/tempest/api/receivers/test_receiver_show.py deleted file mode 100644 index 24fbefd8f..000000000 --- a/senlin/tests/tempest/api/receivers/test_receiver_show.py +++ /dev/null @@ -1,44 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestReceiverShow(base.BaseSenlinAPITest): - - def setUp(self): - super(TestReceiverShow, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, cluster_id) - - self.receiver_id = utils.create_a_receiver(self, cluster_id, - 'CLUSTER_RESIZE') - self.addCleanup(self.client.delete_obj, 'receivers', self.receiver_id) - - @decorators.idempotent_id('6a86b2e4-127a-4acc-b0ec-6f951b240e5b') - def test_receiver_show(self): - res = self.client.get_obj('receivers', self.receiver_id) - - self.assertEqual(200, res['status']) - self.assertIsNone(res['location']) - self.assertIsNotNone(res['body']) - receiver = res['body'] - for key in ['action', 'actor', 'channel', 'cluster_id', - 'created_at', 'domain', 'id', 'name', 'params', - 'project', 'type', 'updated_at', 'user']: - self.assertIn(key, receiver) diff --git a/senlin/tests/tempest/api/receivers/test_receiver_show_negative.py b/senlin/tests/tempest/api/receivers/test_receiver_show_negative.py deleted file mode 100644 index 1c7a3aa92..000000000 --- a/senlin/tests/tempest/api/receivers/test_receiver_show_negative.py +++ /dev/null @@ -1,54 +0,0 @@ -# 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. - -from tempest.lib import decorators -from tempest.lib import exceptions - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestReceiverShowNegativeNotFound(base.BaseSenlinAPITest): - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('0cca923f-3e6c-4e23-8d42-2e1c70243c9d') - def test_receiver_show_not_found(self): - self.assertRaises(exceptions.NotFound, - self.client.get_obj, - 'receivers', - '0cca923f-3e6c-4e23-8d42-2e1c70243c9d') - - -class TestReceiverShowNegativeBadRequest(base.BaseSenlinAPITest): - - def setUp(self): - super(TestReceiverShowNegativeBadRequest, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, cluster_id) - - self.receiver_id1 = utils.create_a_receiver(self, cluster_id, - 'CLUSTER_RESIZE', - name='r-01') - self.receiver_id2 = utils.create_a_receiver(self, cluster_id, - 'CLUSTER_RESIZE', - name='r-01') - self.addCleanup(self.client.delete_obj, 'receivers', self.receiver_id1) - self.addCleanup(self.client.delete_obj, 'receivers', self.receiver_id2) - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('5bbfde20-c083-4212-81fb-4eea63271bbb') - def test_receiver_show_multiple_choice(self): - self.assertRaises(exceptions.BadRequest, - self.client.get_obj, - 'receivers', 'r-01') diff --git a/senlin/tests/tempest/api/receivers/test_webhook_trigger.py b/senlin/tests/tempest/api/receivers/test_webhook_trigger.py deleted file mode 100644 index 501b4966c..000000000 --- a/senlin/tests/tempest/api/receivers/test_webhook_trigger.py +++ /dev/null @@ -1,48 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.api import base -from senlin.tests.tempest.common import utils - - -class TestWebhookTrigger(base.BaseSenlinAPITest): - - def setUp(self): - super(TestWebhookTrigger, self).setUp() - profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, profile_id) - - cluster_id = utils.create_a_cluster(self, profile_id) - self.addCleanup(utils.delete_a_cluster, self, cluster_id) - - params = {'max_size': 2} - self.receiver_id = utils.create_a_receiver(self, cluster_id, - 'CLUSTER_RESIZE', - params=params) - self.addCleanup(self.client.delete_obj, 'receivers', self.receiver_id) - - receiver = self.client.get_obj('receivers', self.receiver_id) - self.webhook_url = receiver['body']['channel']['alarm_url'] - - @decorators.idempotent_id('afd671af-330a-46d6-bdb5-9c50966ab8b5') - def test_webhook_trigger(self): - res = self.client.trigger_webhook(self.webhook_url) - - # Verify resp of webhook API - self.assertEqual(202, res['status']) - self.assertIn('actions', res['location']) - - # Trigger webhook action - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') diff --git a/senlin/tests/tempest/base.py b/senlin/tests/tempest/base.py deleted file mode 100644 index bd2361223..000000000 --- a/senlin/tests/tempest/base.py +++ /dev/null @@ -1,44 +0,0 @@ -# -# 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. - -from tempest import config -from tempest import test - -CONF = config.CONF - - -class BaseSenlinTest(test.BaseTestCase): - - credentials = ['primary'] - - default_params = config.service_client_config() - - # NOTE: Tempest uses timeout values of compute API if project specific - # timeout values don't exist. - default_params_with_timeout_values = { - 'build_interval': CONF.compute.build_interval, - 'build_timeout': CONF.compute.build_timeout - } - default_params_with_timeout_values.update(default_params) - - @classmethod - def skip_checks(cls): - super(BaseSenlinTest, cls).skip_checks() - if not CONF.service_available.senlin: - skip_msg = 'Senlin is disabled' - raise cls.skipException(skip_msg) - - @classmethod - def setup_clients(cls): - super(BaseSenlinTest, cls).setup_clients() diff --git a/senlin/tests/tempest/common/__init__.py b/senlin/tests/tempest/common/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/common/clustering_client.py b/senlin/tests/tempest/common/clustering_client.py deleted file mode 100644 index d57cd00c8..000000000 --- a/senlin/tests/tempest/common/clustering_client.py +++ /dev/null @@ -1,185 +0,0 @@ -# -# 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. - -from six.moves.urllib import parse as urllib -import time - -from oslo_serialization import jsonutils -from oslo_utils import timeutils -from tempest import config -from tempest.lib.common import rest_client -from tempest.lib import exceptions - -CONF = config.CONF - - -class ClusteringAPIClient(rest_client.RestClient): - version = 'v1' - api_microversion = 'latest' - - def get_headers(self, accept_type=None, send_type=None): - headers = super(ClusteringAPIClient, self).get_headers( - accept_type=accept_type, send_type=send_type) - headers['openstack-api-version'] = ('clustering %s' % - self.api_microversion) - return headers - - def get_resp(self, resp, body): - # Parse status code and location - res = { - 'status': int(resp.pop('status')), - 'location': resp.pop('location', None) - } - # Parse other keys included in resp - res.update(resp) - - # Parse body - if body and str(body) != 'null': - res['body'] = self._parse_resp(body) - else: - res['body'] = None - - return res - - def get_obj(self, obj_type, obj_id, params=None): - uri = '{0}/{1}/{2}'.format(self.version, obj_type, obj_id) - if params: - uri += '?{0}'.format(urllib.urlencode(params)) - resp, body = self.get(uri) - - return self.get_resp(resp, body) - - def create_obj(self, obj_type, attrs): - uri = '{0}/{1}'.format(self.version, obj_type) - resp, body = self.post(uri, body=jsonutils.dumps(attrs)) - - return self.get_resp(resp, body) - - def list_objs(self, obj_type, params=None): - uri = '{0}/{1}'.format(self.version, obj_type) - if params: - uri += '?{0}'.format(urllib.urlencode(params)) - resp, body = self.get(uri) - - return self.get_resp(resp, body) - - def update_obj(self, obj_type, obj_id, attrs): - uri = '{0}/{1}/{2}'.format(self.version, obj_type, obj_id) - resp, body = self.patch(uri, body=jsonutils.dumps(attrs)) - - return self.get_resp(resp, body) - - def delete_obj(self, obj_type, obj_id): - uri = '{0}/{1}/{2}'.format(self.version, obj_type, obj_id) - resp, body = self.delete(uri) - - return self.get_resp(resp, body) - - def validate_obj(self, obj_type, attrs): - uri = '{0}/{1}/validate'.format(self.version, obj_type) - headers = {'openstack-api-version': 'clustering 1.2'} - resp, body = self.post(uri, body=jsonutils.dumps(attrs), - headers=headers) - - return self.get_resp(resp, body) - - def trigger_webhook(self, webhook_url, params=None): - if params is not None: - params = jsonutils.dumps(params) - resp, body = self.raw_request(webhook_url, 'POST', body=params) - return self.get_resp(resp, body) - - def trigger_action(self, obj_type, obj_id, params=None): - uri = '{0}/{1}/{2}/actions'.format(self.version, obj_type, obj_id) - if params is not None: - params = jsonutils.dumps(params) - resp, body = self.post(uri, body=params) - - return self.get_resp(resp, body) - - def trigger_operation(self, obj_type, obj_id, params): - uri = '{0}/{1}/{2}/ops'.format(self.version, obj_type, obj_id) - data = jsonutils.dumps(params) - resp, body = self.post(uri, body=data) - return self.get_resp(resp, body) - - def cluster_replace_nodes(self, obj_type, obj_id, params=None): - uri = '{0}/{1}/{2}/actions'.format(self.version, obj_type, obj_id) - if params is not None: - params = jsonutils.dumps(params) - headers = self.get_headers() - resp, body = self.post(uri, body=params, headers=headers) - - return self.get_resp(resp, body) - - def list_cluster_policies(self, cluster_id, params=None): - uri = '{0}/clusters/{1}/policies'.format(self.version, cluster_id) - if params: - uri += '?{0}'.format(urllib.urlencode(params)) - - resp, body = self.get(uri) - - return self.get_resp(resp, body) - - def get_cluster_policy(self, cluster_id, policy_id): - uri = '{0}/clusters/{1}/policies/{2}'.format(self.version, cluster_id, - policy_id) - resp, body = self.get(uri) - - return self.get_resp(resp, body) - - def cluster_collect(self, cluster, path): - uri = '{0}/clusters/{1}/attrs/{2}'.format(self.version, cluster, path) - resp, body = self.get(uri) - - return self.get_resp(resp, body) - - def wait_for_status(self, obj_type, obj_id, expected_status, timeout=None): - if timeout is None: - timeout = CONF.clustering.wait_timeout - - with timeutils.StopWatch(timeout) as timeout_watch: - while timeout > 0: - res = self.get_obj(obj_type, obj_id) - if res['body']['status'] == expected_status: - return res - time.sleep(5) - timeout = timeout_watch.leftover(True) - - raise Exception('Timeout waiting for status.') - - def wait_for_delete(self, obj_type, obj_id, timeout=None): - if timeout is None: - timeout = CONF.clustering.wait_timeout - - with timeutils.StopWatch(timeout) as timeout_watch: - while timeout > 0: - try: - self.get_obj(obj_type, obj_id) - except exceptions.NotFound: - return - time.sleep(5) - timeout = timeout_watch.leftover(True) - - raise Exception('Timeout waiting for deletion.') - - -class ClusteringFunctionalClient(ClusteringAPIClient): - """This is the tempest client for Senlin functional test""" - pass - - -class ClusteringIntegrationClient(ClusteringAPIClient): - """This is the tempest client for Senlin integration test""" - pass diff --git a/senlin/tests/tempest/common/compute_client.py b/senlin/tests/tempest/common/compute_client.py deleted file mode 100644 index e5ac46e1d..000000000 --- a/senlin/tests/tempest/common/compute_client.py +++ /dev/null @@ -1,50 +0,0 @@ -# -# 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. - -from oslo_serialization import jsonutils -from tempest import config -from tempest.lib.common import rest_client - -CONF = config.CONF - - -class V21ComputeClient(rest_client.RestClient): - def __init__(self, auth_provider, service, region, **kwargs): - super(V21ComputeClient, self).__init__( - auth_provider, service, region, **kwargs) - - def get_resp(self, resp, body): - # Parse status code and location - res = { - 'status': int(resp.pop('status')), - 'location': resp.pop('location', None) - } - # Parse other keys included in resp - res.update(resp) - - # Parse body - res['body'] = self._parse_resp(body) - return res - - def create_obj(self, obj_type, attrs): - uri = '/{0}'.format(obj_type) - resp, body = self.post(uri, body=jsonutils.dumps(attrs)) - - return self.get_resp(resp, body) - - def delete_obj(self, obj_type, obj_id): - uri = '/{0}/{1}'.format(obj_type, obj_id) - resp, body = self.delete(uri) - - return self.get_resp(resp, body) diff --git a/senlin/tests/tempest/common/constants.py b/senlin/tests/tempest/common/constants.py deleted file mode 100644 index 03a32dfe3..000000000 --- a/senlin/tests/tempest/common/constants.py +++ /dev/null @@ -1,117 +0,0 @@ -# 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. - - -spec_nova_server = { - "type": "os.nova.server", - "version": "1.0", - "properties": { - "flavor": "1", - "name": "new-server-test", - "image": "cirros-0.3.5-x86_64-disk", - "networks": [ - {"network": "private"} - ], - "key_name": "oskey" - } -} - - -spec_heat_stack = { - "type": "os.heat.stack", - "version": "1.0", - "properties": { - "template": { - "heat_template_version": "2014-10-16", - "parameters": { - "str_length": { - "type": "number", - "default": 64 - } - }, - "resources": { - "random": { - "type": "OS::Heat::RandomString", - "properties": { - "length": {"get_param": "str_length"} - } - } - }, - "outputs": { - "result": { - "value": {"get_attr": ["random", "value"]} - } - } - } - } -} - - -spec_scaling_policy = { - "type": "senlin.policy.scaling", - "version": "1.0", - "properties": { - "event": "CLUSTER_SCALE_IN", - "adjustment": { - "type": "CHANGE_IN_CAPACITY", - "number": 1, - "min_step": 1, - "best_effort": True - } - } -} - - -spec_lb_policy = { - "type": "senlin.policy.loadbalance", - "version": "1.1", - "properties": { - "pool": { - "protocol": "HTTP", - "protocol_port": 80, - "subnet": "private-subnet", - "lb_method": "ROUND_ROBIN", - "session_persistence": { - "type": "SOURCE_IP", - "cookie_name": "test-cookie" - } - }, - "vip": { - "subnet": "private-subnet", - "connection_limit": 100, - "protocol": "HTTP", - "protocol_port": 80 - }, - "health_monitor": { - "type": "HTTP", - "delay": "1", - "timeout": 1, - "max_retries": 5, - "admin_state_up": True, - "http_method": "GET", - "url_path": "/index.html", - "expected_codes": "200,201,202" - }, - "lb_status_timeout": 300 - } -} - - -spec_batch_policy = { - "type": "senlin.policy.batch", - "version": "1.0", - "properties": { - "min_in_service": 1, - "max_batch_size": 1, - "pause_time": 3 - } -} diff --git a/senlin/tests/tempest/common/messaging_client.py b/senlin/tests/tempest/common/messaging_client.py deleted file mode 100644 index 344915fea..000000000 --- a/senlin/tests/tempest/common/messaging_client.py +++ /dev/null @@ -1,52 +0,0 @@ -# -# 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. - -from oslo_serialization import jsonutils -from oslo_utils import uuidutils -from tempest import config -from tempest.lib.common import rest_client - -CONF = config.CONF - - -class V2MessagingClient(rest_client.RestClient): - def __init__(self, auth_provider, service, region, **kwargs): - super(V2MessagingClient, self).__init__( - auth_provider, service, region, **kwargs) - - self.uri_prefix = 'v2' - - client_id = uuidutils.generate_uuid() - self.headers = {'Client-ID': client_id} - - def get_resp(self, resp, body): - # Parse status code and location - res = { - 'status': int(resp.pop('status')), - 'location': resp.pop('location', None) - } - # Parse other keys included in resp - res.update(resp) - - # Parse body - res['body'] = self._parse_resp(body) - return res - - def post_messages(self, queue_name, messages): - uri = '{0}/queues/{1}/messages'.format(self.uri_prefix, queue_name) - resp, body = self.post(uri, body=jsonutils.dumps(messages), - extra_headers=True, - headers=self.headers) - - return self.get_resp(resp, body) diff --git a/senlin/tests/tempest/common/network_client.py b/senlin/tests/tempest/common/network_client.py deleted file mode 100644 index 071b8902e..000000000 --- a/senlin/tests/tempest/common/network_client.py +++ /dev/null @@ -1,52 +0,0 @@ -# -# 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. - -from oslo_serialization import jsonutils -from tempest import config -from tempest.lib.common import rest_client - -CONF = config.CONF - - -class NetworkClient(rest_client.RestClient): - def __init__(self, auth_provider, service, region, **kwargs): - super(NetworkClient, self).__init__( - auth_provider, service, region, **kwargs) - - self.uri_prefix = 'v2.0' - - def get_resp(self, resp, body): - # Parse status code and location - res = { - 'status': int(resp.pop('status')), - 'location': resp.pop('location', None) - } - # Parse other keys included in resp - res.update(resp) - - # Parse body - res['body'] = self._parse_resp(body) - return res - - def create_obj(self, obj_type, attrs): - uri = '{0}/{1}'.format(self.uri_prefix, obj_type) - resp, body = self.post(uri, body=jsonutils.dumps(attrs)) - - return self.get_resp(resp, body) - - def delete_obj(self, obj_type, obj_id): - uri = '{0}/{1}/{2}'.format(self.uri_prefix, obj_type, obj_id) - resp, body = self.delete(uri) - - return self.get_resp(resp, body) diff --git a/senlin/tests/tempest/common/utils.py b/senlin/tests/tempest/common/utils.py deleted file mode 100644 index 98a6e49fe..000000000 --- a/senlin/tests/tempest/common/utils.py +++ /dev/null @@ -1,523 +0,0 @@ -# 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. - -import functools - -from tempest.lib.common.utils import data_utils -from tempest.lib import exceptions - -from senlin.tests.tempest.common import constants - - -def api_microversion(api_microversion): - """Decorator used to specify api_microversion for test.""" - def decorator(func): - @functools.wraps(func) - def wrapped(self): - old = self.client.api_microversion - self.client.api_microversion = api_microversion - func(self) - self.client.api_microversion = old - return wrapped - return decorator - - -def prepare_and_cleanup_for_nova_server(base): - keypair_name = create_a_keypair(base, is_admin_manager=False) - base.spec = constants.spec_nova_server - base.spec['properties']['key_name'] = keypair_name - base.addCleanup(delete_a_keypair, base, keypair_name, - is_admin_manager=False) - - n_name = base.spec['properties']['networks'][0]['network'] - network_id = create_a_network(base, name=n_name) - base.addCleanup(delete_a_network, base, network_id) - - subnet_id = create_a_subnet(base, network_id, "192.168.199.0/24") - base.addCleanup(delete_a_subnet, base, subnet_id) - - -def create_a_profile(base, spec=None, name=None, metadata=None): - """Utility function that generates a Senlin profile.""" - - if spec is None: - spec = constants.spec_nova_server - - if name is None: - name = data_utils.rand_name("tempest-created-profile") - - params = { - 'profile': { - 'name': name, - 'spec': spec, - 'metadata': metadata, - } - } - res = base.client.create_obj('profiles', params) - return res['body']['id'] - - -def delete_a_profile(base, profile_id, ignore_missing=False): - """Utility function that deletes a Senlin profile.""" - res = base.client.delete_obj('profiles', profile_id) - if res['status'] == 404: - if ignore_missing: - return - raise exceptions.NotFound() - - -def create_a_cluster(base, profile_id, desired_capacity=0, min_size=0, - max_size=-1, timeout=None, metadata=None, name=None, - wait_timeout=None): - """Utility function that generates a Senlin cluster. - - Create a cluster and return it after it is ACTIVE. The function is used for - deduplicate code in API tests where an 'existing' cluster is needed. - """ - if name is None: - name = data_utils.rand_name("tempest-created-cluster") - params = { - 'cluster': { - 'profile_id': profile_id, - 'desired_capacity': desired_capacity, - 'min_size': min_size, - 'max_size': max_size, - 'timeout': timeout, - 'metadata': metadata, - 'name': name - } - } - res = base.client.create_obj('clusters', params) - cluster_id = res['body']['id'] - action_id = res['location'].split('/actions/')[1] - base.client.wait_for_status('actions', action_id, 'SUCCEEDED', - wait_timeout) - - return cluster_id - - -def update_a_cluster(base, cluster_id, profile_id=None, name=None, - expected_status='SUCCEEDED', metadata=None, - timeout=None, wait_timeout=None): - """Utility function that updates a Senlin cluster. - - Update a cluster and return it after it is ACTIVE. - """ - params = { - 'cluster': { - 'profile_id': profile_id, - 'metadata': metadata, - 'name': name, - 'timeout': timeout - } - } - res = base.client.update_obj('clusters', cluster_id, params) - action_id = res['location'].split('/actions/')[1] - base.client.wait_for_status('actions', action_id, expected_status, - wait_timeout) - return res['body'] - - -def get_a_cluster(base, cluster_id): - """Utility function that gets a Senlin cluster.""" - res = base.client.get_obj('clusters', cluster_id) - return res['body'] - - -def list_clusters(base): - """Utility function that lists Senlin clusters.""" - res = base.client.list_objs('clusters') - return res['body'] - - -def delete_a_cluster(base, cluster_id, wait_timeout=None): - """Utility function that deletes a Senlin cluster.""" - res = base.client.delete_obj('clusters', cluster_id) - action_id = res['location'].split('/actions/')[1] - base.client.wait_for_status('actions', action_id, 'SUCCEEDED', - wait_timeout) - return - - -def create_a_node(base, profile_id, cluster_id=None, metadata=None, - role=None, name=None, wait_timeout=None): - """Utility function that creates a node. - - Create a node and return it after it is ACTIVE. This function is for - minimizing the code duplication that could happen in API tests where - an 'existing' Senlin node is needed. - """ - if name is None: - name = data_utils.rand_name("tempest-created-node") - - params = { - 'node': { - 'profile_id': profile_id, - 'cluster_id': cluster_id, - 'metadata': metadata, - 'role': role, - 'name': name - } - } - res = base.client.create_obj('nodes', params) - node_id = res['body']['id'] - action_id = res['location'].split('/actions/')[1] - base.client.wait_for_status('actions', action_id, 'SUCCEEDED', - wait_timeout) - res = base.client.get_obj('nodes', node_id) - return res['body']['id'] - - -def get_a_node(base, node_id, show_details=False): - """Utility function that gets a Senlin node.""" - params = None - if show_details: - params = {'show_details': True} - res = base.client.get_obj('nodes', node_id, params) - return res['body'] - - -def list_nodes(base): - """Utility function that lists Senlin nodes.""" - res = base.client.list_objs('nodes') - return res['body'] - - -def update_a_node(base, node_id, profile_id=None, name=None, - metadata=None, role=None, wait_timeout=None): - """Utility function that updates a Senlin node. - - Update a node and return it after it is ACTIVE. - """ - params = { - 'node': { - 'profile_id': profile_id, - 'metadata': metadata, - 'name': name, - 'role': role - } - } - res = base.client.update_obj('nodes', node_id, params) - action_id = res['location'].split('/actions/')[1] - base.client.wait_for_status('actions', action_id, 'SUCCEEDED', - wait_timeout) - - return res['body']['status_reason'] - - -def delete_a_node(base, node_id, wait_timeout=None): - """Utility function that deletes a Senlin node.""" - res = base.client.delete_obj('nodes', node_id) - action_id = res['location'].split('/actions/')[1] - base.client.wait_for_status('actions', action_id, 'SUCCEEDED', - wait_timeout) - return - - -def create_a_policy(base, spec=None, name=None): - """Utility function that generates a Senlin policy.""" - - params = { - 'policy': { - 'name': name or data_utils.rand_name("tempest-created-policy"), - 'spec': spec or constants.spec_scaling_policy - } - } - res = base.client.create_obj('policies', params) - return res['body']['id'] - - -def get_a_policy(base, policy_id): - """Utility function that gets a Senlin policy.""" - res = base.client.get_obj('policies', policy_id) - return res['body'] - - -def delete_a_policy(base, policy_id, ignore_missing=False): - """Utility function that deletes a policy.""" - res = base.client.delete_obj('policies', policy_id) - if res['status'] == 404: - if ignore_missing: - return - raise exceptions.NotFound() - return - - -def cluster_attach_policy(base, cluster_id, policy_id, - expected_status='SUCCEEDED', wait_timeout=None): - """Utility function that attach a policy to cluster.""" - - params = { - 'policy_attach': { - 'enabled': True, - 'policy_id': policy_id - } - } - res = base.client.trigger_action('clusters', cluster_id, params=params) - action_id = res['location'].split('/actions/')[1] - res = base.client.wait_for_status('actions', action_id, expected_status, - wait_timeout) - - return res['body']['status_reason'] - - -def cluster_detach_policy(base, cluster_id, policy_id, - expected_status='SUCCEEDED', wait_timeout=None): - """Utility function that detach a policy from cluster.""" - - params = { - 'policy_detach': { - 'policy_id': policy_id - } - } - res = base.client.trigger_action('clusters', cluster_id, params=params) - action_id = res['location'].split('/actions/')[1] - res = base.client.wait_for_status('actions', action_id, expected_status, - wait_timeout) - return res['body']['status_reason'] - - -def cluster_replace_nodes(base, cluster_id, nodes, - expected_status='SUCCEEDED', wait_timeout=None): - """Utility function that replace nodes of cluster.""" - - params = { - 'replace_nodes': { - 'nodes': nodes - } - } - res = base.client.cluster_replace_nodes('clusters', cluster_id, - params=params) - action_id = res['location'].split('/actions/')[1] - res = base.client.wait_for_status('actions', action_id, expected_status, - wait_timeout) - return res['body']['status_reason'] - - -def cluster_add_nodes(base, cluster_id, nodes, expected_status='SUCCEEDED', - wait_timeout=None): - """Utility function that add nodes to cluster.""" - - params = { - 'add_nodes': { - 'nodes': nodes - } - } - res = base.client.trigger_action('clusters', cluster_id, params=params) - action_id = res['location'].split('/actions/')[1] - res = base.client.wait_for_status('actions', action_id, expected_status, - wait_timeout) - return res['body']['status_reason'] - - -def cluster_del_nodes(base, cluster_id, nodes, expected_status='SUCCEEDED', - wait_timeout=None): - """Utility function that delete nodes from cluster.""" - - params = { - 'del_nodes': { - 'nodes': nodes - } - } - res = base.client.trigger_action('clusters', cluster_id, params=params) - action_id = res['location'].split('/actions/')[1] - res = base.client.wait_for_status('actions', action_id, expected_status, - wait_timeout) - return res['body']['status_reason'] - - -def cluster_scale_out(base, cluster_id, count=None, - expected_status='SUCCEEDED', wait_timeout=None): - """Utility function that scale out cluster.""" - - params = { - 'scale_out': { - 'count': count - } - } - res = base.client.trigger_action('clusters', cluster_id, params=params) - action_id = res['location'].split('/actions/')[1] - res = base.client.wait_for_status('actions', action_id, expected_status, - wait_timeout) - return res['body']['status_reason'] - - -def cluster_scale_in(base, cluster_id, count=None, - expected_status='SUCCEEDED', wait_timeout=None): - """Utility function that scale in cluster.""" - - params = { - 'scale_in': { - 'count': count - } - } - res = base.client.trigger_action('clusters', cluster_id, params=params) - action_id = res['location'].split('/actions/')[1] - res = base.client.wait_for_status('actions', action_id, expected_status, - wait_timeout) - return res['body']['status_reason'] - - -def cluster_resize(base, cluster_id, adj_type=None, number=None, min_size=None, - max_size=None, min_step=None, strict=True, - expected_status='SUCCEEDED', wait_timeout=None): - """Utility function that resize cluster.""" - - params = { - 'resize': { - 'adjustment_type': adj_type, - 'number': number, - 'min_size': min_size, - 'max_size': max_size, - 'min_step': min_step, - 'strict': strict - } - } - res = base.client.trigger_action('clusters', cluster_id, params=params) - action_id = res['location'].split('/actions/')[1] - res = base.client.wait_for_status('actions', action_id, expected_status, - wait_timeout) - return res['body']['status_reason'] - - -def create_a_receiver(base, cluster_id, action, r_type=None, name=None, - params=None): - """Utility function that generates a Senlin receiver.""" - - if name is None: - name = data_utils.rand_name("tempest-created-receiver") - - body = { - 'receiver': { - 'name': name, - 'cluster_id': cluster_id, - 'type': r_type or 'webhook', - 'action': action, - 'params': params or {} - } - } - res = base.client.create_obj('receivers', body) - return res['body']['id'] - - -def get_a_receiver(base, receiver_id): - """Utility function that gets a Senlin receiver.""" - res = base.client.get_obj('receivers', receiver_id) - return res['body'] - - -def delete_a_receiver(base, receiver_id, ignore_missing=False): - """Utility function that deletes a Senlin receiver.""" - res = base.client.delete_obj('receivers', receiver_id) - if res['status'] == 404: - if ignore_missing: - return - raise exceptions.NotFound() - - -def create_a_keypair(base, name=None, is_admin_manager=True): - """Utility function that creates a Nova keypair.""" - - if name is None: - name = data_utils.rand_name("tempest-created-keypair") - - if is_admin_manager is True: - body = base.os_admin.keypairs_client.create_keypair(name=name) - body = body['keypair'] - else: - params = { - "keypair": { - "name": name, - } - } - body = base.compute_client.create_obj('os-keypairs', params)['body'] - - return body['name'] - - -def delete_a_keypair(base, name, is_admin_manager=True, ignore_missing=False): - """Utility function that deletes a Nova keypair.""" - - if is_admin_manager is True: - base.os_admin.keypairs_client.delete_keypair(name) - return - - res = base.compute_client.delete_obj('os-keypairs', name) - if res['status'] == 404: - if ignore_missing is True: - return - raise exceptions.NotFound() - - -def create_a_network(base, name=None): - """Utility function that creates a Neutron network""" - - if name is None: - name = data_utils.rand_name("tempest-created-network") - - params = { - "network": { - "name": name, - } - } - body = base.network_client.create_obj('networks', params) - - return body['body']['id'] - - -def delete_a_network(base, network_id, ignore_missing=False): - """Utility function that deletes a Neutron network.""" - - res = base.network_client.delete_obj('networks', network_id) - if res['status'] == 404: - if ignore_missing is True: - return - raise exceptions.NotFound() - - -def create_a_subnet(base, network_id, cidr, ip_version=4, name=None): - """Utility function that creates a Neutron subnet""" - - if name is None: - name = data_utils.rand_name("tempest-created-subnet") - - params = { - "subnet": { - "name": name, - "network_id": network_id, - "cidr": cidr, - "ip_version": ip_version, - } - } - body = base.network_client.create_obj('subnets', params) - - return body['body']['id'] - - -def delete_a_subnet(base, subnet_id, ignore_missing=False): - """Utility function that deletes a Neutron subnet.""" - - res = base.network_client.delete_obj('subnets', subnet_id) - if res['status'] == 404: - if ignore_missing is True: - return - raise exceptions.NotFound() - - -def post_messages(base, queue_name, messages): - """Utility function that posts message(s) to Zaqar queue.""" - res = base.messaging_client.post_messages(queue_name, - {'messages': messages}) - if res['status'] != 201: - msg = 'Failed in posting messages to Zaqar queue %s' % queue_name - raise Exception(msg) diff --git a/senlin/tests/tempest/config.py b/senlin/tests/tempest/config.py deleted file mode 100644 index ab7a3c40d..000000000 --- a/senlin/tests/tempest/config.py +++ /dev/null @@ -1,32 +0,0 @@ -# -# 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. - -from oslo_config import cfg -from senlin.common.i18n import _ - -service_option = cfg.BoolOpt("senlin", - default=True, - help="Whether or not senlin is expected to be" - "available") - -clustering_group = cfg.OptGroup(name="clustering", - title="Clustering Service Options") - -ClusteringGroup = [ - cfg.StrOpt("catalog_type", - default="clustering", - help=_("Catalog type of the clustering service.")), - cfg.IntOpt("wait_timeout", - default=60, - help=_("Waiting time for a specific status, in seconds.")) -] diff --git a/senlin/tests/tempest/functional/__init__.py b/senlin/tests/tempest/functional/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/functional/base.py b/senlin/tests/tempest/functional/base.py deleted file mode 100644 index bda4e6839..000000000 --- a/senlin/tests/tempest/functional/base.py +++ /dev/null @@ -1,56 +0,0 @@ -# -# 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. - -from tempest import config - -from senlin.tests.tempest import base -from senlin.tests.tempest.common import clustering_client -from senlin.tests.tempest.common import compute_client -from senlin.tests.tempest.common import network_client - -CONF = config.CONF - - -class BaseSenlinFunctionalTest(base.BaseSenlinTest): - - network_resources = { - 'network': False, - 'router': False, - 'subnet': False, - 'dhcp': False, - } - - @classmethod - def setup_clients(cls): - super(BaseSenlinFunctionalTest, cls).setup_clients() - cls.client = clustering_client.ClusteringFunctionalClient( - cls.os_primary.auth_provider, - CONF.clustering.catalog_type, - CONF.identity.region, - **cls.default_params_with_timeout_values - ) - - cls.compute_client = compute_client.V21ComputeClient( - cls.os_primary.auth_provider, - CONF.compute.catalog_type, - CONF.identity.region, - **cls.default_params_with_timeout_values - ) - - cls.network_client = network_client.NetworkClient( - cls.os_primary.auth_provider, - CONF.network.catalog_type, - CONF.identity.region, - **cls.default_params_with_timeout_values - ) diff --git a/senlin/tests/tempest/functional/test_batch_policy.py b/senlin/tests/tempest/functional/test_batch_policy.py deleted file mode 100644 index 9c9f5093c..000000000 --- a/senlin/tests/tempest/functional/test_batch_policy.py +++ /dev/null @@ -1,55 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.common import constants -from senlin.tests.tempest.common import utils -from senlin.tests.tempest.functional import base - - -class TestBatchPolicy(base.BaseSenlinFunctionalTest): - - def setUp(self): - super(TestBatchPolicy, self).setUp() - self.new_profile2 = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.new_profile2) - self.new_profile = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.new_profile) - self.old_profile = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.old_profile) - self.cluster_id = utils.create_a_cluster(self, self.old_profile, - min_size=0, max_size=2, - desired_capacity=2) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('b35e63ed-f1d5-4ec6-afb0-2378d260afcb') - def test_batch_policy(self): - # Create a batch policy targets on CLUSTER_UPDATE action - spec = constants.spec_batch_policy - policy_id = utils.create_a_policy(self, spec) - self.addCleanup(utils.delete_a_policy, self, policy_id) - - # Attach batch policy to cluster - utils.cluster_attach_policy(self, self.cluster_id, policy_id) - self.addCleanup(utils.cluster_detach_policy, self, - self.cluster_id, policy_id) - - utils.update_a_cluster(self, self.cluster_id, - profile_id=self.new_profile) - - # Verify cluster update result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(2, len(cluster['nodes'])) - self.assertEqual(self.new_profile, cluster['profile_id']) diff --git a/senlin/tests/tempest/functional/test_cluster_basic.py b/senlin/tests/tempest/functional/test_cluster_basic.py deleted file mode 100644 index 2c38a1fdf..000000000 --- a/senlin/tests/tempest/functional/test_cluster_basic.py +++ /dev/null @@ -1,107 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.common import utils -from senlin.tests.tempest.functional import base - - -class TestClusterCreateListDelete(base.BaseSenlinFunctionalTest): - - def setUp(self): - super(TestClusterCreateListDelete, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('d2001e89-e7e7-4ceb-8497-2255becc5d7f') - def test_cluster_create_list_delete(self): - # Create a cluster - desired_capacity = 2 - min_size = 1 - max_size = 3 - metadata = {'k1': 'v1'} - timeout = 120 - cluster_id1 = utils.create_a_cluster( - self, self.profile_id, desired_capacity, min_size, max_size, - timeout, metadata) - - # Verify creation result - cluster1 = utils.get_a_cluster(self, cluster_id1) - self.assertIsNotNone(cluster1) - self.assertEqual(desired_capacity, cluster1['desired_capacity']) - self.assertEqual(desired_capacity, len(cluster1['nodes'])) - self.assertEqual(min_size, cluster1['min_size']) - self.assertEqual(max_size, cluster1['max_size']) - self.assertEqual(metadata, cluster1['metadata']) - self.assertEqual(timeout, cluster1['timeout']) - - # Create another cluster - cluster_id2 = utils.create_a_cluster(self, self.profile_id) - - # List clusters - clusters = utils.list_clusters(self) - self.assertIsNotNone(clusters) - cluster_ids = [c['id'] for c in clusters] - self.assertIn(cluster_id1, cluster_ids) - self.assertIn(cluster_id2, cluster_ids) - - # Delete cluster - utils.delete_a_cluster(self, cluster_id1) - utils.delete_a_cluster(self, cluster_id2) - - -class TestClusterUpdate(base.BaseSenlinFunctionalTest): - - def setUp(self): - super(TestClusterUpdate, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.profile_id_new = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id_new) - self.cluster_id = utils.create_a_cluster(self, self.profile_id, - desired_capacity=3) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('308ee213-b379-4f2d-b193-0ea44b0de622') - def test_cluster_update_basic_properties(self): - name = 'new-name' - metadata = {'k1': 'v1'} - timeout = 360 - - # Update cluster - utils.update_a_cluster(self, self.cluster_id, name=name, - metadata=metadata, timeout=timeout) - - # Verify update result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual(name, cluster['name']) - self.assertEqual(metadata, cluster['metadata']) - self.assertEqual(timeout, cluster['timeout']) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('bf655d2b-11d4-47b7-b10c-8dfb8a4538a5') - def test_cluster_update_profile(self): - - # Update cluster - utils.update_a_cluster(self, self.cluster_id, - profile_id=self.profile_id_new) - - # Verify update result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual(self.profile_id_new, cluster['profile_id']) - nodes = cluster['nodes'] - for n in nodes: - node = utils.get_a_node(self, n) - self.assertEqual(self.profile_id_new, node['profile_id']) diff --git a/senlin/tests/tempest/functional/test_cluster_membership.py b/senlin/tests/tempest/functional/test_cluster_membership.py deleted file mode 100644 index f6cbf466e..000000000 --- a/senlin/tests/tempest/functional/test_cluster_membership.py +++ /dev/null @@ -1,164 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.common import utils -from senlin.tests.tempest.functional import base - - -class TestClusterMembership(base.BaseSenlinFunctionalTest): - - def setUp(self): - super(TestClusterMembership, self).setUp() - # Create a profile - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - # Create a cluster - self.cluster_id = utils.create_a_cluster(self, self.profile_id, - desired_capacity=0, - min_size=0, max_size=3) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - # Create three orphan nodes - self.node_id1 = utils.create_a_node(self, self.profile_id) - self.node_id2 = utils.create_a_node(self, self.profile_id) - self.node_id3 = utils.create_a_node(self, self.profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id1) - self.addCleanup(utils.delete_a_node, self, self.node_id2) - self.addCleanup(utils.delete_a_node, self, self.node_id3) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('137a36d9-b4ee-485d-8bff-51ebb6113e9b') - def test_cluster_node_add_del(self): - # Add one node to cluster - utils.cluster_add_nodes(self, self.cluster_id, [self.node_id1]) - - # Verify result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual(1, len(cluster['nodes'])) - self.assertIn(self.node_id1, cluster['nodes']) - node1 = utils.get_a_node(self, self.node_id1) - self.assertEqual(self.cluster_id, node1['cluster_id']) - self.assertEqual(1, node1['index']) - - # Add two nodes to cluster - nodes = [self.node_id2, self.node_id3] - utils.cluster_add_nodes(self, self.cluster_id, nodes) - - # Verify result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual(3, len(cluster['nodes'])) - self.assertIn(self.node_id2, cluster['nodes']) - self.assertIn(self.node_id3, cluster['nodes']) - node2 = utils.get_a_node(self, self.node_id2) - node3 = utils.get_a_node(self, self.node_id3) - self.assertEqual(self.cluster_id, node2['cluster_id']) - self.assertEqual(self.cluster_id, node3['cluster_id']) - self.assertEqual([2, 3], sorted([node2['index'], node3['index']])) - - # Delete one node from cluster - utils.cluster_del_nodes(self, self.cluster_id, [self.node_id1]) - - # Verify result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual(2, len(cluster['nodes'])) - self.assertNotIn(self.node_id1, cluster['nodes']) - node1 = utils.get_a_node(self, self.node_id1) - self.assertEqual('', node1['cluster_id']) - self.assertEqual(-1, node1['index']) - - # Delete two nodes from cluster - nodes = [self.node_id2, self.node_id3] - utils.cluster_del_nodes(self, self.cluster_id, nodes) - - # Verify result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual(0, len(cluster['nodes'])) - node2 = utils.get_a_node(self, self.node_id2) - node3 = utils.get_a_node(self, self.node_id3) - self.assertEqual('', node2['cluster_id']) - self.assertEqual('', node3['cluster_id']) - self.assertEqual(-1, node2['index']) - self.assertEqual(-1, node3['index']) - - -class TestClusterReplaceNodes(base.BaseSenlinFunctionalTest): - - def setUp(self): - super(TestClusterReplaceNodes, self).setUp() - # Create a profile - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - # Create a cluster - self.cluster_id = utils.create_a_cluster(self, self.profile_id, - max_size=10) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - self.old_id1 = utils.create_a_node(self, self.profile_id, - self.cluster_id) - self.old_id2 = utils.create_a_node(self, self.profile_id, - self.cluster_id) - self.old_id3 = utils.create_a_node(self, self.profile_id, - self.cluster_id) - self.addCleanup(utils.delete_a_node, self, self.old_id3) - self.addCleanup(utils.delete_a_node, self, self.old_id2) - self.addCleanup(utils.delete_a_node, self, self.old_id1) - # Create three orphan nodes - self.new_id1 = utils.create_a_node(self, self.profile_id) - self.new_id2 = utils.create_a_node(self, self.profile_id) - self.new_id3 = utils.create_a_node(self, self.profile_id) - - @utils.api_microversion('1.3') - @decorators.attr(type=['functional']) - @decorators.idempotent_id('c2948087-b0ff-47f7-a4bf-1cb16e71cc9d') - def test_cluster_replace_node(self): - # Verify the cluster - cluster = utils.get_a_cluster(self, self.cluster_id) - cluster_nodes = cluster['nodes'] - self.assertEqual(3, len(cluster_nodes)) - self.assertEqual('ACTIVE', cluster['status']) - - # Replace one node - nodes = { - self.old_id1: self.new_id1 - } - utils.cluster_replace_nodes(self, self.cluster_id, nodes) - # Verify result - cluster = utils.get_a_cluster(self, self.cluster_id) - cluster_nodes = cluster['nodes'] - self.assertEqual(3, len(cluster_nodes)) - self.assertIn(self.new_id1, cluster_nodes) - new_node1 = utils.get_a_node(self, self.new_id1) - old_node1 = utils.get_a_node(self, self.old_id1) - self.assertEqual(self.cluster_id, new_node1['cluster_id']) - self.assertEqual('', old_node1['cluster_id']) - - # Replace two nodes - nodes = { - self.old_id2: self.new_id2, - self.old_id3: self.new_id3 - } - utils.cluster_replace_nodes(self, self.cluster_id, nodes) - - # Verify result - cluster = utils.get_a_cluster(self, self.cluster_id) - cluster_nodes = cluster['nodes'] - self.assertEqual(3, len(cluster_nodes)) - self.assertIn(self.new_id2, cluster_nodes) - self.assertIn(self.new_id3, cluster_nodes) - new_node2 = utils.get_a_node(self, self.new_id2) - new_node3 = utils.get_a_node(self, self.new_id3) - old_node2 = utils.get_a_node(self, self.old_id2) - old_node3 = utils.get_a_node(self, self.old_id3) - self.assertEqual(self.cluster_id, new_node2['cluster_id']) - self.assertEqual(self.cluster_id, new_node3['cluster_id']) - self.assertEqual('', old_node2['cluster_id']) - self.assertEqual('', old_node3['cluster_id']) diff --git a/senlin/tests/tempest/functional/test_cluster_scaling.py b/senlin/tests/tempest/functional/test_cluster_scaling.py deleted file mode 100644 index 488dc20a8..000000000 --- a/senlin/tests/tempest/functional/test_cluster_scaling.py +++ /dev/null @@ -1,240 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.common.i18n import _ -from senlin.tests.tempest.common import utils -from senlin.tests.tempest.functional import base - - -class TestClusterScaleInOut(base.BaseSenlinFunctionalTest): - - def setUp(self): - super(TestClusterScaleInOut, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id, - min_size=1, max_size=5, - desired_capacity=1) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('e326554b-9b42-45f8-a9ea-4ab0914fb364') - def test_cluster_scale_in_out(self): - # Scale out cluster without count specified - utils.cluster_scale_out(self, self.cluster_id) - - # Verify scale out result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(2, cluster['desired_capacity']) - self.assertEqual(2, len(cluster['nodes'])) - - # Scale out cluster with count set to 2 - utils.cluster_scale_out(self, self.cluster_id, count=2) - - # Verify scale out result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(4, cluster['desired_capacity']) - self.assertEqual(4, len(cluster['nodes'])) - - # Keep scaling out cluster with count set to 2 - res = utils.cluster_scale_out(self, self.cluster_id, count=2, - expected_status='FAILED') - - # Verify action result and action failure reason - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(4, cluster['desired_capacity']) - self.assertEqual(4, len(cluster['nodes'])) - reason = _("The target capacity (6) is greater " - "than the cluster's max_size (5).") - self.assertEqual(reason, res) - - # Scale in cluster with count set to 2 - utils.cluster_scale_in(self, self.cluster_id, count=2) - - # Verify scale in result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(2, cluster['desired_capacity']) - self.assertEqual(2, len(cluster['nodes'])) - - # Scale in cluster without count specified - utils.cluster_scale_in(self, self.cluster_id) - - # Verify scale in result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(1, cluster['desired_capacity']) - self.assertEqual(1, len(cluster['nodes'])) - - # Keep scaling in cluster - res = utils.cluster_scale_in(self, self.cluster_id, - expected_status='FAILED') - - # Verify action result and action failure reason - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(1, cluster['desired_capacity']) - self.assertEqual(1, len(cluster['nodes'])) - reason = _("The target capacity (0) is less " - "than the cluster's min_size (1).") - self.assertEqual(reason, res) - - -class TestClusterResize(base.BaseSenlinFunctionalTest): - - def setUp(self): - super(TestClusterResize, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id, - min_size=2, max_size=5, - desired_capacity=3) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('02b570ef-9101-489b-9ee7-8c1f35d2b105') - def test_cluster_resize_basic(self): - # Increase cluster size by specifying adjustment count - kwargs = { - 'adj_type': 'CHANGE_IN_CAPACITY', - 'number': 2 - } - utils.cluster_resize(self, self.cluster_id, **kwargs) - - # Verify resizing result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(5, cluster['desired_capacity']) - self.assertEqual(5, len(cluster['nodes'])) - - # Decrease cluster size by specifying adjustment percentage - kwargs = { - 'adj_type': 'CHANGE_IN_PERCENTAGE', - 'number': -50 - } - utils.cluster_resize(self, self.cluster_id, **kwargs) - - # Verify resizing result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(3, cluster['desired_capacity']) - self.assertEqual(3, len(cluster['nodes'])) - - # Decrease cluster size by specifying exact capacity - kwargs = { - 'adj_type': 'EXACT_CAPACITY', - 'number': 2 - } - utils.cluster_resize(self, self.cluster_id, **kwargs) - - # Verify resizing result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(2, cluster['desired_capacity']) - self.assertEqual(2, len(cluster['nodes'])) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('72aac2f7-8cb3-4d95-a0b8-4aeeadf4b319') - def test_cluster_resize_constraint_breaking(self): - # Do best-effort resizing when size upper limit is broken - kwargs = { - 'adj_type': 'CHANGE_IN_CAPACITY', - 'number': 1, - 'strict': False - } - utils.cluster_resize(self, self.cluster_id, **kwargs) - - # Verify resizing result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(4, cluster['desired_capacity']) - self.assertEqual(4, len(cluster['nodes'])) - - # Do best-effort resizing when size lower limit is broken - kwargs = { - 'adj_type': 'CHANGE_IN_CAPACITY', - 'number': -5, - 'strict': False - } - utils.cluster_resize(self, self.cluster_id, **kwargs) - - # Verify resizing result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(2, cluster['desired_capacity']) - self.assertEqual(2, len(cluster['nodes'])) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('9bde1918-7821-4024-a382-44e6b4950a7e') - def test_cluster_resize_constraint_adjusting(self): - # Increase cluster size with upper limit increased - kwargs = { - 'adj_type': 'CHANGE_IN_CAPACITY', - 'number': 3, - 'max_size': 7 - } - utils.cluster_resize(self, self.cluster_id, **kwargs) - - # Verify resizing result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(6, cluster['desired_capacity']) - self.assertEqual(6, len(cluster['nodes'])) - self.assertEqual(7, cluster['max_size']) - - # Decrease cluster size upper limit with strict set to False - kwargs = { - 'max_size': 4, - 'strict': False - } - utils.cluster_resize(self, self.cluster_id, **kwargs) - - # Verify resizing result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(4, cluster['desired_capacity']) - self.assertEqual(4, len(cluster['nodes'])) - self.assertEqual(4, cluster['max_size']) - - # Decrease cluster size with lower limit decreased - kwargs = { - 'adj_type': 'CHANGE_IN_CAPACITY', - 'number': -4, - 'min_size': 0 - } - utils.cluster_resize(self, self.cluster_id, **kwargs) - - # Verify resizing result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(0, cluster['desired_capacity']) - self.assertEqual(0, len(cluster['nodes'])) - self.assertEqual(0, cluster['min_size']) - - # Increase cluster size lower limit with strict set to False - kwargs = { - 'min_size': 2, - 'strict': False - } - utils.cluster_resize(self, self.cluster_id, **kwargs) - - # Verify resizing result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(2, cluster['desired_capacity']) - self.assertEqual(2, len(cluster['nodes'])) - self.assertEqual(2, cluster['min_size']) diff --git a/senlin/tests/tempest/functional/test_lb_policy.py b/senlin/tests/tempest/functional/test_lb_policy.py deleted file mode 100644 index eb998ac55..000000000 --- a/senlin/tests/tempest/functional/test_lb_policy.py +++ /dev/null @@ -1,89 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.common import constants -from senlin.tests.tempest.common import utils -from senlin.tests.tempest.functional import base - - -class TestLBPolicy(base.BaseSenlinFunctionalTest): - - def setUp(self): - super(TestLBPolicy, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id, - min_size=0, max_size=5, - desired_capacity=2) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('6b513a5d-75b6-447a-b95d-e17b84ac9ee8') - def test_lb_policy(self): - # Verify there is no lb information in node data - cluster = utils.get_a_cluster(self, self.cluster_id) - for n in cluster['nodes']: - node = utils.get_a_node(self, n) - self.assertNotIn('lb_member', node['data']) - - # Create a lb policy - spec = constants.spec_lb_policy - policy_id = utils.create_a_policy(self, spec) - lb_policy = utils.get_a_policy(self, policy_id) - self.addCleanup(utils.delete_a_policy, self, lb_policy['id']) - - # Attach lb policy to cluster - utils.cluster_attach_policy(self, self.cluster_id, lb_policy['id']) - - # Verify lb information is added into node data - cluster = utils.get_a_cluster(self, self.cluster_id) - for n in cluster['nodes']: - node = utils.get_a_node(self, n) - self.assertIn('lb_member', node['data']) - - # Scale out cluster - utils.cluster_scale_out(self, self.cluster_id) - - # Verify scale out result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(3, cluster['desired_capacity']) - self.assertEqual(3, len(cluster['nodes'])) - - # Verify lb information in all nodes' data - cluster = utils.get_a_cluster(self, self.cluster_id) - for n in cluster['nodes']: - node = utils.get_a_node(self, n) - self.assertIn('lb_member', node['data']) - - # Scale in cluster - utils.cluster_scale_in(self, self.cluster_id) - - # Verify scale in result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(2, cluster['desired_capacity']) - self.assertEqual(2, len(cluster['nodes'])) - for n in cluster['nodes']: - node = utils.get_a_node(self, n) - self.assertIn('lb_member', node['data']) - - # Detach lb policy from cluster - utils.cluster_detach_policy(self, self.cluster_id, lb_policy['id']) - - # Verify lb information has been removed from node data - cluster = utils.get_a_cluster(self, self.cluster_id) - for n in cluster['nodes']: - node = utils.get_a_node(self, n) - self.assertNotIn('lb_member', node['data']) diff --git a/senlin/tests/tempest/functional/test_node_basic.py b/senlin/tests/tempest/functional/test_node_basic.py deleted file mode 100644 index 25d0b93e1..000000000 --- a/senlin/tests/tempest/functional/test_node_basic.py +++ /dev/null @@ -1,116 +0,0 @@ -# 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. - -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators - -from senlin.tests.tempest.common import utils -from senlin.tests.tempest.functional import base - - -class TestNodeCreateShowListDelete(base.BaseSenlinFunctionalTest): - - def setUp(self): - super(TestNodeCreateShowListDelete, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('eff142d3-e7fd-4f2a-aaff-46c210d9fa0d') - def test_node_create_show_list_delete(self): - # Create an orphan node - name = data_utils.rand_name('node') - metadata = {'k1': 'v1'} - role = 'individual' - node_id1 = utils.create_a_node( - self, self.profile_id, metadata=metadata, role=role, name=name) - - # Verify creation result - node1 = utils.get_a_node(self, node_id1) - self.assertIsNotNone(node1) - self.assertEqual(name, node1['name']) - self.assertEqual(metadata, node1['metadata']) - self.assertEqual(role, node1['role']) - self.assertEqual('', node1['cluster_id']) - self.assertNotIn('details', node1) - - # Get node with detail - node1 = utils.get_a_node(self, node_id1, show_details=True) - self.assertIn('details', node1) - self.assertIsNotNone(node1['details']) - - # Create second node with target cluster - name = data_utils.rand_name('node') - node_id2 = utils.create_a_node( - self, self.profile_id, cluster_id=self.cluster_id, - metadata=metadata, role=role, name=name) - - # Verify creation result - node2 = utils.get_a_node(self, node_id2) - self.assertIsNotNone(node2) - self.assertEqual(self.cluster_id, node2['cluster_id']) - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertIn(node_id2, cluster['nodes']) - - # List nodes - nodes = utils.list_nodes(self) - self.assertIsNotNone(nodes) - self.assertEqual(2, len(nodes)) - node_ids = [n['id'] for n in nodes] - self.assertIn(node_id1, node_ids) - self.assertIn(node_id2, node_ids) - - # Delete nodes - utils.delete_a_node(self, node_id1) - utils.delete_a_node(self, node_id2) - - -class TestNodeUpdate(base.BaseSenlinFunctionalTest): - - def setUp(self): - super(TestNodeUpdate, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.profile_id_new = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id_new) - self.node_id = utils.create_a_node(self, self.profile_id) - self.addCleanup(utils.delete_a_node, self, self.node_id) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('d373fb1d-33a1-434f-a850-fb78eff15d18') - def test_node_update_basic_properties(self): - name = 'new-name' - role = 'new-role' - metadata = {'k2': 'v2'} - - # Update node - utils.update_a_node(self, self.node_id, name=name, metadata=metadata, - role=role) - - # Verify update result - node = utils.get_a_node(self, self.node_id) - self.assertEqual(name, node['name']) - self.assertEqual(metadata, node['metadata']) - self.assertEqual(role, node['role']) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('361e051d-b55b-4943-8a01-462f6fc5be43') - def test_node_update_profile(self): - - # Update node - utils.update_a_node(self, self.node_id, profile_id=self.profile_id_new) - - # Verify update result - node = utils.get_a_node(self, self.node_id) - self.assertEqual(self.profile_id_new, node['profile_id']) diff --git a/senlin/tests/tempest/functional/test_receiver.py b/senlin/tests/tempest/functional/test_receiver.py deleted file mode 100644 index 881a7b89c..000000000 --- a/senlin/tests/tempest/functional/test_receiver.py +++ /dev/null @@ -1,48 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.common import utils -from senlin.tests.tempest.functional import base - - -class TestReceiver(base.BaseSenlinFunctionalTest): - - def setUp(self): - super(TestReceiver, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('60b04757-1ee1-4955-a098-b1c42af6bb19') - def test_webhook(self): - # Create a webhook type of receiver - receiver_id = utils.create_a_receiver(self, self.cluster_id, - 'CLUSTER_SCALE_OUT', - r_type='webhook', - params={'count': 2}) - self.addCleanup(utils.delete_a_receiver, self, receiver_id) - receiver = utils.get_a_receiver(self, receiver_id) - webhook_url = receiver['channel']['alarm_url'] - - # Trigger webhook and wait for action execution - res = self.client.trigger_webhook(webhook_url) - action_id = res['location'].split('/actions/')[1] - self.client.wait_for_status('actions', action_id, 'SUCCEEDED') - - # Verify action result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual(2, cluster['desired_capacity']) - self.assertEqual(2, len(cluster['nodes'])) diff --git a/senlin/tests/tempest/functional/test_scaling_policy.py b/senlin/tests/tempest/functional/test_scaling_policy.py deleted file mode 100644 index 53b224710..000000000 --- a/senlin/tests/tempest/functional/test_scaling_policy.py +++ /dev/null @@ -1,131 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.common.i18n import _ -from senlin.tests.tempest.common import constants -from senlin.tests.tempest.common import utils -from senlin.tests.tempest.functional import base - - -class TestScalingPolicy(base.BaseSenlinFunctionalTest): - - def setUp(self): - super(TestScalingPolicy, self).setUp() - self.profile_id = utils.create_a_profile(self) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id, - min_size=0, max_size=5, - desired_capacity=1) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.attr(type=['functional']) - @decorators.idempotent_id('6b513a5d-75b6-447a-b95d-e17b84ac9ee8') - def test_scaling_policy(self): - # Create a scaling policy targets on CLUSTER_SCALE_OUT action - spec = constants.spec_scaling_policy - spec['properties'] = { - 'event': 'CLUSTER_SCALE_OUT', - 'adjustment': { - 'type': 'CHANGE_IN_CAPACITY', - 'number': 2, - 'min_step': 1, - 'best_effort': True - } - } - policy_id = utils.create_a_policy(self, spec) - scaleout_policy = utils.get_a_policy(self, policy_id) - self.addCleanup(utils.delete_a_policy, self, scaleout_policy['id']) - - # Create a scaling policy targets on CLUSTER_SCALE_IN action - spec['properties'] = { - 'event': 'CLUSTER_SCALE_IN', - 'adjustment': { - 'type': 'CHANGE_IN_PERCENTAGE', - 'number': 50, - 'min_step': 2, - 'best_effort': False - } - } - policy_id = utils.create_a_policy(self, spec) - scalein_policy = utils.get_a_policy(self, policy_id) - self.addCleanup(utils.delete_a_policy, self, scalein_policy['id']) - - # Attach scale in/out policies to cluster - for policy in [scaleout_policy, scalein_policy]: - utils.cluster_attach_policy(self, self.cluster_id, policy['id']) - self.addCleanup(utils.cluster_detach_policy, self, - self.cluster_id, policy['id']) - - # Scale out cluster without count specified - utils.cluster_scale_out(self, self.cluster_id) - - # Verify scale out result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(3, cluster['desired_capacity']) - self.assertEqual(3, len(cluster['nodes'])) - - # Scale out cluster with count set to 1 - utils.cluster_scale_out(self, self.cluster_id, count=1) - - # Verify scale out result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(4, cluster['desired_capacity']) - self.assertEqual(4, len(cluster['nodes'])) - - # Keep scaling out cluster with count set to 2 to - # verify best_effort parameter - utils.cluster_scale_out(self, self.cluster_id, count=2) - - # Verify scale out result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(5, cluster['desired_capacity']) - self.assertEqual(5, len(cluster['nodes'])) - - # Scale in cluster without count specified - utils.cluster_scale_in(self, self.cluster_id) - - # Verify scale in result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(3, cluster['desired_capacity']) - self.assertEqual(3, len(cluster['nodes'])) - - # Scale in cluster without count specified to - # verify min_step parameter - utils.cluster_scale_in(self, self.cluster_id) - - # Verify scale in result - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(1, cluster['desired_capacity']) - self.assertEqual(1, len(cluster['nodes'])) - - # Keep scaling in cluster with count set to 2 to - # verify best_effort parameter - res = utils.cluster_scale_in(self, self.cluster_id, count=2, - expected_status='FAILED') - - # Verify action result and action failure reason - cluster = utils.get_a_cluster(self, self.cluster_id) - self.assertEqual('ACTIVE', cluster['status']) - self.assertEqual(1, cluster['desired_capacity']) - self.assertEqual(1, len(cluster['nodes'])) - reason = _( - "Policy check failure: Failed policy '%s': The target " - "capacity (-1) is less than the cluster's " - "min_size (0).") % scalein_policy['name'] - self.assertEqual(reason, res) diff --git a/senlin/tests/tempest/integration/__init__.py b/senlin/tests/tempest/integration/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/senlin/tests/tempest/integration/base.py b/senlin/tests/tempest/integration/base.py deleted file mode 100644 index dcb328046..000000000 --- a/senlin/tests/tempest/integration/base.py +++ /dev/null @@ -1,79 +0,0 @@ -# -# 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. - -from tempest import config - -from senlin.tests.tempest import base -from senlin.tests.tempest.common import clustering_client -from senlin.tests.tempest.common import compute_client -from senlin.tests.tempest.common import messaging_client -from senlin.tests.tempest.common import network_client - -CONF = config.CONF - - -class BaseSenlinIntegrationTest(base.BaseSenlinTest): - - credentials = ['admin'] - - @classmethod - def setup_clients(cls): - super(BaseSenlinIntegrationTest, cls).setup_clients() - cls.client = clustering_client.ClusteringIntegrationClient( - cls.os_admin.auth_provider, - CONF.clustering.catalog_type, - CONF.identity.region, - **cls.default_params_with_timeout_values - ) - - cls.messaging_client = messaging_client.V2MessagingClient( - cls.os_admin.auth_provider, - CONF.messaging.catalog_type, - CONF.identity.region, - **cls.default_params_with_timeout_values - ) - - -class BaseSenlinIntegrationNonAdminTest(base.BaseSenlinTest): - - @classmethod - def setup_clients(cls): - super(BaseSenlinIntegrationNonAdminTest, cls).setup_clients() - cls.client = clustering_client.ClusteringIntegrationClient( - cls.os_primary.auth_provider, - CONF.clustering.catalog_type, - CONF.identity.region, - **cls.default_params_with_timeout_values - ) - - cls.messaging_client = messaging_client.V2MessagingClient( - cls.os_primary.auth_provider, - CONF.messaging.catalog_type, - CONF.identity.region, - **cls.default_params_with_timeout_values - ) - - cls.compute_client = compute_client.V21ComputeClient( - cls.os_primary.auth_provider, - CONF.compute.catalog_type, - CONF.identity.region, - **cls.default_params_with_timeout_values - ) - - cls.network_client = network_client.NetworkClient( - cls.os_primary.auth_provider, - CONF.network.catalog_type, - CONF.identity.region, - **cls.default_params_with_timeout_values - ) diff --git a/senlin/tests/tempest/integration/test_heat_stack_cluster.py b/senlin/tests/tempest/integration/test_heat_stack_cluster.py deleted file mode 100644 index ab3643da1..000000000 --- a/senlin/tests/tempest/integration/test_heat_stack_cluster.py +++ /dev/null @@ -1,52 +0,0 @@ -# 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. - -from tempest.lib import decorators - -from senlin.tests.tempest.common import constants -from senlin.tests.tempest.common import utils -from senlin.tests.tempest.integration import base - - -class TestHeatStackCluster(base.BaseSenlinIntegrationTest): - - def setUp(self): - super(TestHeatStackCluster, self).setUp() - self.profile_id = utils.create_a_profile( - self, spec=constants.spec_heat_stack) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - - @decorators.attr(type=['integration']) - @decorators.idempotent_id('c9ba5700-f384-4376-b61b-e2b108ab3a16') - def test_cluster_create_delete(self): - # Create a cluster - desired_capacity = 2 - min_size = 1 - max_size = 3 - metadata = {'k1': 'v1'} - timeout = 300 - cluster_id = utils.create_a_cluster( - self, self.profile_id, desired_capacity, min_size, max_size, - timeout, metadata) - - # Verify creation result - cluster = utils.get_a_cluster(self, cluster_id) - self.assertIsNotNone(cluster) - self.assertEqual(desired_capacity, cluster['desired_capacity']) - self.assertEqual(desired_capacity, len(cluster['nodes'])) - for nid in cluster['nodes']: - node = utils.get_a_node(self, nid) - self.assertEqual('ACTIVE', node['status']) - self.assertEqual(cluster_id, node['cluster_id']) - - # Delete cluster - utils.delete_a_cluster(self, cluster_id) diff --git a/senlin/tests/tempest/integration/test_nova_server_cluster.py b/senlin/tests/tempest/integration/test_nova_server_cluster.py deleted file mode 100644 index 05eb8c484..000000000 --- a/senlin/tests/tempest/integration/test_nova_server_cluster.py +++ /dev/null @@ -1,116 +0,0 @@ -# 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. - -import six - -from tempest.lib import decorators - -from senlin.tests.tempest.common import constants -from senlin.tests.tempest.common import utils -from senlin.tests.tempest.integration import base - - -class TestNovaServerCluster(base.BaseSenlinIntegrationTest): - - def setUp(self): - super(TestNovaServerCluster, self).setUp() - keypair_name = utils.create_a_keypair(self) - self.spec = constants.spec_nova_server - self.spec['properties']['key_name'] = keypair_name - self.profile_id = utils.create_a_profile(self, self.spec) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.addCleanup(utils.delete_a_keypair, self, keypair_name) - - @decorators.attr(type=['integration']) - @decorators.idempotent_id('c26eae1c-5c46-4a5f-be63-954d7229c8cc') - def test_cluster_create_delete(self): - # Create a cluster - desired_capacity = 2 - min_size = 1 - max_size = 3 - metadata = {'k1': 'v1'} - timeout = 600 - cluster_id = utils.create_a_cluster( - self, self.profile_id, desired_capacity, min_size, max_size, - timeout, metadata) - - # Verify creation result - cluster = utils.get_a_cluster(self, cluster_id) - self.assertIsNotNone(cluster) - self.assertEqual(desired_capacity, cluster['desired_capacity']) - self.assertEqual(desired_capacity, len(cluster['nodes'])) - for nid in cluster['nodes']: - node = utils.get_a_node(self, nid, show_details=True) - self.assertEqual('ACTIVE', node['status']) - self.assertEqual(cluster_id, node['cluster_id']) - self.assertIsNotNone(node['details']) - self.assertEqual('ACTIVE', node['details']['status']) - self.assertEqual(self.spec['properties']['flavor'], - node['details']['flavor']) - self.assertEqual(self.spec['properties']['name'], - node['details']['name']) - metadata = { - 'cluster_id': cluster['id'], - 'cluster_node_id': node['id'], - 'cluster_node_index': six.text_type(node['index']) - } - self.assertEqual(metadata, node['details']['metadata']) - - # Delete cluster - utils.delete_a_cluster(self, cluster_id) - - -class TestNovaServerClusterNonAdmin(base.BaseSenlinIntegrationNonAdminTest): - - def setUp(self): - super(TestNovaServerClusterNonAdmin, self).setUp() - utils.prepare_and_cleanup_for_nova_server(self) - self.profile_id = utils.create_a_profile(self, self.spec) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - - @decorators.attr(type=['integration']) - @decorators.idempotent_id('c26eae1c-5c46-4a5f-be63-954d7229c8cc') - def test_cluster_create_delete(self): - # Create a cluster - desired_capacity = 2 - min_size = 1 - max_size = 3 - metadata = {'k1': 'v1'} - timeout = 600 - cluster_id = utils.create_a_cluster( - self, self.profile_id, desired_capacity, min_size, max_size, - timeout, metadata) - - # Verify creation result - cluster = utils.get_a_cluster(self, cluster_id) - self.assertIsNotNone(cluster) - self.assertEqual(desired_capacity, cluster['desired_capacity']) - self.assertEqual(desired_capacity, len(cluster['nodes'])) - for nid in cluster['nodes']: - node = utils.get_a_node(self, nid, show_details=True) - self.assertEqual('ACTIVE', node['status']) - self.assertEqual(cluster_id, node['cluster_id']) - self.assertIsNotNone(node['details']) - self.assertEqual('ACTIVE', node['details']['status']) - self.assertEqual(self.spec['properties']['flavor'], - node['details']['flavor']) - self.assertEqual(self.spec['properties']['name'], - node['details']['name']) - metadata = { - 'cluster_id': cluster['id'], - 'cluster_node_id': node['id'], - 'cluster_node_index': six.text_type(node['index']) - } - self.assertEqual(metadata, node['details']['metadata']) - - # Delete cluster - utils.delete_a_cluster(self, cluster_id) diff --git a/senlin/tests/tempest/integration/test_receiver.py b/senlin/tests/tempest/integration/test_receiver.py deleted file mode 100644 index 29ec1cd16..000000000 --- a/senlin/tests/tempest/integration/test_receiver.py +++ /dev/null @@ -1,90 +0,0 @@ -# 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. - -import time - -from oslo_utils import timeutils -from tempest.lib import decorators - -from senlin.tests.tempest.common import constants -from senlin.tests.tempest.common import utils -from senlin.tests.tempest.integration import base - - -class TestReceiver(base.BaseSenlinIntegrationTest): - - def setUp(self): - super(TestReceiver, self).setUp() - self.profile_id = utils.create_a_profile( - self, spec=constants.spec_heat_stack) - self.addCleanup(utils.delete_a_profile, self, self.profile_id) - self.cluster_id = utils.create_a_cluster(self, self.profile_id, - desired_capacity=1) - self.addCleanup(utils.delete_a_cluster, self, self.cluster_id) - - @decorators.attr(type=['integration']) - @decorators.idempotent_id('16902c7a-1057-49bb-aa9e-227297864a92') - def test_message_receiver(self): - # Create a message type of receiver - receiver_id = utils.create_a_receiver(self, None, None, - r_type='message') - self.addCleanup(utils.delete_a_receiver, self, receiver_id) - receiver = utils.get_a_receiver(self, receiver_id) - queue_name = receiver['channel']['queue_name'] - self.assertTrue(queue_name.startswith('senlin-receiver-')) - - # Trigger cluster_scale_out action - message1 = { - 'body': { - 'cluster': self.cluster_id, - 'action': 'CLUSTER_SCALE_OUT' - }, - 'ttl': 3600 - } - utils.post_messages(self, queue_name, [message1]) - - # Wait and verify result - timeout = 120 - with timeutils.StopWatch(timeout) as timeout_watch: - while timeout > 0: - time.sleep(5) - cluster = utils.get_a_cluster(self, self.cluster_id) - if (len(cluster['nodes']) == 2 and - cluster['status'] == 'ACTIVE'): - break - timeout = timeout_watch.leftover(True) - - if timeout <= 0: - raise Exception('Failed in triggering cluster action.') - - # TODO(Anyone): uncomment the following code when DB - # concurrency issue is fixed. -# # Trigger multiple actions at the same time -# message2 = { -# 'body': { -# 'cluster': self.cluster_id, -# 'action': 'CLUSTER_SCALE_IN' -# }, -# 'ttl': 3600 -# } -# utils.post_messages(self, queue_name, [message1, message1, message2]) -# -# # Wait and verify result -# timeout = 360 -# while timeout > 0: -# time.sleep(5) -# cluster = utils.get_a_cluster(self, self.cluster_id) -# if len(cluster['nodes']) == 3 and cluster['status'] == 'ACTIVE': -# break -# timeout -= 5 -# if timeout <= 0: -# raise Exception('Failed in triggering cluster action.') diff --git a/senlin/tests/tempest/plugin.py b/senlin/tests/tempest/plugin.py deleted file mode 100644 index e7547758f..000000000 --- a/senlin/tests/tempest/plugin.py +++ /dev/null @@ -1,41 +0,0 @@ -# -# 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. - - -import os - -from tempest.test_discover import plugins - -from senlin.tests.tempest import config as config_senlin - - -class SenlinTempestPlugin(plugins.TempestPlugin): - def load_tests(self): - base_path = os.path.split(os.path.dirname( - os.path.abspath(__file__)))[0] - base_path += '/../..' - test_dir = "senlin/tests/tempest" - full_test_dir = os.path.join(base_path, test_dir) - return full_test_dir, base_path - - def register_opts(self, conf): - conf.register_opt(config_senlin.service_option, - group='service_available') - conf.register_group(config_senlin.clustering_group) - conf.register_opts(config_senlin.ClusteringGroup, - group='clustering') - - def get_opt_lists(self): - return [(config_senlin.clustering_group.name, - config_senlin.ClusteringGroup), - ('service_available', [config_senlin.service_option])] diff --git a/senlin/tests/tempest/post_test_hook.sh b/senlin/tests/tempest/post_test_hook.sh index ff5b847d8..7e26eef93 100755 --- a/senlin/tests/tempest/post_test_hook.sh +++ b/senlin/tests/tempest/post_test_hook.sh @@ -21,3 +21,9 @@ export DEVSTACK_DIR=$DEST/devstack export SENLIN_DIR=$DEST/senlin source $DEVSTACK_DIR/openrc admin admin + +if [ ! -z "$1" ]; then + cd $DEST/tempest + echo "Running tempest with regex $1" + sudo tox -evenv-tempest -- tempest run --regex $1 +fi diff --git a/setup.cfg b/setup.cfg index 7da4e9e79..8e4caa0fa 100644 --- a/setup.cfg +++ b/setup.cfg @@ -67,9 +67,6 @@ senlin.endpoints = heat = senlin.engine.notifications.heat_endpoint:HeatNotificationEndpoint nova = senlin.engine.notifications.nova_endpoint:NovaNotificationEndpoint -tempest.test_plugins = - senlin_tests = senlin.tests.tempest.plugin:SenlinTempestPlugin - [global] setup-hooks = pbr.hooks.setup_hook