Merge "Tempest changes to support stack updates"

This commit is contained in:
Jenkins 2017-08-16 14:36:03 +00:00 committed by Gerrit Code Review
commit 8d11af2357
15 changed files with 92 additions and 215 deletions

View File

@ -41,7 +41,7 @@ class ValetGroupsTest(base.BaseValetTest):
description = data_utils.rand_name('Description') description = data_utils.rand_name('Description')
group = self.client.create_group( group = self.client.create_group(
name=group_name, group_type='exclusivity', name=group_name, group_type='exclusivity',
description=description) description=description, level='host')
self.addCleanup(self.client.delete_group, group['id']) self.addCleanup(self.client.delete_group, group['id'])
group_ids.append(group['id']) group_ids.append(group['id'])
@ -61,7 +61,7 @@ class ValetGroupsTest(base.BaseValetTest):
description = data_utils.rand_name('Description') description = data_utils.rand_name('Description')
group = self.client.create_group( group = self.client.create_group(
name=group_name, group_type='exclusivity', name=group_name, group_type='exclusivity',
description=description) description=description, level='host')
self.addCleanup(self.client.delete_group, group['id']) self.addCleanup(self.client.delete_group, group['id'])
self.assertIn('id', group) self.assertIn('id', group)
@ -78,7 +78,7 @@ class ValetGroupsTest(base.BaseValetTest):
description = data_utils.rand_name('Description') description = data_utils.rand_name('Description')
body = self.client.create_group( body = self.client.create_group(
name=group_name, group_type='exclusivity', name=group_name, group_type='exclusivity',
description=description) description=description, level='host')
group_id = body.get('id') group_id = body.get('id')
@ -100,7 +100,7 @@ class ValetGroupsTest(base.BaseValetTest):
description = data_utils.rand_name('Description') description = data_utils.rand_name('Description')
group = self.client.create_group( group = self.client.create_group(
name=group_name, group_type='exclusivity', name=group_name, group_type='exclusivity',
description=description) description=description, level='host')
self.addCleanup(self.client.delete_group, group['id']) self.addCleanup(self.client.delete_group, group['id'])
@ -120,7 +120,7 @@ class ValetGroupsTest(base.BaseValetTest):
description = data_utils.rand_name('Description') description = data_utils.rand_name('Description')
group = self.client.create_group( group = self.client.create_group(
name=group_name, group_type='exclusivity', name=group_name, group_type='exclusivity',
description=description) description=description, level='host')
self.addCleanup(self.client.delete_group, group['id']) self.addCleanup(self.client.delete_group, group['id'])

View File

@ -35,7 +35,8 @@ class ValetGroupsMembersTest(base.BaseValetTest):
group_name = data_utils.rand_name('membergroup') group_name = data_utils.rand_name('membergroup')
resp = self.client.create_group(name=group_name, resp = self.client.create_group(name=group_name,
group_type='exclusivity', group_type='exclusivity',
description='Test Member Group') description='Test Member Group',
level='host')
group_id = resp['id'] group_id = resp['id']
self.addCleanup(self._delete_group, group_id) self.addCleanup(self._delete_group, group_id)
return group_id return group_id

View File

@ -41,14 +41,15 @@ class Analyzer(object):
self.instances_on_host = defaultdict(list) self.instances_on_host = defaultdict(list)
self.tries = CONF.valet.TRIES_TO_SHOW_SERVER self.tries = CONF.valet.TRIES_TO_SHOW_SERVER
def check(self, resources): def check(self, resources, levels, group_types):
"""Checking if all instances are on the Appropriate hosts and racks.""" """Checking if all instances are on the Appropriate hosts and racks """
self.log.log_info("Starting to check instances location") self.log.log_info("Starting to check instances location")
result = True result = True
self.init_servers_list() self.init_servers_list()
self.init_resources(resources) self.init_resources(resources)
ins_group = self.init_instances_for_group(resources) ins_group = self.init_instances_for_group(resources,
levels, group_types)
try: try:
for group_type in ins_group: for group_type in ins_group:
@ -72,18 +73,18 @@ class Analyzer(object):
return result return result
def init_instances_for_group(self, resources): def init_instances_for_group(self, resources, levels, group_types):
"""Init instances for a group with the given resources.""" self.log.log_info("initializing instances for groups")
self.log.log_info("initializing instances for group")
ins_group = defaultdict(list) ins_group = defaultdict(list)
index = 0
for grp in resources.groups.keys(): for grp in resources.groups.keys():
self.group_instance_name[grp] = \ self.group_instance_name[grp] = \
resources.groups[grp].group_resources resources.groups[grp].group_resources
resources.groups[grp].group_resources.append( resources.groups[grp].group_resources.append(levels[index])
resources.groups[grp].level) ins_group[group_types[index]].append(
ins_group[resources.groups[grp].group_type].append(
resources.groups[grp].group_resources) resources.groups[grp].group_resources)
++index
# replacing group for it's instances # replacing group for it's instances
ins_group = self.organize(ins_group) ins_group = self.organize(ins_group)
@ -224,7 +225,7 @@ class Analyzer(object):
return ins_group return ins_group
def get_exclusivity_group_hosts(self): def get_exclusivity_group_hosts(self):
'''Get all hosts that exclusivity group instances are located on ''' """Get all hosts that exclusivity group instances are located on """
servers_list = self.nova_client.list_servers() servers_list = self.nova_client.list_servers()
exclusivity_hosts = [] exclusivity_hosts = []
for serv in servers_list["servers"]: for serv in servers_list["servers"]:

