Config manager
The path introduces the CloudConfigManager class, intended for easy conversion between python dictionary and configuration text file formats. The class also containing the defaults values for the cloud config hardcoded. CloudConfigManager inherits from the abstract ConfigManager; that's done in assumption that later another ConfigManager, namely TestConfigManager class will be developed. Blueprint test-engine Change-Id: I8ea61f18cedd6d586a6e9cf8ae73a34edabf4bb9
This commit is contained in:
parent
6ecc94ec7b
commit
ac4fc3b003
115
rally/benchmark/config.py
Normal file
115
rally/benchmark/config.py
Normal file
@ -0,0 +1,115 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# 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.
|
||||
|
||||
import abc
|
||||
import ConfigParser
|
||||
|
||||
|
||||
class ConfigManager(ConfigParser.RawConfigParser, object):
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
@abc.abstractmethod
|
||||
def to_dict(self):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def read_from_dict(self):
|
||||
pass
|
||||
|
||||
|
||||
class CloudConfigManager(ConfigManager):
|
||||
|
||||
_DEFAULT_CLOUD_CONFIG = {
|
||||
'identity': {
|
||||
'url': 'http://localhost/',
|
||||
'uri': 'http://localhost:5000/v2.0/',
|
||||
'admin_username': 'admin',
|
||||
'admin_password': 'admin',
|
||||
'admin_tenant_name': 'service',
|
||||
'region': 'RegionOne',
|
||||
'strategy': 'keystone',
|
||||
'catalog_type': 'identity',
|
||||
'disable_ssl_certificate_validation': False
|
||||
},
|
||||
'compute': {
|
||||
'controller_nodes': 'localhost',
|
||||
'controller_nodes_name': 'localhost',
|
||||
'controller_node_ssh_user': 'root',
|
||||
'controller_node_ssh_password': 'r00tme',
|
||||
'controller_node_ssh_key_path': '/root/.ssh/id_rsa',
|
||||
'image_name': 'cirros-0.3.1-x86_64-uec',
|
||||
'image_ssh_user': 'cirros',
|
||||
'image_alt_ssh_user': 'cirros',
|
||||
'flavor_ref': 1,
|
||||
'allow_tenant_isolation': True,
|
||||
'ssh_timeout': 300,
|
||||
'ssh_channel_timeout': 60,
|
||||
'build_interval': 3,
|
||||
'build_timeout': 300,
|
||||
'enabled_services': 'nova-cert, nova-consoleauth, ' +
|
||||
'nova-scheduler, nova-conductor, ' +
|
||||
'nova-compute, nova-network, ' +
|
||||
'nova-compute, nova-network',
|
||||
'run_ssh': False,
|
||||
'catalog_type': 'compute',
|
||||
'allow_tenant_reuse': True,
|
||||
'create_image_enabled': True
|
||||
},
|
||||
'network': {
|
||||
'api_version': '2.0',
|
||||
'tenant_network_mask_bits': 28,
|
||||
'tenant_network_cidr': '10.0.0.0/24',
|
||||
'tenant_networks_reachable': True,
|
||||
'neutron_available': False,
|
||||
'catalog_type': 'network'
|
||||
},
|
||||
'image': {
|
||||
'api_version': '1',
|
||||
'http_image': 'http://download.cirros-cloud.net/0.3.1/' +
|
||||
'cirros-0.3.1-x86_64-uec.tar.gz',
|
||||
'catalog_type': 'image'
|
||||
},
|
||||
'volume': {
|
||||
'multi_backend_enabled': 'false',
|
||||
'backend1_name': 'BACKEND_1',
|
||||
'backend2_name': 'BACKEND_2',
|
||||
'build_timeout': 300,
|
||||
'build_interval': 3,
|
||||
'catalog_type': 'volume'
|
||||
},
|
||||
'object-storage': {
|
||||
'container_sync_interval': 5,
|
||||
'container_sync_timeout': 120,
|
||||
'catalog_type': 'object-store'
|
||||
}
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
super(CloudConfigManager, self).__init__()
|
||||
self.read_from_dict(self._DEFAULT_CLOUD_CONFIG)
|
||||
|
||||
def read_from_dict(self, dct):
|
||||
for section_name, section in dct.iteritems():
|
||||
self.add_section(section_name)
|
||||
for option in section:
|
||||
self.set(section_name, option, section[option])
|
||||
|
||||
def to_dict(self):
|
||||
res = {}
|
||||
for section in self.sections():
|
||||
res[section] = dict(self.items(section))
|
||||
return res
|
@ -1,173 +0,0 @@
|
||||
[identity]
|
||||
# This section contains configuration options that a variety of
|
||||
# test clients use when authenticating with different user/tenant
|
||||
# combinations
|
||||
url = http://localhost/
|
||||
# The type of endpoint for a Identity service. Unless you have a
|
||||
# custom Keystone service catalog implementation, you probably want to leave
|
||||
# this value as "identity"
|
||||
catalog_type = identity
|
||||
# Ignore SSL certificate validation failures? Use when in testing
|
||||
# environments that have self-signed SSL certs.
|
||||
disable_ssl_certificate_validation = False
|
||||
# URL for where to find the OpenStack Identity API endpoint (Keystone)
|
||||
uri = http://localhost:5000/v2.0/
|
||||
# URL for where to find the OpenStack V3 Identity API endpoint (Keystone)
|
||||
#uri_v3 = http://127.0.0.1:5000/v3/
|
||||
# Should typically be left as keystone unless you have a non-Keystone
|
||||
# authentication API service
|
||||
strategy = keystone
|
||||
# The identity region
|
||||
region = RegionOne
|
||||
|
||||
# This should be the username of a user WITH administrative privileges
|
||||
admin_username = admin
|
||||
# The above administrative user's password
|
||||
admin_password = admin
|
||||
# The above administrative user's tenant name
|
||||
admin_tenant_name = service
|
||||
|
||||
[compute]
|
||||
# This section contains configuration options used when executing tests
|
||||
# against the OpenStack Compute API.
|
||||
|
||||
#One of the controller nodes
|
||||
controller_nodes = localhost
|
||||
controller_nodes_name = localhost
|
||||
|
||||
#Controller node user who able connect via ssh
|
||||
controller_node_ssh_user = root
|
||||
|
||||
#Controller node ssh user's password
|
||||
controller_node_ssh_password = r00tme
|
||||
#When you use devstack single-machine deployment make sure you have keys created and user your running tests from can
|
||||
#access keys as well
|
||||
controller_node_ssh_key_path = /root/.ssh/id_rsa
|
||||
|
||||
#The list of the services should be enabled
|
||||
enabled_services=nova-cert, nova-consoleauth, nova-scheduler, nova-conductor, nova-compute, nova-network, nova-compute, nova-network
|
||||
|
||||
# Allows test cases to create/destroy tenants and users. This option
|
||||
# enables isolated test cases and better parallel execution,
|
||||
# but also requires that OpenStack Identity API admin credentials
|
||||
# are known.
|
||||
allow_tenant_isolation = True
|
||||
|
||||
# Allows test cases to create/destroy tenants and users. This option
|
||||
# enables isolated test cases and better parallel execution,
|
||||
# but also requires that OpenStack Identity API admin credentials
|
||||
# are known.
|
||||
allow_tenant_reuse = true
|
||||
|
||||
# Reference data for tests. The ref and ref_alt should be
|
||||
# distinct images/flavors.
|
||||
image_name = cirros-0.3.1-x86_64-uec
|
||||
flavor_ref = 1
|
||||
|
||||
# User names used to authenticate to an instance for a given image.
|
||||
image_ssh_user = cirros
|
||||
image_alt_ssh_user = cirros
|
||||
|
||||
# Number of seconds to wait while looping to check the status of an
|
||||
# instance that is building.
|
||||
build_interval = 3
|
||||
|
||||
# Number of seconds to time out on waiting for an instance
|
||||
# to build or reach an expected status
|
||||
build_timeout = 300
|
||||
|
||||
# Run additional tests that use SSH for instance validation?
|
||||
# This requires the instances be routable from the host
|
||||
# executing the tests
|
||||
run_ssh = false
|
||||
|
||||
# Number of seconds to wait to authenticate to an instance
|
||||
ssh_timeout = 300
|
||||
|
||||
# Number of seconds to wait for output from ssh channel
|
||||
ssh_channel_timeout = 60
|
||||
|
||||
# The type of endpoint for a Compute API service. Unless you have a
|
||||
# custom Keystone service catalog implementation, you probably want to leave
|
||||
# this value as "compute"
|
||||
catalog_type = compute
|
||||
|
||||
# Does the Compute API support creation of images?
|
||||
create_image_enabled = true
|
||||
|
||||
[image]
|
||||
# This section contains configuration options used when executing tests
|
||||
# against the OpenStack Images API
|
||||
|
||||
# The type of endpoint for an Image API service. Unless you have a
|
||||
# custom Keystone service catalog implementation, you probably want to leave
|
||||
# this value as "image"
|
||||
catalog_type = image
|
||||
|
||||
# The version of the OpenStack Images API to use
|
||||
api_version = 1
|
||||
|
||||
# HTTP image to use for glance http image testing
|
||||
http_image = http://download.cirros-cloud.net/0.3.1/cirros-0.3.1-x86_64-uec.tar.gz
|
||||
|
||||
[network]
|
||||
# This section contains configuration options used when executing tests
|
||||
# against the OpenStack Network API.
|
||||
|
||||
# Version of the Quantum API
|
||||
api_version = 2.0
|
||||
# Catalog type of the Quantum Service
|
||||
catalog_type = network
|
||||
|
||||
# A large private cidr block from which to allocate smaller blocks for
|
||||
# tenant networks.
|
||||
tenant_network_cidr = 10.0.0.0/24
|
||||
|
||||
# The mask bits used to partition the tenant block.
|
||||
tenant_network_mask_bits = 28
|
||||
|
||||
# If tenant networks are reachable, connectivity checks will be
|
||||
# performed directly against addresses on those networks.
|
||||
tenant_networks_reachable = true
|
||||
|
||||
# Whether or not quantum is expected to be available
|
||||
neutron_available = false
|
||||
|
||||
[volume]
|
||||
# This section contains the configuration options used when executing tests
|
||||
# against the OpenStack Block Storage API service
|
||||
|
||||
# The type of endpoint for a Cinder or Block Storage API service.
|
||||
# Unless you have a custom Keystone service catalog implementation, you
|
||||
# probably want to leave this value as "volume"
|
||||
catalog_type = volume
|
||||
# Number of seconds to wait while looping to check the status of a
|
||||
# volume that is being made available
|
||||
build_interval = 3
|
||||
# Number of seconds to time out on waiting for a volume
|
||||
# to be available or reach an expected status
|
||||
build_timeout = 300
|
||||
# Runs Cinder multi-backend tests (requires 2 backends declared in cinder.conf)
|
||||
# They must have different volume_backend_name (backend1_name and backend2_name
|
||||
# have to be different)
|
||||
multi_backend_enabled = false
|
||||
backend1_name = BACKEND_1
|
||||
backend2_name = BACKEND_2
|
||||
|
||||
[object-storage]
|
||||
# This section contains configuration options used when executing tests
|
||||
# against the OpenStack Object Storage API.
|
||||
|
||||
# You can configure the credentials in the compute section
|
||||
|
||||
# The type of endpoint for an Object Storage API service. Unless you have a
|
||||
# custom Keystone service catalog implementation, you probably want to leave
|
||||
# this value as "object-store"
|
||||
catalog_type = object-store
|
||||
|
||||
# Number of seconds to time on waiting for a container to container
|
||||
# synchronization complete
|
||||
container_sync_timeout = 120
|
||||
# Number of seconds to wait while looping to check the status of a
|
||||
# container to container synchronization
|
||||
container_sync_interval = 5
|
47
tests/benchmark/test_config.py
Normal file
47
tests/benchmark/test_config.py
Normal file
@ -0,0 +1,47 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# 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.
|
||||
|
||||
"""Tests for config managers."""
|
||||
from rally.benchmark import config
|
||||
from rally import test
|
||||
|
||||
|
||||
class CloudConfigManagerTestCase(test.NoDBTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(CloudConfigManagerTestCase, self).setUp()
|
||||
self.manager = config.CloudConfigManager()
|
||||
|
||||
def test_defaults(self):
|
||||
self.assertTrue(self.manager.has_section('identity'))
|
||||
self.assertTrue(self.manager.has_section('compute'))
|
||||
# TODO(msdubov): Don't know exactly which sections
|
||||
# should always be there
|
||||
|
||||
def test_to_dict(self):
|
||||
self.manager.add_section('dummy_section')
|
||||
self.manager.set('dummy_section', 'dummy_option', 'dummy_value')
|
||||
dct = self.manager.to_dict()
|
||||
self.assertTrue('dummy_section' in dct)
|
||||
self.assertEquals(dct['dummy_section']['dummy_option'], 'dummy_value')
|
||||
|
||||
def test_read_from_dict(self):
|
||||
dct = {'dummy_section': {'dummy_option': 'dummy_value'}}
|
||||
self.manager.read_from_dict(dct)
|
||||
self.assertTrue(self.manager.has_section('dummy_section'))
|
||||
self.assertEquals(self.manager.get('dummy_section', 'dummy_option'),
|
||||
'dummy_value')
|
@ -17,7 +17,9 @@
|
||||
|
||||
"""Tests for utils."""
|
||||
import mock
|
||||
import os
|
||||
|
||||
from rally.benchmark import config
|
||||
from rally.benchmark import utils
|
||||
from rally import test
|
||||
|
||||
@ -35,13 +37,19 @@ class UtilsTestCase(test.NoDBTestCase):
|
||||
super(UtilsTestCase, self).setUp()
|
||||
self.fc = mock.patch('fuel_health.cleanup.cleanup')
|
||||
self.fc.start()
|
||||
self.cloud_config_manager = config.CloudConfigManager()
|
||||
self.cloud_config_path = os.path.abspath('dummy_test.conf')
|
||||
with open(self.cloud_config_path, 'w') as f:
|
||||
self.cloud_config_manager.write(f)
|
||||
|
||||
def tearDown(self):
|
||||
self.fc.stop()
|
||||
if os.path.exists(self.cloud_config_path):
|
||||
os.remove(self.cloud_config_path)
|
||||
super(UtilsTestCase, self).tearDown()
|
||||
|
||||
def test_running_test(self):
|
||||
tester = utils.Tester('rally/benchmark/test.conf')
|
||||
tester = utils.Tester(self.cloud_config_path)
|
||||
test = ['./tests/benchmark/test_utils.py', '-k', 'test_dummy']
|
||||
for (times, concurrent) in [(1, 1), (3, 2), (2, 3)]:
|
||||
results = tester.run(test, times=times, concurrent=concurrent)
|
||||
@ -50,7 +58,7 @@ class UtilsTestCase(test.NoDBTestCase):
|
||||
self.assertEqual(result['status'], 0)
|
||||
|
||||
def test_running_multiple_tests(self):
|
||||
tester = utils.Tester('rally/benchmark/test.conf')
|
||||
tester = utils.Tester(self.cloud_config_path)
|
||||
tests = [['./tests/benchmark/test_utils.py', '-k', 'test_dummy'],
|
||||
['./tests/benchmark/test_utils.py', '-k', 'test_dummy_2']]
|
||||
for test_results in tester.run_all(tests):
|
||||
|
Loading…
Reference in New Issue
Block a user