Add designate support with domain scenarios
*) Add designate client *) Add designate cleanup *) Add domain benchmarks Change-Id: I4d791411487788ba157f60c3f99aa48bf237b10b
This commit is contained in:
parent
d091b3bfc8
commit
e8d8099d4d
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"DesignateBasic.create_and_delete_domain": [
|
||||||
|
{
|
||||||
|
"runner": {
|
||||||
|
"type": "constant",
|
||||||
|
"times": 3,
|
||||||
|
"concurrency": 2
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"users": {
|
||||||
|
"tenants": 2,
|
||||||
|
"users_per_tenant": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
DesignateBasic.create_and_delete_domain:
|
||||||
|
-
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 3
|
||||||
|
concurrency: 2
|
||||||
|
context:
|
||||||
|
users:
|
||||||
|
tenants: 2
|
||||||
|
users_per_tenant: 2
|
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"DesignateBasic.create_and_list_domains": [
|
||||||
|
{
|
||||||
|
"runner": {
|
||||||
|
"type": "constant",
|
||||||
|
"times": 3,
|
||||||
|
"concurrency": 2
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"users": {
|
||||||
|
"tenants": 2,
|
||||||
|
"users_per_tenant": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
DesignateBasic.create_and_list_domains:
|
||||||
|
-
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 3
|
||||||
|
concurrency: 2
|
||||||
|
context:
|
||||||
|
users:
|
||||||
|
tenants: 2
|
||||||
|
users_per_tenant: 2
|
17
doc/samples/tasks/scenarios/designate/list-domains.json
Normal file
17
doc/samples/tasks/scenarios/designate/list-domains.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"DesignateBasic.list_domains": [
|
||||||
|
{
|
||||||
|
"runner": {
|
||||||
|
"type": "constant",
|
||||||
|
"times": 3,
|
||||||
|
"concurrency": 2
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"users": {
|
||||||
|
"tenants": 2,
|
||||||
|
"users_per_tenant": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
11
doc/samples/tasks/scenarios/designate/list-domains.yaml
Normal file
11
doc/samples/tasks/scenarios/designate/list-domains.yaml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
DesignateBasic.list_domains:
|
||||||
|
-
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 3
|
||||||
|
concurrency: 2
|
||||||
|
context:
|
||||||
|
users:
|
||||||
|
tenants: 2
|
||||||
|
users_per_tenant: 2
|
@ -41,7 +41,7 @@ class UserCleanup(base.Context):
|
|||||||
"items": {
|
"items": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["nova", "glance", "cinder",
|
"enum": ["nova", "glance", "cinder",
|
||||||
"neutron", "ceilometer", "heat", "sahara"]
|
"neutron", "ceilometer", "heat", "sahara", "designate"]
|
||||||
},
|
},
|
||||||
"uniqueItems": True
|
"uniqueItems": True
|
||||||
}
|
}
|
||||||
@ -64,7 +64,9 @@ class UserCleanup(base.Context):
|
|||||||
"ceilometer": (utils.delete_ceilometer_resources,
|
"ceilometer": (utils.delete_ceilometer_resources,
|
||||||
clients.ceilometer, tenant_id),
|
clients.ceilometer, tenant_id),
|
||||||
"heat": (utils.delete_heat_resources, clients.heat),
|
"heat": (utils.delete_heat_resources, clients.heat),
|
||||||
"sahara": (utils.delete_sahara_resources, clients.sahara)
|
"sahara": (utils.delete_sahara_resources, clients.sahara),
|
||||||
|
"designate": (utils.delete_designate_resources,
|
||||||
|
clients.designate),
|
||||||
}
|
}
|
||||||
|
|
||||||
for service_name in self.config:
|
for service_name in self.config:
|
||||||
|
@ -154,6 +154,11 @@ def delete_neutron_resources(neutron, project_uuid):
|
|||||||
neutron.delete_network(network["id"])
|
neutron.delete_network(network["id"])
|
||||||
|
|
||||||
|
|
||||||
|
def delete_designate_resources(designate):
|
||||||
|
for domain in designate.domains.list():
|
||||||
|
designate.domains.delete(domain.id)
|
||||||
|
|
||||||
|
|
||||||
def delete_ceilometer_resources(ceilometer, project_uuid):
|
def delete_ceilometer_resources(ceilometer, project_uuid):
|
||||||
delete_alarms(ceilometer, project_uuid)
|
delete_alarms(ceilometer, project_uuid)
|
||||||
|
|
||||||
|
0
rally/benchmark/scenarios/designate/__init__.py
Normal file
0
rally/benchmark/scenarios/designate/__init__.py
Normal file
66
rally/benchmark/scenarios/designate/basic.py
Normal file
66
rally/benchmark/scenarios/designate/basic.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||||
|
#
|
||||||
|
# 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.benchmark.scenarios import base
|
||||||
|
from rally.benchmark.scenarios.designate import utils
|
||||||
|
from rally.benchmark import validation
|
||||||
|
from rally import consts
|
||||||
|
|
||||||
|
|
||||||
|
class DesignateBasic(utils.DesignateScenario):
|
||||||
|
|
||||||
|
@base.scenario(context={"cleanup": ["designate"]})
|
||||||
|
@validation.required_services(consts.Service.DESIGNATE)
|
||||||
|
def create_and_list_domains(self):
|
||||||
|
"""Tests creating a domain and listing domains.
|
||||||
|
|
||||||
|
This scenario is a very useful tool to measure
|
||||||
|
the "designate domain-list" command performance.
|
||||||
|
|
||||||
|
If you have only 1 user in your context, you will
|
||||||
|
add 1 domain on every iteration. So you will have more
|
||||||
|
and more domain and will be able to measure the
|
||||||
|
performance of the "designate domain-list" command depending on
|
||||||
|
the number of domains owned by users.
|
||||||
|
"""
|
||||||
|
self._create_domain()
|
||||||
|
self._list_domains()
|
||||||
|
|
||||||
|
@base.scenario(context={"cleanup": ["designate"]})
|
||||||
|
@validation.required_services(consts.Service.DESIGNATE)
|
||||||
|
def list_domains(self):
|
||||||
|
"""Test the designate domain-list command.
|
||||||
|
|
||||||
|
This simple scenario tests the designate domain-list command by listing
|
||||||
|
all the domains.
|
||||||
|
|
||||||
|
Suppose if we have 2 users in context and each has 2 domains
|
||||||
|
uploaded for them we will be able to test the performance of
|
||||||
|
designate domain-list command in this case.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self._list_domains()
|
||||||
|
|
||||||
|
@base.scenario(context={"cleanup": ["designate"]})
|
||||||
|
@validation.required_services(consts.Service.DESIGNATE)
|
||||||
|
def create_and_delete_domain(self):
|
||||||
|
"""Test adds and then deletes domain.
|
||||||
|
|
||||||
|
This is very useful to measure perfromance of creating and deleting
|
||||||
|
domains with different level of load.
|
||||||
|
"""
|
||||||
|
domain = self._create_domain()
|
||||||
|
self._delete_domain(domain['id'])
|
49
rally/benchmark/scenarios/designate/utils.py
Normal file
49
rally/benchmark/scenarios/designate/utils.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||||
|
#
|
||||||
|
# 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.benchmark.scenarios import base
|
||||||
|
|
||||||
|
|
||||||
|
class DesignateScenario(base.Scenario):
|
||||||
|
"""This class should contain base operations for benchmarking designate."""
|
||||||
|
|
||||||
|
RESOURCE_NAME_PREFIX = "rally_"
|
||||||
|
|
||||||
|
@base.atomic_action_timer('designate.create_domain')
|
||||||
|
def _create_domain(self, domain=None):
|
||||||
|
"""Create domain.
|
||||||
|
|
||||||
|
:param domain: dict, POST /v1/domains request options
|
||||||
|
:returns: designate domain dict
|
||||||
|
"""
|
||||||
|
domain = domain or {}
|
||||||
|
|
||||||
|
domain.setdefault('email', 'root@random.name')
|
||||||
|
domain.setdefault('name', '%s.name.' % self._generate_random_name())
|
||||||
|
return self.clients("designate").domains.create(domain)
|
||||||
|
|
||||||
|
@base.atomic_action_timer('designate.list_domains')
|
||||||
|
def _list_domains(self):
|
||||||
|
"""Return user domain list."""
|
||||||
|
return self.clients("designate").domains.list()
|
||||||
|
|
||||||
|
@base.atomic_action_timer('designate.delete_domain')
|
||||||
|
def _delete_domain(self, domain_id):
|
||||||
|
"""Delete designate zone.
|
||||||
|
|
||||||
|
:param domain: Domain object
|
||||||
|
"""
|
||||||
|
self.clients("designate").domains.delete(domain_id)
|
@ -28,6 +28,7 @@ TEMPEST_TEST_SETS = ("full",
|
|||||||
"smoke",
|
"smoke",
|
||||||
"baremetal",
|
"baremetal",
|
||||||
"compute",
|
"compute",
|
||||||
|
"dns",
|
||||||
"data_processing",
|
"data_processing",
|
||||||
"identity",
|
"identity",
|
||||||
"image",
|
"image",
|
||||||
@ -87,6 +88,7 @@ class _Service(utils.ImmutableMixin, utils.EnumMixin):
|
|||||||
HEAT = "heat"
|
HEAT = "heat"
|
||||||
KEYSTONE = "keystone"
|
KEYSTONE = "keystone"
|
||||||
NEUTRON = "neutron"
|
NEUTRON = "neutron"
|
||||||
|
DESIGNATE = "designate"
|
||||||
CEILOMETER = "ceilometer"
|
CEILOMETER = "ceilometer"
|
||||||
S3 = "s3"
|
S3 = "s3"
|
||||||
TROVE = "trove"
|
TROVE = "trove"
|
||||||
@ -106,6 +108,7 @@ class _ServiceType(utils.ImmutableMixin, utils.EnumMixin):
|
|||||||
COMPUTE = "compute"
|
COMPUTE = "compute"
|
||||||
COMPUTEV3 = "computev3"
|
COMPUTEV3 = "computev3"
|
||||||
NETWORK = "network"
|
NETWORK = "network"
|
||||||
|
DNS = "dns"
|
||||||
METERING = "metering"
|
METERING = "metering"
|
||||||
S3 = "s3"
|
S3 = "s3"
|
||||||
DATABASE = "database"
|
DATABASE = "database"
|
||||||
@ -123,6 +126,7 @@ class _ServiceType(utils.ImmutableMixin, utils.EnumMixin):
|
|||||||
self.ORCHESTRATION: _Service.HEAT,
|
self.ORCHESTRATION: _Service.HEAT,
|
||||||
self.IDENTITY: _Service.KEYSTONE,
|
self.IDENTITY: _Service.KEYSTONE,
|
||||||
self.NETWORK: _Service.NEUTRON,
|
self.NETWORK: _Service.NEUTRON,
|
||||||
|
self.DNS: _Service.DESIGNATE,
|
||||||
self.METERING: _Service.CEILOMETER,
|
self.METERING: _Service.CEILOMETER,
|
||||||
self.S3: _Service.S3,
|
self.S3: _Service.S3,
|
||||||
self.DATABASE: _Service.TROVE,
|
self.DATABASE: _Service.TROVE,
|
||||||
|
@ -17,6 +17,7 @@ import urlparse
|
|||||||
|
|
||||||
from ceilometerclient import client as ceilometer
|
from ceilometerclient import client as ceilometer
|
||||||
from cinderclient import client as cinder
|
from cinderclient import client as cinder
|
||||||
|
from designateclient import v1 as designate
|
||||||
import glanceclient as glance
|
import glanceclient as glance
|
||||||
from heatclient import client as heat
|
from heatclient import client as heat
|
||||||
from ironicclient import client as ironic
|
from ironicclient import client as ironic
|
||||||
@ -250,6 +251,19 @@ class Clients(object):
|
|||||||
|
|
||||||
return client
|
return client
|
||||||
|
|
||||||
|
@cached
|
||||||
|
def designate(self):
|
||||||
|
"""Return designate client."""
|
||||||
|
kc = self.keystone()
|
||||||
|
dns_api_url = kc.service_catalog.url_for(
|
||||||
|
service_type='dns', endpoint_type='public',
|
||||||
|
region_name=self.endpoint.region_name)
|
||||||
|
client = designate.Client(
|
||||||
|
endpoint=dns_api_url,
|
||||||
|
token=kc.auth_token,
|
||||||
|
insecure=CONF.https_insecure)
|
||||||
|
return client
|
||||||
|
|
||||||
@cached
|
@cached
|
||||||
def services(self):
|
def services(self):
|
||||||
"""Return available services names and types.
|
"""Return available services names and types.
|
||||||
|
@ -11,6 +11,7 @@ pbr>=0.6,!=0.7,<1.0
|
|||||||
pecan>=0.5.0
|
pecan>=0.5.0
|
||||||
PrettyTable>=0.7,<0.8
|
PrettyTable>=0.7,<0.8
|
||||||
PyYAML>=3.1.0
|
PyYAML>=3.1.0
|
||||||
|
python-designateclient>=1.0.0
|
||||||
python-glanceclient>=0.13.1
|
python-glanceclient>=0.13.1
|
||||||
python-keystoneclient>=0.10.0
|
python-keystoneclient>=0.10.0
|
||||||
python-novaclient>=2.17.0
|
python-novaclient>=2.17.0
|
||||||
|
0
tests/benchmark/scenarios/designate/__init__.py
Normal file
0
tests/benchmark/scenarios/designate/__init__.py
Normal file
56
tests/benchmark/scenarios/designate/test_basic.py
Normal file
56
tests/benchmark/scenarios/designate/test_basic.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||||
|
#
|
||||||
|
# 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 mock
|
||||||
|
|
||||||
|
from rally.benchmark.scenarios.designate import basic
|
||||||
|
from tests import test
|
||||||
|
|
||||||
|
DESIGNATE_BASIC = "rally.benchmark.scenarios.designate.basic.DesignateBasic"
|
||||||
|
|
||||||
|
|
||||||
|
class DesignateBasicTestCase(test.TestCase):
|
||||||
|
|
||||||
|
@mock.patch(DESIGNATE_BASIC + "._list_domains")
|
||||||
|
@mock.patch(DESIGNATE_BASIC + "._create_domain")
|
||||||
|
def test_create_and_list_networks(self, mock_create, mock_list):
|
||||||
|
scenario = basic.DesignateBasic()
|
||||||
|
|
||||||
|
# Default options
|
||||||
|
scenario.create_and_list_domains()
|
||||||
|
mock_create.assert_called_once_with()
|
||||||
|
mock_list.assert_called_once_with()
|
||||||
|
|
||||||
|
@mock.patch(DESIGNATE_BASIC + "._delete_domain")
|
||||||
|
@mock.patch(DESIGNATE_BASIC + "._create_domain")
|
||||||
|
def test_create_and_delete_domain(self, mock_create, mock_delete):
|
||||||
|
scenario = basic.DesignateBasic()
|
||||||
|
|
||||||
|
mock_create.return_value = {"id": "123"}
|
||||||
|
|
||||||
|
# Default options
|
||||||
|
scenario.create_and_delete_domain()
|
||||||
|
|
||||||
|
mock_create.assert_called_once_with()
|
||||||
|
mock_delete.assert_called_once_with("123")
|
||||||
|
|
||||||
|
@mock.patch(DESIGNATE_BASIC + "._list_domains")
|
||||||
|
def test_list_domains(self, mock_list):
|
||||||
|
scenario = basic.DesignateBasic()
|
||||||
|
|
||||||
|
# Default options
|
||||||
|
scenario.list_domains()
|
||||||
|
mock_list.assert_called_once_with()
|
84
tests/benchmark/scenarios/designate/test_utils.py
Normal file
84
tests/benchmark/scenarios/designate/test_utils.py
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||||
|
#
|
||||||
|
# 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 mock
|
||||||
|
|
||||||
|
from rally.benchmark.scenarios.designate import utils
|
||||||
|
from tests.benchmark.scenarios import test_base
|
||||||
|
from tests import test
|
||||||
|
|
||||||
|
|
||||||
|
DESIGNATE_UTILS = "rally.benchmark.scenarios.designate.utils."
|
||||||
|
|
||||||
|
|
||||||
|
class DesignateScenarioTestCase(test.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(DesignateScenarioTestCase, self).setUp()
|
||||||
|
self.domain = mock.Mock()
|
||||||
|
|
||||||
|
def _test_atomic_action_timer(self, atomic_actions_time, name):
|
||||||
|
action_duration = test_base.get_atomic_action_timer_value_by_name(
|
||||||
|
atomic_actions_time, name)
|
||||||
|
self.assertIsNotNone(action_duration)
|
||||||
|
self.assertIsInstance(action_duration, float)
|
||||||
|
|
||||||
|
@mock.patch(DESIGNATE_UTILS + 'DesignateScenario._generate_random_name')
|
||||||
|
@mock.patch(DESIGNATE_UTILS + 'DesignateScenario.clients')
|
||||||
|
def test_create_domain(self, mock_clients, mock_random_name):
|
||||||
|
scenario = utils.DesignateScenario()
|
||||||
|
|
||||||
|
random_name = "foo"
|
||||||
|
explicit_name = "bar.io."
|
||||||
|
email = "root@zone.name"
|
||||||
|
|
||||||
|
mock_random_name.return_value = random_name
|
||||||
|
mock_clients("designate").domains.create.return_value = self.domain
|
||||||
|
|
||||||
|
# Check that the defaults / randoms are used if nothing is specified
|
||||||
|
domain = scenario._create_domain()
|
||||||
|
mock_clients("designate").domains.create.assert_called_once_with(
|
||||||
|
{"email": "root@random.name", "name": '%s.name.' % random_name})
|
||||||
|
self.assertEqual(self.domain, domain)
|
||||||
|
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||||
|
'designate.create_domain')
|
||||||
|
|
||||||
|
mock_clients("designate").domains.create.reset_mock()
|
||||||
|
|
||||||
|
# Check that when specifying zone defaults are not used...
|
||||||
|
data = {"email": email, "name": explicit_name}
|
||||||
|
domain = scenario._create_domain(data)
|
||||||
|
mock_clients("designate").domains.create.assert_called_once_with(data)
|
||||||
|
self.assertEqual(self.domain, domain)
|
||||||
|
|
||||||
|
@mock.patch(DESIGNATE_UTILS + 'DesignateScenario.clients')
|
||||||
|
def test_list_domains(self, mock_clients):
|
||||||
|
scenario = utils.DesignateScenario()
|
||||||
|
domains_list = []
|
||||||
|
mock_clients("designate").domains.list.return_value = domains_list
|
||||||
|
return_domains_list = scenario._list_domains()
|
||||||
|
self.assertEqual(domains_list, return_domains_list)
|
||||||
|
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||||
|
'designate.list_domains')
|
||||||
|
|
||||||
|
@mock.patch(DESIGNATE_UTILS + 'DesignateScenario.clients')
|
||||||
|
def test_delete_domain(self, mock_clients):
|
||||||
|
scenario = utils.DesignateScenario()
|
||||||
|
|
||||||
|
domain = scenario._create_domain()
|
||||||
|
scenario._delete_domain(domain['id'])
|
||||||
|
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||||
|
'designate.delete_domain')
|
Loading…
Reference in New Issue
Block a user