View File

@ -42,8 +42,15 @@ class TemplateResources(object):
resource_type = str(doc[TEMPLATE_RES][resource]["type"]) resource_type = str(doc[TEMPLATE_RES][resource]["type"])
if resource_type == "OS::Nova::Server": if resource_type == "OS::Nova::Server":
self.instances.append(Instance(doc, resource)) self.instances.append(Instance(doc, resource))
elif resource_type == "ATT::Valet::GroupAssignment": temp = Group(doc, resource)
self.groups[resource] = Group(doc, resource)
if not any(self.groups):
self.groups[temp.group_name] = temp
elif temp.group_name in self.groups:
self.groups[temp.group_name].group_resources. \
append(resource)
else:
self.groups[temp.group_name] = temp
except Exception: except Exception:
LOG.error("Failed to initialize TemplateResources") LOG.error("Failed to initialize TemplateResources")
@ -84,28 +91,20 @@ class Instance(object):
class Group(object): class Group(object):
"""Class representing group object.""" def __init__(self, doc, instance_name):
def __init__(self, doc, group_name):
"""Init group with type, name, level, resources and call fill."""
self.group_type = None
self.group_name = None self.group_name = None
self.level = None
self.group_resources = [] self.group_resources = []
self.fill(doc, group_name) self.fill(doc, instance_name)
def fill(self, doc, group_name): def fill(self, doc, instance_name):
"""Fill group details from template."""
try: try:
template_property = doc[TEMPLATE_RES][group_name]["properties"] property_metadata = (doc[TEMPLATE_RES][instance_name]["properties"]
["metadata"]["valet"])
self.group_type = template_property["group_type"] self.group_name = property_metadata["groups"][0] \
self.group_name = template_property["group_name"] if \ if "groups" in property_metadata else None
"group_name" in template_property else None self.group_resources.append(instance_name)
self.level = template_property["level"]
for res in template_property[TEMPLATE_RES]:
self.group_resources.append(res["get_resource"])
except Exception: except Exception:
LOG.error("Failed to initialize Group") LOG.error("Failed to initialize Group")

View File

@ -69,7 +69,7 @@ class ScenarioTestCase(test.BaseTestCase):
cls.stack_identifier = None cls.stack_identifier = None
cls.tries = CONF.valet.TRIES_TO_CREATE cls.tries = CONF.valet.TRIES_TO_CREATE
def run_test(self, logger, stack_name, template_path): def run_test(self, logger, stack_name, template_path, levels, group_types):
"""Scenario. """Scenario.
create new stack create new stack
@ -84,29 +84,31 @@ class ScenarioTestCase(test.BaseTestCase):
self.log.log_info(" ******** Creating Stack ******** ") self.log.log_info(" ******** Creating Stack ******** ")
name = data_utils.rand_name(name=stack_name) name = data_utils.rand_name(name=stack_name)
self.assertEqual(True, self.create_stack(name, env_data, template)) self.assertEqual(True, self.create_stack(name, env_data, template,
levels, group_types))
self.log.log_info(" ******** Analyzing Stack ******** ") self.log.log_info(" ******** Analyzing Stack ******** ")
analyzer = Analyzer(self.log, self.stack_identifier, self.heat_client, analyzer = Analyzer(self.log, self.stack_identifier, self.heat_client,
self.nova_client) self.nova_client)
self.assertEqual(True, analyzer.check(template)) self.assertEqual(True, analyzer.check(template, levels, group_types))
self.log.log_info(" ********** THE END ****************") self.log.log_info(" ********** THE END ****************")
def create_stack(self, stack_name, env_data, template_resources): def create_stack(self, stack_name, env_data, template_resources, levels,
"""Create stack with name/env/resource. Create all groups/instances.""" group_types):
try: try:
groups = template_resources.groups groups = template_resources.groups
index = 0
for key in groups: for key in groups:
if groups[key].group_type == "exclusivity": grp_name = data_utils.rand_name(name=groups[key].group_name)
self.log.log_info(" creating valet group ") template_resources.template_data = \
grp_name = data_utils.rand_name( template_resources.template_data.replace(groups[key].
name=groups[key].group_name) group_name,
template_resources.template_data = \ grp_name)
template_resources.template_data.replace( self.create_valet_group(grp_name,
groups[key].group_name, grp_name) levels[index], group_types[index])
self.create_valet_group(grp_name) ++index
for instance in template_resources.instances: for instance in template_resources.instances:
generated_name = data_utils.rand_name(instance.name) generated_name = data_utils.rand_name(instance.name)
@ -125,12 +127,12 @@ class ScenarioTestCase(test.BaseTestCase):
return False return False
return True return True
def create_valet_group(self, group_name): def create_valet_group(self, group_name, level, group_type):
"""Create valet group with name using valet client. Add members."""
try: try:
v_group = self.valet_client.create_group(name=group_name, v_group = self.valet_client.create_group(name=group_name,
group_type='exclusivity', description="description",
description="description") level=level,
group_type=group_type)
group_id = v_group['id'] group_id = v_group['id']
tenant_id = self.tenants_client.tenant_id tenant_id = self.tenants_client.tenant_id
self.addCleanup(self._delete_group, group_id) self.addCleanup(self._delete_group, group_id)

