Merge "[Verify] Add tempest configs and move to new section"

This commit is contained in:
Jenkins 2016-06-09 17:16:36 +00:00 committed by Gerrit Code Review
commit 39dc633d41
4 changed files with 124 additions and 87 deletions

View File

@ -6,10 +6,11 @@
# If set to true, the logging level will be set to DEBUG instead of
# the default INFO level. (boolean value)
# Note: This option can be changed without restarting.
#debug = false
# If set to false, the logging level will be set to WARNING instead of
# the default INFO level. (boolean value)
# DEPRECATED: If set to false, the logging level will be set to
# WARNING instead of the default INFO level. (boolean value)
# This option is deprecated for removal.
# Its value may be silently ignored in the future.
#verbose = true
@ -155,13 +156,6 @@
# point value)
#glance_image_create_poll_interval = 1.0
# Time to wait for glance image to be deleted. (floating point value)
#glance_image_delete_timeout = 120.0
# Interval between checks when waiting for image deletion. (floating
# point value)
#glance_image_delete_poll_interval = 1.0
# Time(in sec) to sleep after creating a resource before polling for
# it status. (floating point value)
#heat_stack_create_prepoll_delay = 2.0
@ -635,51 +629,74 @@
#db_max_retries = 20
[image]
[roles_context]
#
# From rally
#
# CirrOS image URL (string value)
#cirros_img_url = http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img
# How many concurrent threads to use for serving roles context
# (integer value)
#resource_management_workers = 30
[tempest]
#
# From rally
#
# image URL (string value)
# Deprecated group/name - [image]/cirros_img_url
#img_url = http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img
# Image disk format to use when creating the image (string value)
#disk_format = qcow2
# Deprecated group/name - [image]/disk_format
#img_disk_format = qcow2
# Image container format to use when creating the image (string value)
#container_format = bare
# Deprecated group/name - [image]/container_format
#img_container_format = bare
# Regular expression for name of a public image to discover it in the
# cloud and use it for the tests. Note that when Rally is searching
# for the image, case insensitive matching is performed. Specify
# nothing ('name_regex =') if you want to disable discovering. In this
# case Rally will create needed resources by itself if the values for
# the corresponding config options are not specified in the Tempest
# config file (string value)
#name_regex = ^.*(cirros|testvm).*$
[role]
#
# From rally
#
# nothing ('img_name_regex =') if you want to disable discovering. In
# this case Rally will create needed resources by itself if the values
# for the corresponding config options are not specified in the
# Tempest config file (string value)
# Deprecated group/name - [image]/name_regex
#img_name_regex = ^.*(cirros|testvm).*$
# Role required for users to be able to create Swift containers
# (string value)
# Deprecated group/name - [role]/swift_operator_role
#swift_operator_role = Member
# User role that has reseller admin (string value)
# Deprecated group/name - [role]/swift_reseller_admin_role
#swift_reseller_admin_role = ResellerAdmin
# Role required for users to be able to manage Heat stacks (string
# value)
# Deprecated group/name - [role]/heat_stack_owner_role
#heat_stack_owner_role = heat_stack_owner
# Role for Heat template-defined users (string value)
# Deprecated group/name - [role]/heat_stack_user_role
#heat_stack_user_role = heat_stack_user
# Primary flavor RAM size used by most of the test cases (integer
# value)
#flavor_ref_ram = 64
# Alternate reference flavor RAM size used by test thatneed two
# flavors, like those that resize an instnace (integer value)
#flavor_ref_alt_ram = 128
# RAM size flavor used for orchestration test cases (integer value)
#heat_instance_type_ram = 64
[users_context]

View File

@ -48,9 +48,8 @@ def list_opts():
nova_utils.NOVA_BENCHMARK_OPTS,
sahara_utils.SAHARA_BENCHMARK_OPTS,
vm_utils.VM_BENCHMARK_OPTS)),
("image",
itertools.chain(tempest_conf.IMAGE_OPTS)),
("role", itertools.chain(tempest_conf.ROLE_OPTS)),
("tempest",
itertools.chain(tempest_conf.TEMPEST_OPTS)),
("roles_context", itertools.chain(roles.ROLES_CONTEXT_OPTS)),
("users_context", itertools.chain(users.USER_CONTEXT_OPTS)),
("cleanup", itertools.chain(cleanup_base.CLEANUP_OPTS))

View File

