Remove Senlin
This removes all support for the retired Senlin project that was deprecated in 3.0.0 Change-Id: I2d083fa65c535201a2c25b56cf2a2ae710983d2f
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
- job:
|
||||
name: rally-task-senlin
|
||||
parent: rally-task-at-devstack
|
||||
vars:
|
||||
rally_task: rally-jobs/senlin.yaml
|
||||
@@ -26,6 +26,8 @@ Removed
|
||||
* Removed all support for the retired Murano project
|
||||
* Removed all support for the retired Sahara project
|
||||
|
||||
* Removed all support for the retired Senlin project
|
||||
|
||||
[3.0.0] - 2024-05-23
|
||||
--------------------
|
||||
|
||||
|
||||
@@ -818,10 +818,6 @@
|
||||
# Number of cleanup threads to run (integer value)
|
||||
#cleanup_threads = 20
|
||||
|
||||
# Time in seconds to wait for senlin action to finish. (floating point
|
||||
# value)
|
||||
#senlin_action_timeout = 3600
|
||||
|
||||
# Neutron create loadbalancer timeout (floating point value)
|
||||
#neutron_create_loadbalancer_timeout = 500.0
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
version: 2
|
||||
title: Task for gate-rally-dsvm-senlin-rally-ubuntu-xenial-nv job
|
||||
description: >
|
||||
This task contains various scenarios for testing senlin plugins
|
||||
subtasks:
|
||||
-
|
||||
title: SenlinClusters.create_and_delete_cluster tests
|
||||
scenario:
|
||||
SenlinClusters.create_and_delete_cluster:
|
||||
desired_capacity: 3
|
||||
min_size: 0
|
||||
max_size: 5
|
||||
runner:
|
||||
constant:
|
||||
times: 3
|
||||
concurrency: 2
|
||||
contexts:
|
||||
users:
|
||||
tenants: 2
|
||||
users_per_tenant: 2
|
||||
profiles:
|
||||
type: os.nova.server
|
||||
version: "1.0"
|
||||
properties:
|
||||
name: cirros_server
|
||||
flavor: 1
|
||||
image: "cirros-0.5.2-x86_64-disk"
|
||||
networks:
|
||||
- network: private
|
||||
@@ -26,7 +26,6 @@ from rally_openstack.common.cfg import nova
|
||||
from rally_openstack.common.cfg import octavia
|
||||
from rally_openstack.common.cfg import osclients
|
||||
from rally_openstack.common.cfg import profiler
|
||||
from rally_openstack.common.cfg import senlin
|
||||
from rally_openstack.common.cfg import vm
|
||||
from rally_openstack.common.cfg import watcher
|
||||
|
||||
@@ -48,7 +47,7 @@ def list_opts():
|
||||
nova.OPTS, osclients.OPTS, profiler.OPTS,
|
||||
vm.OPTS, glance.OPTS, watcher.OPTS, tempest.OPTS,
|
||||
keystone_roles.OPTS, keystone_users.OPTS, cleanup.OPTS,
|
||||
senlin.OPTS, neutron.OPTS, octavia.OPTS,
|
||||
neutron.OPTS, octavia.OPTS,
|
||||
osprofilerchart.OPTS):
|
||||
for category, opt in l_opts.items():
|
||||
opts.setdefault(category, [])
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
# Copyright 2013: Mirantis Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 rally.common import cfg
|
||||
|
||||
OPTS = {"openstack": [
|
||||
cfg.FloatOpt("senlin_action_timeout",
|
||||
default=3600,
|
||||
deprecated_group="benchmark",
|
||||
help="Time in seconds to wait for senlin action to finish.")
|
||||
]}
|
||||
@@ -57,7 +57,6 @@ class _Service(utils.ImmutableMixin, utils.EnumMixin):
|
||||
CEILOMETER = "ceilometer"
|
||||
MONASCA = "monasca"
|
||||
S3 = "s3"
|
||||
SENLIN = "senlin"
|
||||
TROVE = "trove"
|
||||
SWIFT = "swift"
|
||||
MISTRAL = "mistral"
|
||||
@@ -82,7 +81,6 @@ class _ServiceType(utils.ImmutableMixin, utils.EnumMixin):
|
||||
CLOUD = "cloudformation"
|
||||
ORCHESTRATION = "orchestration"
|
||||
IDENTITY = "identity"
|
||||
CLUSTERING = "clustering"
|
||||
COMPUTE = "compute"
|
||||
NETWORK = "network"
|
||||
DNS = "dns"
|
||||
@@ -101,7 +99,6 @@ class _ServiceType(utils.ImmutableMixin, utils.EnumMixin):
|
||||
|
||||
def __init__(self):
|
||||
self.__names = {
|
||||
self.CLUSTERING: _Service.SENLIN,
|
||||
self.COMPUTE: _Service.NOVA,
|
||||
# unversioned endpoint of Cinder
|
||||
self.BLOCK_STORAGE: _Service.CINDER,
|
||||
|
||||
@@ -729,24 +729,6 @@ class Monasca(OSClient):
|
||||
return client
|
||||
|
||||
|
||||
@configure("senlin", default_version="1", default_service_type="clustering",
|
||||
supported_versions=["1"])
|
||||
class Senlin(OSClient):
|
||||
"""Wrapper for SenlinClient which returns an authenticated native client.
|
||||
|
||||
"""
|
||||
|
||||
def create_client(self, version=None, service_type=None):
|
||||
"""Return senlin client."""
|
||||
from senlinclient import client as senlin
|
||||
|
||||
return senlin.Client(
|
||||
self.choose_version(version),
|
||||
**self._get_auth_info(project_name_key="project_name",
|
||||
cacert_key="cert",
|
||||
endpoint_type="interface"))
|
||||
|
||||
|
||||
@configure("magnum", default_version="1", supported_versions=["1"],
|
||||
default_service_type="container-infra",)
|
||||
class Magnum(OSClient):
|
||||
|
||||
@@ -99,42 +99,6 @@ class HeatStack(base.ResourceManager):
|
||||
return self.raw_resource.stack_name
|
||||
|
||||
|
||||
# SENLIN
|
||||
|
||||
_senlin_order = get_order(150)
|
||||
|
||||
|
||||
@base.resource(service=None, resource=None, admin_required=True)
|
||||
class SenlinMixin(base.ResourceManager):
|
||||
|
||||
def id(self):
|
||||
return self.raw_resource["id"]
|
||||
|
||||
def _manager(self):
|
||||
client = self._admin_required and self.admin or self.user
|
||||
return getattr(client, self._service)()
|
||||
|
||||
def list(self):
|
||||
return getattr(self._manager(), self._resource)()
|
||||
|
||||
def delete(self):
|
||||
# make singular form of resource name from plural form
|
||||
res_name = self._resource[:-1]
|
||||
return getattr(self._manager(), "delete_%s" % res_name)(self.id())
|
||||
|
||||
|
||||
@base.resource("senlin", "clusters",
|
||||
admin_required=True, order=next(_senlin_order))
|
||||
class SenlinCluster(SenlinMixin):
|
||||
"""Resource class for Senlin Cluster."""
|
||||
|
||||
|
||||
@base.resource("senlin", "profiles", order=next(_senlin_order),
|
||||
admin_required=False, tenant_resource=True)
|
||||
class SenlinProfile(SenlinMixin):
|
||||
"""Resource class for Senlin Profile."""
|
||||
|
||||
|
||||
# NOVA
|
||||
|
||||
_nova_order = get_order(200)
|
||||
|
||||
@@ -1,65 +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 rally.common import validation
|
||||
|
||||
from rally_openstack.common import consts
|
||||
from rally_openstack.task import context
|
||||
from rally_openstack.task.scenarios.senlin import utils as senlin_utils
|
||||
|
||||
|
||||
@validation.add("required_platform", platform="openstack", users=True)
|
||||
@context.configure(name="profiles", platform="openstack", order=190)
|
||||
class ProfilesGenerator(context.OpenStackContext):
|
||||
"""Context creates a temporary profile for Senlin test."""
|
||||
|
||||
CONFIG_SCHEMA = {
|
||||
"type": "object",
|
||||
"$schema": consts.JSON_SCHEMA,
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"additionalProperties": True,
|
||||
}
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"required": ["type", "version", "properties"]
|
||||
}
|
||||
|
||||
def setup(self):
|
||||
"""Create test profiles."""
|
||||
for user, tenant_id in self._iterate_per_tenants():
|
||||
|
||||
senlin_scenario = senlin_utils.SenlinScenario({
|
||||
"user": user,
|
||||
"task": self.context["task"]
|
||||
})
|
||||
profile = senlin_scenario._create_profile(self.config)
|
||||
|
||||
self.context["tenants"][tenant_id]["profile"] = profile.id
|
||||
|
||||
def cleanup(self):
|
||||
"""Delete created test profiles."""
|
||||
for user, tenant_id in self._iterate_per_tenants():
|
||||
|
||||
senlin_scenario = senlin_utils.SenlinScenario({
|
||||
"user": user,
|
||||
"task": self.context["task"]
|
||||
})
|
||||
senlin_scenario._delete_profile(
|
||||
self.context["tenants"][tenant_id]["profile"])
|
||||
@@ -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 rally.task import validation
|
||||
|
||||
from rally_openstack.common import consts
|
||||
from rally_openstack.task import scenario
|
||||
from rally_openstack.task.scenarios.senlin import utils
|
||||
|
||||
|
||||
"""Scenarios for Senlin clusters."""
|
||||
|
||||
|
||||
@validation.add("required_platform", platform="openstack", admin=True)
|
||||
@validation.add("required_services", services=[consts.Service.SENLIN])
|
||||
@validation.add("required_contexts", contexts=("profiles"))
|
||||
@scenario.configure(context={"admin_cleanup@openstack": ["senlin"]},
|
||||
name="SenlinClusters.create_and_delete_cluster",
|
||||
platform="openstack")
|
||||
class CreateAndDeleteCluster(utils.SenlinScenario):
|
||||
|
||||
def run(self, desired_capacity=0, min_size=0,
|
||||
max_size=-1, timeout=3600, metadata=None):
|
||||
"""Create a cluster and then delete it.
|
||||
|
||||
Measure the "senlin cluster-create" and "senlin cluster-delete"
|
||||
commands performance.
|
||||
|
||||
:param desired_capacity: The capacity or initial number of nodes
|
||||
owned by the cluster
|
||||
:param min_size: The minimum number of nodes owned by the cluster
|
||||
:param max_size: The maximum number of nodes owned by the cluster.
|
||||
-1 means no limit
|
||||
:param timeout: The timeout value in seconds for cluster creation
|
||||
:param metadata: A set of key value pairs to associate with the cluster
|
||||
"""
|
||||
|
||||
profile_id = self.context["tenant"]["profile"]
|
||||
cluster = self._create_cluster(profile_id, desired_capacity,
|
||||
min_size, max_size, timeout, metadata)
|
||||
self._delete_cluster(cluster)
|
||||
@@ -1,145 +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 rally.common import cfg
|
||||
from rally import exceptions
|
||||
from rally.task import atomic
|
||||
from rally.task import utils
|
||||
|
||||
from rally_openstack.task import scenario
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class SenlinScenario(scenario.OpenStackScenario):
|
||||
"""Base class for Senlin scenarios with basic atomic actions."""
|
||||
|
||||
@atomic.action_timer("senlin.list_clusters")
|
||||
def _list_clusters(self, **queries):
|
||||
"""Return user cluster list.
|
||||
|
||||
:param kwargs **queries: Optional query parameters to be sent to
|
||||
restrict the clusters to be returned. Available parameters include:
|
||||
|
||||
* name: The name of a cluster.
|
||||
* status: The current status of a cluster.
|
||||
* sort: A list of sorting keys separated by commas. Each sorting
|
||||
key can optionally be attached with a sorting direction
|
||||
modifier which can be ``asc`` or ``desc``.
|
||||
* limit: Requests a specified size of returned items from the
|
||||
query. Returns a number of items up to the specified limit
|
||||
value.
|
||||
* marker: Specifies the ID of the last-seen item. Use the limit
|
||||
parameter to make an initial limited request and use the ID of
|
||||
the last-seen item from the response as the marker parameter
|
||||
value in a subsequent limited request.
|
||||
* global_project: A boolean value indicating whether clusters
|
||||
from all projects will be returned.
|
||||
|
||||
:returns: list of clusters according to query.
|
||||
"""
|
||||
return list(self.admin_clients("senlin").clusters(**queries))
|
||||
|
||||
@atomic.action_timer("senlin.create_cluster")
|
||||
def _create_cluster(self, profile_id, desired_capacity=0, min_size=0,
|
||||
max_size=-1, timeout=60, metadata=None):
|
||||
"""Create a new cluster from attributes.
|
||||
|
||||
:param profile_id: ID of profile used to create cluster
|
||||
:param desired_capacity: The capacity or initial number of nodes
|
||||
owned by the cluster
|
||||
:param min_size: The minimum number of nodes owned by the cluster
|
||||
:param max_size: The maximum number of nodes owned by the cluster.
|
||||
-1 means no limit
|
||||
:param timeout: The timeout value in minutes for cluster creation
|
||||
:param metadata: A set of key value pairs to associate with the cluster
|
||||
|
||||
:returns: object of cluster created.
|
||||
"""
|
||||
attrs = {
|
||||
"profile_id": profile_id,
|
||||
"name": self.generate_random_name(),
|
||||
"desired_capacity": desired_capacity,
|
||||
"min_size": min_size,
|
||||
"max_size": max_size,
|
||||
"metadata": metadata,
|
||||
"timeout": timeout
|
||||
}
|
||||
|
||||
cluster = self.admin_clients("senlin").create_cluster(**attrs)
|
||||
cluster = utils.wait_for_status(
|
||||
cluster,
|
||||
ready_statuses=["ACTIVE"],
|
||||
failure_statuses=["ERROR"],
|
||||
update_resource=self._get_cluster,
|
||||
timeout=CONF.openstack.senlin_action_timeout)
|
||||
|
||||
return cluster
|
||||
|
||||
def _get_cluster(self, cluster):
|
||||
"""Get cluster details.
|
||||
|
||||
:param cluster: cluster to get
|
||||
|
||||
:returns: object of cluster
|
||||
"""
|
||||
try:
|
||||
return self.admin_clients("senlin").get_cluster(cluster.id)
|
||||
except Exception as e:
|
||||
if getattr(e, "code", getattr(e, "http_status", 400)) == 404:
|
||||
raise exceptions.GetResourceNotFound(resource=cluster.id)
|
||||
raise exceptions.GetResourceFailure(resource=cluster.id, err=e)
|
||||
|
||||
@atomic.action_timer("senlin.delete_cluster")
|
||||
def _delete_cluster(self, cluster):
|
||||
"""Delete given cluster.
|
||||
|
||||
Returns after the cluster is successfully deleted.
|
||||
|
||||
:param cluster: cluster object to delete
|
||||
"""
|
||||
self.admin_clients("senlin").delete_cluster(cluster)
|
||||
utils.wait_for_status(
|
||||
cluster,
|
||||
ready_statuses=["DELETED"],
|
||||
failure_statuses=["ERROR"],
|
||||
check_deletion=True,
|
||||
update_resource=self._get_cluster,
|
||||
timeout=CONF.openstack.senlin_action_timeout)
|
||||
|
||||
@atomic.action_timer("senlin.create_profile")
|
||||
def _create_profile(self, spec, metadata=None):
|
||||
"""Create a new profile from attributes.
|
||||
|
||||
:param spec: spec dictionary used to create profile
|
||||
:param metadata: A set of key value pairs to associate with the
|
||||
profile
|
||||
|
||||
:returns: object of profile created
|
||||
"""
|
||||
attrs = {"spec": spec,
|
||||
"name": self.generate_random_name()}
|
||||
if metadata:
|
||||
attrs["metadata"] = metadata
|
||||
|
||||
return self.clients("senlin").create_profile(**attrs)
|
||||
|
||||
@atomic.action_timer("senlin.delete_profile")
|
||||
def _delete_profile(self, profile):
|
||||
"""Delete given profile.
|
||||
|
||||
Returns after the profile is successfully deleted.
|
||||
|
||||
:param profile: profile object to be deleted
|
||||
"""
|
||||
self.clients("senlin").delete_profile(profile)
|
||||
@@ -18,7 +18,6 @@ from rally.common import utils
|
||||
|
||||
class _TempestApiTestSets(utils.ImmutableMixin, utils.EnumMixin):
|
||||
BAREMETAL = "baremetal"
|
||||
CLUSTERING = "clustering"
|
||||
COMPUTE = "compute"
|
||||
DATABASE = "database"
|
||||
IDENTITY = "identity"
|
||||
|
||||
@@ -25,7 +25,6 @@ python-monascaclient # Apache Software License
|
||||
python-neutronclient # Apache Software License
|
||||
python-novaclient # Apache License, Version 2.0
|
||||
python-octaviaclient # Apache Software License
|
||||
python-senlinclient # Apache Software License
|
||||
python-swiftclient # Apache License, Version 2.0
|
||||
python-troveclient # Apache Software License
|
||||
python-watcherclient # Apache Software License
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"Dummy.openstack": [
|
||||
{
|
||||
"args": {
|
||||
"sleep": 0.1
|
||||
},
|
||||
"runner": {
|
||||
"type": "constant",
|
||||
"times": 3,
|
||||
"concurrency": 1
|
||||
},
|
||||
"context": {
|
||||
"users": {
|
||||
"tenants": 1,
|
||||
"users_per_tenant": 1
|
||||
},
|
||||
"profiles": {
|
||||
"type": "os.nova.server",
|
||||
"version": "1.0",
|
||||
"properties": {
|
||||
"name": "cirros_server",
|
||||
"flavor": 1,
|
||||
"image": "cirros-0.5.2-x86_64-disk",
|
||||
"networks": [
|
||||
{ "network": "private" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
Dummy.openstack:
|
||||
-
|
||||
args:
|
||||
sleep: 0.1
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 3
|
||||
concurrency: 1
|
||||
context:
|
||||
users:
|
||||
tenants: 1
|
||||
users_per_tenant: 1
|
||||
profiles:
|
||||
type: "os.nova.server"
|
||||
version: "1.0"
|
||||
properties:
|
||||
name: "cirros_server"
|
||||
flavor: 1
|
||||
image: "cirros-0.5.2-x86_64-disk"
|
||||
networks:
|
||||
- network: "private"
|
||||
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"SenlinClusters.create_and_delete_cluster": [
|
||||
{
|
||||
"args": {
|
||||
"desired_capacity": 3,
|
||||
"min_size": 0,
|
||||
"max_size": 5
|
||||
},
|
||||
"runner": {
|
||||
"type": "constant",
|
||||
"times": 3,
|
||||
"concurrency": 1
|
||||
},
|
||||
"context": {
|
||||
"users": {
|
||||
"tenants": 1,
|
||||
"users_per_tenant": 1
|
||||
},
|
||||
"profiles": {
|
||||
"type": "os.nova.server",
|
||||
"version": "1.0",
|
||||
"properties": {
|
||||
"name": "cirros_server",
|
||||
"flavor": 1,
|
||||
"image": "cirros-0.5.2-x86_64-disk",
|
||||
"networks": [
|
||||
{ "network": "private" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"sla": {
|
||||
"failure_rate": {
|
||||
"max": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
SenlinClusters.create_and_delete_cluster:
|
||||
-
|
||||
args:
|
||||
desired_capacity: 3
|
||||
min_size: 0
|
||||
max_size: 5
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 3
|
||||
concurrency: 1
|
||||
context:
|
||||
users:
|
||||
tenants: 1
|
||||
users_per_tenant: 1
|
||||
profiles:
|
||||
type: os.nova.server
|
||||
version: "1.0"
|
||||
properties:
|
||||
name: cirros_server
|
||||
flavor: 1
|
||||
image: "cirros-0.5.2-x86_64-disk"
|
||||
networks:
|
||||
- network: private
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
@@ -279,17 +279,6 @@ class Cinder(ResourceManager):
|
||||
return self.client.qos_specs.list()
|
||||
|
||||
|
||||
class Senlin(ResourceManager):
|
||||
|
||||
REQUIRED_SERVICE = consts.Service.SENLIN
|
||||
|
||||
def list_clusters(self):
|
||||
return self.client.clusters()
|
||||
|
||||
def list_profiles(self):
|
||||
return self.client.profiles()
|
||||
|
||||
|
||||
class Manila(ResourceManager):
|
||||
|
||||
REQUIRED_SERVICE = consts.Service.MANILA
|
||||
|
||||
@@ -904,23 +904,6 @@ class OSClientsTestCase(test.TestCase):
|
||||
key += "%s" % {"version": version}
|
||||
self.assertEqual(fake_designate, self.clients.cache[key])
|
||||
|
||||
def test_senlin(self):
|
||||
mock_senlin = mock.MagicMock()
|
||||
self.assertNotIn("senlin", self.clients.cache)
|
||||
with mock.patch.dict("sys.modules", {"senlinclient": mock_senlin}):
|
||||
client = self.clients.senlin()
|
||||
self.assertEqual(mock_senlin.client.Client.return_value, client)
|
||||
mock_senlin.client.Client.assert_called_once_with(
|
||||
"1",
|
||||
username=self.credential.username,
|
||||
password=self.credential.password,
|
||||
project_name=self.credential.tenant_name,
|
||||
cert=self.credential.cacert,
|
||||
auth_url=self.credential.auth_url)
|
||||
self.assertEqual(
|
||||
mock_senlin.client.Client.return_value,
|
||||
self.clients.cache["senlin"])
|
||||
|
||||
@mock.patch("%s.Magnum._get_endpoint" % PATH)
|
||||
def test_magnum(self, mock_magnum__get_endpoint):
|
||||
fake_magnum = fakes.FakeMagnumClient()
|
||||
|
||||
@@ -1441,13 +1441,6 @@ class FakeEC2Client(object):
|
||||
pass
|
||||
|
||||
|
||||
class FakeSenlinClient(object):
|
||||
|
||||
def __init__(self):
|
||||
# TODO(Yanyan Hu):Fake interfaces of senlinclient.
|
||||
pass
|
||||
|
||||
|
||||
class FakeMagnumClient(object):
|
||||
|
||||
def __init__(self):
|
||||
@@ -1484,7 +1477,6 @@ class FakeClients(object):
|
||||
self._swift = None
|
||||
self._monasca = None
|
||||
self._ec2 = None
|
||||
self._senlin = None
|
||||
self._watcher = None
|
||||
self._barbican = None
|
||||
self._credential = credential_ or FakeCredential(
|
||||
@@ -1566,11 +1558,6 @@ class FakeClients(object):
|
||||
self._ec2 = FakeEC2Client()
|
||||
return self._ec2
|
||||
|
||||
def senlin(self):
|
||||
if not self._senlin:
|
||||
self._senlin = FakeSenlinClient()
|
||||
return self._senlin
|
||||
|
||||
def watcher(self):
|
||||
if not self._watcher:
|
||||
self._watcher = FakeWatcherClient()
|
||||
|
||||
@@ -911,44 +911,6 @@ class MistralExecutionsTestCase(test.TestCase):
|
||||
self.assertEqual("bar", resources.MistralExecutions(execution).name())
|
||||
|
||||
|
||||
class SenlinMixinTestCase(test.TestCase):
|
||||
|
||||
def test_id(self):
|
||||
senlin = resources.SenlinMixin()
|
||||
senlin.raw_resource = {"id": "TEST_ID"}
|
||||
self.assertEqual("TEST_ID", senlin.id())
|
||||
|
||||
def test__manager(self):
|
||||
senlin = resources.SenlinMixin()
|
||||
senlin._service = "senlin"
|
||||
senlin.user = mock.MagicMock()
|
||||
self.assertEqual(senlin.user.senlin.return_value, senlin._manager())
|
||||
|
||||
def test_list(self):
|
||||
senlin = resources.SenlinMixin()
|
||||
senlin._service = "senlin"
|
||||
senlin.user = mock.MagicMock()
|
||||
senlin._resource = "some_resources"
|
||||
|
||||
some_resources = [{"name": "resource1"}, {"name": "resource2"}]
|
||||
senlin.user.senlin().some_resources.return_value = some_resources
|
||||
|
||||
self.assertEqual(some_resources, senlin.list())
|
||||
senlin.user.senlin().some_resources.assert_called_once_with()
|
||||
|
||||
def test_delete(self):
|
||||
senlin = resources.SenlinMixin()
|
||||
senlin._service = "senlin"
|
||||
senlin.user = mock.MagicMock()
|
||||
senlin._resource = "some_resources"
|
||||
senlin.raw_resource = {"id": "TEST_ID"}
|
||||
senlin.user.senlin().delete_some_resource.return_value = None
|
||||
|
||||
senlin.delete()
|
||||
senlin.user.senlin().delete_some_resource.assert_called_once_with(
|
||||
"TEST_ID")
|
||||
|
||||
|
||||
class WatcherTemplateTestCase(test.TestCase):
|
||||
|
||||
def test_id(self):
|
||||
|
||||
@@ -1,84 +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 unittest import mock
|
||||
|
||||
from rally_openstack.task.contexts.senlin import profiles
|
||||
from tests.unit import test
|
||||
|
||||
|
||||
BASE_CTX = "rally.task.context"
|
||||
CTX = "rally_openstack.context"
|
||||
BASE_SCN = "rally.task.scenarios"
|
||||
SCN = "rally_openstack.task.scenarios"
|
||||
|
||||
|
||||
class ProfilesGeneratorTestCase(test.ScenarioTestCase):
|
||||
"""Generate tenants."""
|
||||
def _gen_tenants(self, count):
|
||||
tenants = {}
|
||||
for _id in range(count):
|
||||
tenants[str(_id)] = {"id": str(_id)}
|
||||
return tenants
|
||||
|
||||
def setUp(self):
|
||||
super(ProfilesGeneratorTestCase, self).setUp()
|
||||
self.tenants_count = 2
|
||||
self.users_per_tenant = 3
|
||||
tenants = self._gen_tenants(self.tenants_count)
|
||||
users = []
|
||||
for tenant in tenants:
|
||||
for i in range(self.users_per_tenant):
|
||||
users.append({"id": i, "tenant_id": tenant,
|
||||
"credential": mock.MagicMock()})
|
||||
|
||||
self.context = {
|
||||
"config": {
|
||||
"users": {
|
||||
"tenants": self.tenants_count,
|
||||
"users_per_tenant": self.users_per_tenant
|
||||
},
|
||||
"profiles": {
|
||||
"type": "profile_type_name",
|
||||
"version": "1.0",
|
||||
"properties": {"k1": "v1", "k2": "v2"}
|
||||
},
|
||||
},
|
||||
"users": users,
|
||||
"tenants": tenants,
|
||||
"task": mock.MagicMock()
|
||||
}
|
||||
|
||||
@mock.patch("%s.senlin.utils.SenlinScenario._create_profile" % SCN,
|
||||
return_value=mock.MagicMock(id="TEST_PROFILE_ID"))
|
||||
def test_setup(self, mock_senlin_scenario__create_profile):
|
||||
profile_ctx = profiles.ProfilesGenerator(self.context)
|
||||
profile_ctx.setup()
|
||||
spec = self.context["config"]["profiles"]
|
||||
|
||||
mock_calls = [mock.call(spec) for i in range(self.tenants_count)]
|
||||
mock_senlin_scenario__create_profile.assert_has_calls(mock_calls)
|
||||
|
||||
for tenant in self.context["tenants"]:
|
||||
self.assertEqual("TEST_PROFILE_ID",
|
||||
self.context["tenants"][tenant]["profile"])
|
||||
|
||||
@mock.patch("%s.senlin.utils.SenlinScenario._delete_profile" % SCN)
|
||||
def test_cleanup(self, mock_senlin_scenario__delete_profile):
|
||||
for tenant in self.context["tenants"]:
|
||||
self.context["tenants"][tenant].update(
|
||||
{"profile": "TEST_PROFILE_ID"})
|
||||
profile_ctx = profiles.ProfilesGenerator(self.context)
|
||||
profile_ctx.cleanup()
|
||||
mock_calls = [mock.call("TEST_PROFILE_ID") for i in range(
|
||||
self.tenants_count)]
|
||||
mock_senlin_scenario__delete_profile.assert_has_calls(mock_calls)
|
||||
@@ -1,34 +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 unittest import mock
|
||||
|
||||
from rally_openstack.task.scenarios.senlin import clusters
|
||||
from tests.unit import test
|
||||
|
||||
|
||||
class SenlinClustersTestCase(test.ScenarioTestCase):
|
||||
|
||||
def test_create_and_delete_cluster(self):
|
||||
mock_cluster = mock.Mock()
|
||||
self.context["tenant"] = {"profile": "fake_profile_id"}
|
||||
scenario = clusters.CreateAndDeleteCluster(self.context)
|
||||
scenario._create_cluster = mock.Mock(return_value=mock_cluster)
|
||||
scenario._delete_cluster = mock.Mock()
|
||||
|
||||
scenario.run(desired_capacity=1, min_size=0,
|
||||
max_size=3, timeout=60, metadata={"k2": "v2"})
|
||||
|
||||
scenario._create_cluster.assert_called_once_with("fake_profile_id",
|
||||
1, 0, 3, 60,
|
||||
{"k2": "v2"})
|
||||
scenario._delete_cluster.assert_called_once_with(mock_cluster)
|
||||
@@ -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 unittest import mock
|
||||
|
||||
from rally.common import cfg
|
||||
from rally import exceptions
|
||||
|
||||
from rally_openstack.task.scenarios.senlin import utils
|
||||
from tests.unit import test
|
||||
|
||||
SENLIN_UTILS = "rally_openstack.task.scenarios.senlin.utils."
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class SenlinScenarioTestCase(test.ScenarioTestCase):
|
||||
|
||||
def test_list_cluster(self):
|
||||
fake_cluster_list = ["cluster1", "cluster2"]
|
||||
self.admin_clients("senlin").clusters.return_value = fake_cluster_list
|
||||
scenario = utils.SenlinScenario(self.context)
|
||||
result = scenario._list_clusters()
|
||||
|
||||
self.assertEqual(list(fake_cluster_list), result)
|
||||
self.admin_clients("senlin").clusters.assert_called_once_with()
|
||||
|
||||
def test_list_cluster_with_queries(self):
|
||||
fake_cluster_list = ["cluster1", "cluster2"]
|
||||
self.admin_clients("senlin").clusters.return_value = fake_cluster_list
|
||||
scenario = utils.SenlinScenario(self.context)
|
||||
result = scenario._list_clusters(status="ACTIVE")
|
||||
|
||||
self.assertEqual(list(fake_cluster_list), result)
|
||||
self.admin_clients("senlin").clusters.assert_called_once_with(
|
||||
status="ACTIVE")
|
||||
|
||||
@mock.patch(SENLIN_UTILS + "SenlinScenario.generate_random_name",
|
||||
return_value="test_cluster")
|
||||
def test_create_cluster(self, mock_generate_random_name):
|
||||
fake_cluster = mock.Mock(id="fake_cluster_id")
|
||||
res_cluster = mock.Mock()
|
||||
self.admin_clients("senlin").create_cluster.return_value = fake_cluster
|
||||
self.mock_wait_for_status.mock.return_value = res_cluster
|
||||
scenario = utils.SenlinScenario(self.context)
|
||||
result = scenario._create_cluster("fake_profile_id",
|
||||
desired_capacity=1,
|
||||
min_size=0,
|
||||
max_size=3,
|
||||
metadata={"k1": "v1"},
|
||||
timeout=60)
|
||||
|
||||
self.assertEqual(res_cluster, result)
|
||||
self.admin_clients("senlin").create_cluster.assert_called_once_with(
|
||||
profile_id="fake_profile_id", name="test_cluster",
|
||||
desired_capacity=1, min_size=0, max_size=3, metadata={"k1": "v1"},
|
||||
timeout=60)
|
||||
self.mock_wait_for_status.mock.assert_called_once_with(
|
||||
fake_cluster, ready_statuses=["ACTIVE"],
|
||||
failure_statuses=["ERROR"],
|
||||
update_resource=scenario._get_cluster,
|
||||
timeout=CONF.openstack.senlin_action_timeout)
|
||||
mock_generate_random_name.assert_called_once_with()
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"senlin.create_cluster")
|
||||
|
||||
def test_get_cluster(self):
|
||||
fake_cluster = mock.Mock(id="fake_cluster_id")
|
||||
scenario = utils.SenlinScenario(context=self.context)
|
||||
scenario._get_cluster(fake_cluster)
|
||||
|
||||
self.admin_clients("senlin").get_cluster.assert_called_once_with(
|
||||
"fake_cluster_id")
|
||||
|
||||
def test_get_cluster_notfound(self):
|
||||
fake_cluster = mock.Mock(id="fake_cluster_id")
|
||||
ex = Exception()
|
||||
ex.code = 404
|
||||
self.admin_clients("senlin").get_cluster.side_effect = ex
|
||||
scenario = utils.SenlinScenario(context=self.context)
|
||||
|
||||
self.assertRaises(exceptions.GetResourceNotFound,
|
||||
scenario._get_cluster,
|
||||
fake_cluster)
|
||||
self.admin_clients("senlin").get_cluster.assert_called_once_with(
|
||||
"fake_cluster_id")
|
||||
|
||||
def test_get_cluster_failed(self):
|
||||
fake_cluster = mock.Mock(id="fake_cluster_id")
|
||||
ex = Exception()
|
||||
ex.code = 500
|
||||
self.admin_clients("senlin").get_cluster.side_effect = ex
|
||||
scenario = utils.SenlinScenario(context=self.context)
|
||||
|
||||
self.assertRaises(exceptions.GetResourceFailure,
|
||||
scenario._get_cluster,
|
||||
fake_cluster)
|
||||
self.admin_clients("senlin").get_cluster.assert_called_once_with(
|
||||
"fake_cluster_id")
|
||||
|
||||
def test_delete_cluster(self):
|
||||
fake_cluster = mock.Mock()
|
||||
scenario = utils.SenlinScenario(context=self.context)
|
||||
scenario._delete_cluster(fake_cluster)
|
||||
|
||||
self.admin_clients("senlin").delete_cluster.assert_called_once_with(
|
||||
fake_cluster)
|
||||
self.mock_wait_for_status.mock.assert_called_once_with(
|
||||
fake_cluster, ready_statuses=["DELETED"],
|
||||
failure_statuses=["ERROR"], check_deletion=True,
|
||||
update_resource=scenario._get_cluster,
|
||||
timeout=CONF.openstack.senlin_action_timeout)
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"senlin.delete_cluster")
|
||||
|
||||
@mock.patch(SENLIN_UTILS + "SenlinScenario.generate_random_name",
|
||||
return_value="test_profile")
|
||||
def test_create_profile(self, mock_generate_random_name):
|
||||
test_spec = {
|
||||
"version": "1.0",
|
||||
"type": "test_type",
|
||||
"properties": {
|
||||
"key1": "value1"
|
||||
}
|
||||
}
|
||||
scenario = utils.SenlinScenario(self.context)
|
||||
result = scenario._create_profile(test_spec, metadata={"k2": "v2"})
|
||||
|
||||
self.assertEqual(
|
||||
self.clients("senlin").create_profile.return_value, result)
|
||||
self.clients("senlin").create_profile.assert_called_once_with(
|
||||
spec=test_spec, name="test_profile", metadata={"k2": "v2"})
|
||||
mock_generate_random_name.assert_called_once_with()
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"senlin.create_profile")
|
||||
|
||||
def test_delete_profile(self):
|
||||
fake_profile = mock.Mock()
|
||||
scenario = utils.SenlinScenario(context=self.context)
|
||||
scenario._delete_profile(fake_profile)
|
||||
|
||||
self.clients("senlin").delete_profile.assert_called_once_with(
|
||||
fake_profile)
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"senlin.delete_profile")
|
||||
@@ -82,7 +82,6 @@ python-neutronclient===11.2.0
|
||||
python-novaclient===18.6.0
|
||||
python-octaviaclient===3.7.0
|
||||
python-openstackclient===6.6.0
|
||||
python-senlinclient===3.1.0
|
||||
python-subunit===1.4.4
|
||||
python-swiftclient===4.5.0
|
||||
python-troveclient===8.4.0
|
||||
|
||||
Reference in New Issue
Block a user