View File

@ -5,7 +5,7 @@ description: Affinity template - all VMs should be deployed on the same host
parameters: parameters:
instance_image: instance_image:
type: string type: string
instance_flavor: instance_flavor:
type: string type: string
@ -22,6 +22,10 @@ resources:
flavor: { get_param: instance_flavor } flavor: { get_param: instance_flavor }
networks: networks:
- network: { get_param: network } - network: { get_param: network }
metadata:
valet:
groups: [affinity_1]
my-instance-2: my-instance-2:
type: OS::Nova::Server type: OS::Nova::Server
@ -31,16 +35,9 @@ resources:
flavor: { get_param: instance_flavor } flavor: { get_param: instance_flavor }
networks: networks:
- network: { get_param: network } - network: { get_param: network }
metadata:
valet:
test-affinity-group3: groups: [affinity_1]
type: ATT::Valet::GroupAssignment
properties:
group_type: affinity
level: host
resources:
- {get_resource: my-instance-1}
- {get_resource: my-instance-2}
outputs: outputs:
instance_name-1: instance_name-1:

View File

@ -5,7 +5,7 @@ description: Diversity template - all VMs should be deployed on different hosts
parameters: parameters:
instance_image: instance_image:
type: string type: string
instance_flavor: instance_flavor:
type: string type: string
@ -22,6 +22,9 @@ resources:
flavor: { get_param: instance_flavor } flavor: { get_param: instance_flavor }
networks: networks:
- network: { get_param: network } - network: { get_param: network }
metadata:
valet:
groups: [diversity_1]
my-instance-2: my-instance-2:
type: OS::Nova::Server type: OS::Nova::Server
@ -31,19 +34,12 @@ resources:
flavor: { get_param: instance_flavor } flavor: { get_param: instance_flavor }
networks: networks:
- network: { get_param: network } - network: { get_param: network }
metadata:
valet:
groups: [diversity_1]
test-diversity-group:
type: ATT::Valet::GroupAssignment
properties:
group_type: diversity
level: host
resources:
- {get_resource: my-instance-1}
- {get_resource: my-instance-2}
outputs: outputs:
instance_name-1: instance_name-1:
value: { get_attr: [my-instance-1, name] } value: { get_attr: [my-instance-1, name] }
instance_name-2: instance_name-2:
value: { get_attr: [my-instance-2, name] } value: { get_attr: [my-instance-2, name] }

View File

@ -1,4 +0,0 @@
parameters:
instance_image: image_place_holder
instance_flavor: flavor_place_holder
network: network_place_holder

View File

@ -1,90 +0,0 @@
heat_template_version: 2015-04-30
description: Nested affinity and diversity template - Host level diversity
parameters:
instance_image:
type: string
instance_flavor:
type: string
network:
type: string
resources:
my-instance-1:
type: OS::Nova::Server
properties:
name: test-1
image: { get_param: instance_image }
flavor: { get_param: instance_flavor }
networks:
- network: { get_param: network }
my-instance-2:
type: OS::Nova::Server
properties:
name: test-2
image: { get_param: instance_image }
flavor: { get_param: instance_flavor }
networks:
- network: { get_param: network }
my-instance-3:
type: OS::Nova::Server
properties:
name: test-3
image: { get_param: instance_image }
flavor: { get_param: instance_flavor }
networks:
- network: { get_param: network }
my-instance-4:
type: OS::Nova::Server
properties:
name: test-4
image: { get_param: instance_image }
flavor: { get_param: instance_flavor }
networks:
- network: { get_param: network }
test-affinity-group1:
type: ATT::Valet::GroupAssignment
properties:
group_type: affinity
level: host
resources:
- {get_resource: my-instance-1}
- {get_resource: my-instance-2}
test-affinity-group2:
type: ATT::Valet::GroupAssignment
properties:
group_type: affinity
level: host
resources:
- {get_resource: my-instance-3}
- {get_resource: my-instance-4}
test-diversity-group:
type: ATT::Valet::GroupAssignment
properties:
group_type: diversity
level: host
resources:
- {get_resource: test-affinity-group1}
- {get_resource: test-affinity-group2}
outputs:
instance_name-1:
value: { get_attr: [my-instance-1, name] }
instance_name-2:
value: { get_attr: [my-instance-2, name] }
instance_name-3:
value: { get_attr: [my-instance-3, name] }
instance_name-4:
value: { get_attr: [my-instance-4, name] }