@ -38,49 +38,67 @@ from rally.task import utils as task_utils
LOG = logging.getLogger(__name__)
IMAGE_OPTS = [
cfg.StrOpt("cirros_img_url",
TEMPEST_OPTS = [
cfg.StrOpt("img_url",
deprecated_opts=[cfg.DeprecatedOpt("cirros_img_url",
group="image")],
default="http://download.cirros-cloud.net/"
"0.3.4/cirros-0.3.4-x86_64-disk.img",
help="CirrOS image URL"),
cfg.StrOpt("disk_format",
help="image URL"),
cfg.StrOpt("img_disk_format",
deprecated_opts=[cfg.DeprecatedOpt("disk_format",
group="image")],
default="qcow2",
help="Image disk format to use when creating the image"),
cfg.StrOpt("container_format",
cfg.StrOpt("img_container_format",
deprecated_opts=[cfg.DeprecatedOpt("container_format",
group="image")],
default="bare",
help="Image container format to use when creating the image"),
cfg.StrOpt("name_regex",
cfg.StrOpt("img_name_regex",
deprecated_opts=[cfg.DeprecatedOpt("name_regex",
group="image")],
default="^.*(cirros|testvm).*$",
help="Regular expression for name of a public image to "
"discover it in the cloud and use it for the tests. "
"Note that when Rally is searching for the image, case "
"insensitive matching is performed. Specify nothing "
"('name_regex =') if you want to disable discovering. "
"('img_name_regex =') if you want to disable discovering. "
"In this case Rally will create needed resources by "
"itself if the values for the corresponding config "
"options are not specified in the Tempest config file")
]
ROLE_OPTS = [
"options are not specified in the Tempest config file"),
cfg.StrOpt("swift_operator_role",
deprecated_group="role",
default="Member",
help="Role required for users "
"to be able to create Swift containers"),
cfg.StrOpt("swift_reseller_admin_role",
deprecated_group="role",
default="ResellerAdmin",
help="User role that has reseller admin"),
cfg.StrOpt("heat_stack_owner_role",
deprecated_group="role",
default="heat_stack_owner",
help="Role required for users "
"to be able to manage Heat stacks"),
cfg.StrOpt("heat_stack_user_role",
deprecated_group="role",
default="heat_stack_user",
help="Role for Heat template-defined users")
help="Role for Heat template-defined users"),
cfg.IntOpt("flavor_ref_ram",
default="64",
help="Primary flavor RAM size used by most of the test cases"),
cfg.IntOpt("flavor_ref_alt_ram",
default="128",
help="Alternate reference flavor RAM size used by test that"
"need two flavors, like those that resize an instnace"),
cfg.IntOpt("heat_instance_type_ram",
default="64",
help="RAM size flavor used for orchestration test cases")
]
CONF = cfg.CONF
CONF.register_opts(IMAGE_OPTS, "image")
CONF.register_opts(ROLE_OPTS, "role")
CONF.register_opts(TEMPEST_OPTS, "tempest")
CONF.import_opt("glance_image_delete_timeout",
"rally.plugins.openstack.scenarios.glance.utils",
"benchmark")
@ -120,18 +138,18 @@ class TempestConfig(utils.RandomNameGeneratorMixin):
self.conf.read(os.path.join(os.path.dirname(__file__), "config.ini"))
self.image_name = parse.urlparse(
CONF.image.cirros_img_url).path.split("/")[-1]
self._download_cirros_image()
CONF.tempest.img_url).path.split("/")[-1]
self._download_image()
def _download_cirros_image(self):
def _download_image(self):
img_path = os.path.join(self.data_dir, self.image_name)
if os.path.isfile(img_path):
return
try:
response = requests.get(CONF.image.cirros_img_url, stream=True)
response = requests.get(CONF.tempest.img_url, stream=True)
except requests.ConnectionError as err:
msg = _("Failed to download CirrOS image. "
msg = _("Failed to download image. "
"Possibly there is no connection to Internet. "
"Error: %s.") % (str(err) or "unknown")
raise exceptions.TempestConfigCreationFailure(msg)
@ -145,10 +163,10 @@ class TempestConfig(utils.RandomNameGeneratorMixin):
os.rename(img_path + ".tmp", img_path)
else:
if response.status_code == 404:
msg = _("Failed to download CirrOS image. "
msg = _("Failed to download image. "
"Image was not found.")
else:
msg = _("Failed to download CirrOS image. "
msg = _("Failed to download image. "
"HTTP error code %d.") % response.status_code
raise exceptions.TempestConfigCreationFailure(msg)
@ -280,9 +298,9 @@ class TempestConfig(utils.RandomNameGeneratorMixin):
def _configure_object_storage(self, section_name="object-storage"):
self.conf.set(section_name, "operator_role",
CONF.role.swift_operator_role)
CONF.tempest.swift_operator_role)
self.conf.set(section_name, "reseller_admin_role",
CONF.role.swift_reseller_admin_role)
CONF.tempest.swift_reseller_admin_role)
def _configure_scenario(self, section_name="scenario"):
self.conf.set(section_name, "img_dir", self.data_dir)
@ -321,9 +339,9 @@ class TempestConfig(utils.RandomNameGeneratorMixin):
def _configure_orchestration(self, section_name="orchestration"):
self.conf.set(section_name, "stack_owner_role",
CONF.role.heat_stack_owner_role)
CONF.tempest.heat_stack_owner_role)
self.conf.set(section_name, "stack_user_role",
CONF.role.heat_stack_user_role)
CONF.tempest.heat_stack_user_role)
def generate(self, conf_path=None):
for name, method in inspect.getmembers(self, inspect.ismethod):
@ -351,7 +369,7 @@ class TempestResourcesContext(utils.RandomNameGeneratorMixin):
self.conf.read(conf_path)
self.image_name = parse.urlparse(
CONF.image.cirros_img_url).path.split("/")[-1]
CONF.tempest.img_url).path.split("/")[-1]
self._created_roles = []
self._created_images = []
@ -365,9 +383,11 @@ class TempestResourcesContext(utils.RandomNameGeneratorMixin):
self._configure_option("compute", "image_ref_alt",
self._discover_or_create_image)
self._configure_option("compute", "flavor_ref",
self._discover_or_create_flavor, 64)
self._discover_or_create_flavor,
CONF.tempest.flavor_ref_ram)
self._configure_option("compute", "flavor_ref_alt",
self._discover_or_create_flavor, 128)
self._discover_or_create_flavor,
CONF.tempest.flavor_ref_alt_ram)
if "neutron" in self.available_services:
neutronclient = self.clients.neutron()
if neutronclient.list_networks(shared=True)["networks"]:
@ -384,7 +404,8 @@ class TempestResourcesContext(utils.RandomNameGeneratorMixin):
self._create_network_resources)
if "heat" in self.available_services:
self._configure_option("orchestration", "instance_type",
self._discover_or_create_flavor, 64)
self._discover_or_create_flavor,
CONF.tempest.heat_instance_type_ram)
_write_config(self.conf_path, self.conf)
@ -404,10 +425,10 @@ class TempestResourcesContext(utils.RandomNameGeneratorMixin):
def _create_tempest_roles(self):
keystoneclient = self.clients.verified_keystone()
roles = [CONF.role.swift_operator_role,
CONF.role.swift_reseller_admin_role,
CONF.role.heat_stack_owner_role,
CONF.role.heat_stack_user_role]
roles = [CONF.tempest.swift_operator_role,
CONF.tempest.swift_reseller_admin_role,
CONF.tempest.heat_stack_owner_role,
CONF.tempest.heat_stack_user_role]
existing_roles = set(role.name for role in keystoneclient.roles.list())
for role in roles:
@ -435,14 +456,14 @@ class TempestResourcesContext(utils.RandomNameGeneratorMixin):
def _discover_or_create_image(self):
glance_wrapper = glance.wrap(self.clients.glance, self)
if CONF.image.name_regex:
if CONF.tempest.img_name_regex:
LOG.debug("Trying to discover a public image with name matching "
"regular expression '%s'. Note that case insensitive "
"matching is performed" % CONF.image.name_regex)
"matching is performed" % CONF.tempest.img_name_regex)
images = glance_wrapper.list_images(status="active",
visibility="public")
for img in images:
if img.name and re.match(CONF.image.name_regex,
if img.name and re.match(CONF.tempest.img_name_regex,
img.name, re.IGNORECASE):
LOG.debug(
"The following public image discovered: '{0}'. "
@ -450,12 +471,12 @@ class TempestResourcesContext(utils.RandomNameGeneratorMixin):
return img
LOG.debug("There is no public image with name matching "
"regular expression '%s'" % CONF.image.name_regex)
"regular expression '%s'" % CONF.tempest.img_name_regex)
params = {
"name": self.generate_random_name(),
"disk_format": CONF.image.disk_format,
"container_format": CONF.image.container_format,
"disk_format": CONF.tempest.img_disk_format,
"container_format": CONF.tempest.img_container_format,
"image_location": os.path.join(_create_or_get_data_dir(),
self.image_name),
"visibility": "public"

View File

@ -61,26 +61,26 @@ class TempestConfigTestCase(test.TestCase):
@mock.patch("os.rename")
@mock.patch("six.moves.builtins.open", side_effect=mock.mock_open())
@mock.patch("requests.get", return_value=mock.MagicMock(status_code=200))
def test__download_cirros_image_success(self, mock_get,
mock_open, mock_rename):
def test__download_image_success(self, mock_get,
mock_open, mock_rename):
self.mock_isfile.return_value = False
self.tempest_conf._download_cirros_image()
self.tempest_conf._download_image()
mock_get.assert_called_once_with(
CONF.image.cirros_img_url, stream=True)
CONF.tempest.img_url, stream=True)
@mock.patch("requests.get")
@ddt.data(404, 500)
def test__download_cirros_image_failure(self, status_code, mock_get):
def test__download_image_failure(self, status_code, mock_get):
self.mock_isfile.return_value = False
mock_get.return_value = mock.MagicMock(status_code=status_code)
self.assertRaises(exceptions.TempestConfigCreationFailure,
self.tempest_conf._download_cirros_image)
self.tempest_conf._download_image)
@mock.patch("requests.get", side_effect=requests.ConnectionError())
def test__download_cirros_image_connection_error(self, mock_requests_get):
def test__download_image_connection_error(self, mock_requests_get):
self.mock_isfile.return_value = False
self.assertRaises(exceptions.TempestConfigCreationFailure,
self.tempest_conf._download_cirros_image)
self.tempest_conf._download_image)
@ddt.data({"publicURL": "test_url"},
{"interface": "public", "url": "test_url"})
@ -228,8 +228,8 @@ class TempestConfigTestCase(test.TestCase):
self.tempest_conf._configure_object_storage()
expected = (
("operator_role", CONF.role.swift_operator_role),
("reseller_admin_role", CONF.role.swift_reseller_admin_role))
("operator_role", CONF.tempest.swift_operator_role),
("reseller_admin_role", CONF.tempest.swift_reseller_admin_role))
result = self.tempest_conf.conf.items("object-storage")
for item in expected:
self.assertIn(item, result)
@ -238,8 +238,8 @@ class TempestConfigTestCase(test.TestCase):
self.tempest_conf._configure_orchestration()
expected = (
("stack_owner_role", CONF.role.heat_stack_owner_role),
("stack_user_role", CONF.role.heat_stack_user_role))
("stack_owner_role", CONF.tempest.heat_stack_owner_role),
("stack_user_role", CONF.tempest.heat_stack_user_role))
result = self.tempest_conf.conf.items("orchestration")
for item in expected:
self.assertIn(item, result)
@ -248,7 +248,7 @@ class TempestConfigTestCase(test.TestCase):
self.tempest_conf._configure_scenario()
image_name = parse.urlparse(
config.CONF.image.cirros_img_url).path.split("/")[-1]
config.CONF.tempest.img_url).path.split("/")[-1]
expected = (("img_dir", self.tempest_conf.data_dir),
("img_file", image_name))
result = self.tempest_conf.conf.items("scenario")
@ -370,10 +370,10 @@ class TempestResourcesContextTestCase(test.TestCase):
self.assertEqual(mock_neutron_wrapper_create_network.call_count, 0)
def test__create_tempest_roles(self):
role1 = CONF.role.swift_operator_role
role2 = CONF.role.swift_reseller_admin_role
role3 = CONF.role.heat_stack_owner_role
role4 = CONF.role.heat_stack_user_role
role1 = CONF.tempest.swift_operator_role
role2 = CONF.tempest.swift_reseller_admin_role
role3 = CONF.tempest.heat_stack_owner_role
role4 = CONF.tempest.heat_stack_user_role
client = self.context.clients.verified_keystone()
client.roles.list.return_value = [fakes.FakeRole(name=role1),
@ -423,9 +423,9 @@ class TempestResourcesContextTestCase(test.TestCase):
mock_wrap.assert_called_once_with(self.context.clients.glance,
self.context)
client.create_image.assert_called_once_with(
container_format=CONF.image.container_format,
container_format=CONF.tempest.img_container_format,
image_location=mock.ANY,
disk_format=CONF.image.disk_format,
disk_format=CONF.tempest.img_disk_format,
name=mock.ANY,
visibility="public")