View File

@ -1,11 +1,11 @@
heat_template_version: 2015-04-30 heat_template_version: 2015-04-30
description: Simple template description: Simple template
parameters: parameters:
instance_image: instance_image:
type: string type: string
instance_flavor: instance_flavor:
type: string type: string
@ -21,6 +21,9 @@ resources:
flavor: { get_param: instance_flavor } flavor: { get_param: instance_flavor }
networks: networks:
- network: { get_param: network } - network: { get_param: network }
metadata:
valet:
groups: [exclusivity_1]
my-instance-2: my-instance-2:
type: OS::Nova::Server type: OS::Nova::Server
@ -30,14 +33,6 @@ resources:
flavor: { get_param: instance_flavor } flavor: { get_param: instance_flavor }
networks: networks:
- network: { get_param: network } - network: { get_param: network }
metadata:
valet:
test-exclusivity-group: groups: [exclusivity_1]
type: ATT::Valet::GroupAssignment
properties:
group_type: exclusivity
group_name: template_group
level: host
resources:
- {get_resource: my-instance-1}
- {get_resource: my-instance-2}

View File

@ -25,5 +25,8 @@ class TestAffinity(ScenarioTestCase):
def test_affinity(self): def test_affinity(self):
"""Run affinity test.""" """Run affinity test."""
logger = GeneralLogger("test_affinity") logger = GeneralLogger("test_affinity")
levels = ["host"]
group_types = ["affinity"]
self.run_test(logger, "affinity", self.run_test(logger, "affinity",
"/templates/affinity_basic_2_instances.yml") "/templates/affinity_basic_2_instances.yml",
levels, group_types)

View File

@ -25,5 +25,8 @@ class TestDiversity(ScenarioTestCase):
def test_diversity(self): def test_diversity(self):
"""Run Test diversity.""" """Run Test diversity."""
logger = GeneralLogger("test_diversity") logger = GeneralLogger("test_diversity")
levels = ["host"]
group_types = ["diversity"]
self.run_test(logger, "diversity", self.run_test(logger, "diversity",
"/templates/diversity_basic_2_instances.yml") "/templates/diversity_basic_2_instances.yml",
levels, group_types)

View File

@ -25,5 +25,8 @@ class TestExclusivity(ScenarioTestCase):
def test_exclusivity(self): def test_exclusivity(self):
"""Test Exclusivity.""" """Test Exclusivity."""
logger = GeneralLogger("test_exclusivity") logger = GeneralLogger("test_exclusivity")
levels = ["host"]
group_types = ["exclusivity"]
self.run_test(logger, "exclusivity", self.run_test(logger, "exclusivity",
"/templates/exclusivity_basic_2_instances.yml") "/templates/exclusivity_basic_2_instances.yml",
levels, group_types)

View File

@ -1,29 +0,0 @@
#
# Copyright 2014-2017 AT&T Intellectual Property
#
# 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.
"""Test Nested."""
from valet.tests.tempest.scenario.general_logger import GeneralLogger
from valet.tests.tempest.scenario.scenario_base import ScenarioTestCase
class TestNested(ScenarioTestCase):
"""Test Nested Scenario Test Case."""
def test_nested(self):
"""Log test_nested and call run test from base."""
logger = GeneralLogger("test_nested")
self.run_test(logger, "affinity_diversity",
"/templates/diversity_between_2_affinity.yml")

View File

@ -40,12 +40,12 @@ class ValetClient(rest_client.RestClient):
self.expected_success(200, resp.status) self.expected_success(200, resp.status)
return self._resp_helper(resp, body) return self._resp_helper(resp, body)
def create_group(self, name, group_type, description): def create_group(self, name, description, level, group_type):
"""Create group with name, type and description."""
params = { params = {
"name": name, "name": name,
"type": group_type, "type": group_type,
"description": description, "description": description,
"level": level
} }
req_body = json.dumps(params) req_body = json.dumps(params)
resp, body = self.post('/groups', req_body) resp, body = self.post('/groups', req_body)