Refactor agents processing and add unit tests
Change-Id: I810f7ea8b5d4316c7813552a7fba7703337a4f53
This commit is contained in:
parent
d73c8ad2d4
commit
c83fa7375e
@ -58,17 +58,17 @@ resources:
|
||||
{remote_ip_prefix: 0.0.0.0/0,
|
||||
protocol: icmp}]
|
||||
|
||||
{% for group in groups %}
|
||||
{% for agent in agents.values() %}
|
||||
|
||||
{{ group.master.name }}:
|
||||
{{ agent.id }}:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
name: {{ group.master.name }}
|
||||
name: {{ agent.id }}
|
||||
image: { get_param: image }
|
||||
flavor: { get_param: flavor }
|
||||
availability_zone: "nova:{{ group.master.node }}"
|
||||
availability_zone: "nova:{{ agent.node }}"
|
||||
networks:
|
||||
- port: { get_resource: {{ group.master.name }}_port }
|
||||
- port: { get_resource: {{ agent.id }}_port }
|
||||
user_data_format: RAW
|
||||
user_data:
|
||||
str_replace:
|
||||
@ -77,36 +77,9 @@ resources:
|
||||
screen -dmS shaker-agent-screen shaker-agent --server-endpoint=$SERVER_ENDPOINT --agent-id=$AGENT_ID
|
||||
params:
|
||||
"$SERVER_ENDPOINT": { get_param: server_endpoint }
|
||||
"$AGENT_ID": {{ group.master.name }}
|
||||
"$AGENT_ID": {{ agent.id }}
|
||||
|
||||
{{ group.master.name }}_port:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network_id: { get_resource: private_net }
|
||||
fixed_ips:
|
||||
- subnet_id: { get_resource: private_subnet }
|
||||
security_groups: [{ get_resource: server_security_group }]
|
||||
|
||||
{{ group.slave.name }}:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
name: {{ group.slave.name }}
|
||||
image: { get_param: image }
|
||||
flavor: { get_param: flavor }
|
||||
availability_zone: "nova:{{ group.slave.node }}"
|
||||
networks:
|
||||
- port: { get_resource: {{ group.slave.name }}_port }
|
||||
user_data_format: RAW
|
||||
user_data:
|
||||
str_replace:
|
||||
template: |
|
||||
#!/bin/sh
|
||||
screen -dmS shaker-agent-screen shaker-agent --server-endpoint=$SERVER_ENDPOINT --agent-id=$AGENT_ID
|
||||
params:
|
||||
"$SERVER_ENDPOINT": { get_param: server_endpoint }
|
||||
"$AGENT_ID": {{ group.slave.name }}
|
||||
|
||||
{{ group.slave.name }}_port:
|
||||
{{ agent.id }}_port:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network_id: { get_resource: private_net }
|
||||
@ -117,13 +90,9 @@ resources:
|
||||
{% endfor %}
|
||||
|
||||
outputs:
|
||||
{% for group in groups %}
|
||||
{{ group.master.name }}_ip:
|
||||
value: { get_attr: [ {{ group.master.name }}, networks, { get_attr: [private_net, name] }, 0 ] }
|
||||
{{ group.master.name }}_instance_name:
|
||||
value: { get_attr: [ {{ group.master.name }}, instance_name ] }
|
||||
{{ group.slave.name }}_ip:
|
||||
value: { get_attr: [ {{ group.slave.name }}, networks, { get_attr: [private_net, name] }, 0 ] }
|
||||
{{ group.slave.name }}_instance_name:
|
||||
value: { get_attr: [ {{ group.slave.name }}, instance_name ] }
|
||||
{% for agent in agents.values() %}
|
||||
{{ agent.id }}_instance_name:
|
||||
value: { get_attr: [ {{ agent.id }}, instance_name ] }
|
||||
{{ agent.id }}_ip:
|
||||
value: { get_attr: [ {{ agent.id }}, networks, { get_attr: [private_net, name] }, 0 ] }
|
||||
{% endfor %}
|
||||
|
@ -76,17 +76,17 @@ resources:
|
||||
{remote_ip_prefix: 0.0.0.0/0,
|
||||
protocol: icmp}]
|
||||
|
||||
{% for group in groups %}
|
||||
{% for agent in agents.values() %}
|
||||
|
||||
{{ group.master.name }}:
|
||||
{{ agent.id }}:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
name: {{ group.master.name }}
|
||||
name: {{ agent.id }}
|
||||
image: { get_param: image }
|
||||
flavor: { get_param: flavor }
|
||||
availability_zone: "nova:{{ group.master.node }}"
|
||||
availability_zone: "nova:{{ agent.node }}"
|
||||
networks:
|
||||
- port: { get_resource: {{ group.master.name }}_port }
|
||||
- port: { get_resource: {{ agent.id }}_port }
|
||||
user_data_format: RAW
|
||||
user_data:
|
||||
str_replace:
|
||||
@ -95,53 +95,37 @@ resources:
|
||||
screen -dmS shaker-agent-screen shaker-agent --server-endpoint=$SERVER_ENDPOINT --agent-id=$AGENT_ID
|
||||
params:
|
||||
"$SERVER_ENDPOINT": { get_param: server_endpoint }
|
||||
"$AGENT_ID": {{ group.master.name }}
|
||||
"$AGENT_ID": {{ agent.id }}
|
||||
|
||||
{{ group.master.name }}_port:
|
||||
{% if agent.mode == 'master' %}
|
||||
{{ agent.id }}_port:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network_id: { get_resource: east_private_net }
|
||||
fixed_ips:
|
||||
- subnet_id: { get_resource: east_private_subnet }
|
||||
security_groups: [{ get_resource: server_security_group }]
|
||||
|
||||
{{ group.slave.name }}:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
name: {{ group.slave.name }}
|
||||
image: { get_param: image }
|
||||
flavor: { get_param: flavor }
|
||||
availability_zone: "nova:{{ group.slave.node }}"
|
||||
networks:
|
||||
- port: { get_resource: {{ group.slave.name }}_port }
|
||||
user_data_format: RAW
|
||||
user_data:
|
||||
str_replace:
|
||||
template: |
|
||||
#!/bin/sh
|
||||
screen -dmS shaker-agent-screen shaker-agent --server-endpoint=$SERVER_ENDPOINT --agent-id=$AGENT_ID
|
||||
params:
|
||||
"$SERVER_ENDPOINT": { get_param: server_endpoint }
|
||||
"$AGENT_ID": {{ group.slave.name }}
|
||||
|
||||
{{ group.slave.name }}_port:
|
||||
{% else %}
|
||||
{{ agent.id }}_port:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network_id: { get_resource: west_private_net }
|
||||
fixed_ips:
|
||||
- subnet_id: { get_resource: west_private_subnet }
|
||||
security_groups: [{ get_resource: server_security_group }]
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
outputs:
|
||||
{% for group in groups %}
|
||||
{{ group.master.name }}_ip:
|
||||
value: { get_attr: [ {{ group.master.name }}, networks, { get_attr: [east_private_net, name] }, 0 ] }
|
||||
{{ group.master.name }}_instance_name:
|
||||
value: { get_attr: [ {{ group.master.name }}, instance_name ] }
|
||||
{{ group.slave.name }}_ip:
|
||||
value: { get_attr: [ {{ group.slave.name }}, networks, { get_attr: [west_private_net, name] }, 0 ] }
|
||||
{{ group.slave.name }}_instance_name:
|
||||
value: { get_attr: [ {{ group.slave.name }}, instance_name ] }
|
||||
{% for agent in agents.values() %}
|
||||
{{ agent.id }}_instance_name:
|
||||
value: { get_attr: [ {{ agent.id }}, instance_name ] }
|
||||
{% if agent.mode == 'master' %}
|
||||
{{ agent.id }}_ip:
|
||||
value: { get_attr: [ {{ agent.id }}, networks, { get_attr: [east_private_net, name] }, 0 ] }
|
||||
{% else %}
|
||||
{{ agent.id }}_ip:
|
||||
value: { get_attr: [ {{ agent.id }}, networks, { get_attr: [west_private_net, name] }, 0 ] }
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
@ -84,17 +84,17 @@ resources:
|
||||
{remote_ip_prefix: 0.0.0.0/0,
|
||||
protocol: icmp}]
|
||||
|
||||
{% for group in groups %}
|
||||
{% for agent in agents.values() %}
|
||||
|
||||
{{ group.master.name }}:
|
||||
{{ agent.id }}:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
name: {{ group.master.name }}
|
||||
name: {{ agent.id }}
|
||||
image: { get_param: image }
|
||||
flavor: { get_param: flavor }
|
||||
availability_zone: "nova:{{ group.master.node }}"
|
||||
availability_zone: "nova:{{ agent.node }}"
|
||||
networks:
|
||||
- port: { get_resource: {{ group.master.name }}_port }
|
||||
- port: { get_resource: {{ agent.id }}_port }
|
||||
user_data_format: RAW
|
||||
user_data:
|
||||
str_replace:
|
||||
@ -103,36 +103,18 @@ resources:
|
||||
screen -dmS shaker-agent-screen shaker-agent --server-endpoint=$SERVER_ENDPOINT --agent-id=$AGENT_ID
|
||||
params:
|
||||
"$SERVER_ENDPOINT": { get_param: server_endpoint }
|
||||
"$AGENT_ID": {{ group.slave.name }}
|
||||
"$AGENT_ID": {{ agent.id }}
|
||||
|
||||
{{ group.master.name }}_port:
|
||||
{% if agent.mode == 'master' %}
|
||||
{{ agent.id }}_port:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network_id: { get_resource: north_private_net }
|
||||
fixed_ips:
|
||||
- subnet_id: { get_resource: north_private_subnet }
|
||||
security_groups: [{ get_resource: server_security_group }]
|
||||
|
||||
{{ group.slave.name }}:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
name: {{ group.slave.name }}
|
||||
image: { get_param: image }
|
||||
flavor: { get_param: flavor }
|
||||
availability_zone: "nova:{{ group.slave.node }}"
|
||||
networks:
|
||||
- port: { get_resource: {{ group.slave.name }}_port }
|
||||
user_data_format: RAW
|
||||
user_data:
|
||||
str_replace:
|
||||
template: |
|
||||
#!/bin/sh
|
||||
screen -dmS shaker-agent-screen shaker-agent --server-endpoint=$SERVER_ENDPOINT --agent-id=$AGENT_ID
|
||||
params:
|
||||
"$SERVER_ENDPOINT": { get_param: server_endpoint }
|
||||
"$AGENT_ID": {{ group.slave.name }}
|
||||
|
||||
{{ group.slave.name }}_port:
|
||||
{% else %}
|
||||
{{ agent.id }}_port:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network_id: { get_resource: south_private_net }
|
||||
@ -140,22 +122,24 @@ resources:
|
||||
- subnet_id: { get_resource: south_private_subnet }
|
||||
security_groups: [{ get_resource: server_security_group }]
|
||||
|
||||
{{ group.slave.name }}_floating_ip:
|
||||
{{ agent.id }}_floating_ip:
|
||||
type: OS::Neutron::FloatingIP
|
||||
properties:
|
||||
floating_network: { get_param: external_net }
|
||||
port_id: { get_resource: {{ group.slave.name }}_port }
|
||||
port_id: { get_resource: {{ agent.id }}_port }
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
outputs:
|
||||
{% for group in groups %}
|
||||
{{ group.master.name }}_ip:
|
||||
value: { get_attr: [ {{ group.master.name }}, networks, { get_attr: [north_private_net, name] }, 0 ] }
|
||||
{{ group.master.name }}_instance_name:
|
||||
value: { get_attr: [ {{ group.master.name }}, instance_name ] }
|
||||
{{ group.slave.name }}_ip:
|
||||
value: { get_attr: [ {{ group.slave.name }}_floating_ip, floating_ip_address ] }
|
||||
{{ group.slave.name }}_instance_name:
|
||||
value: { get_attr: [ {{ group.slave.name }}, instance_name ] }
|
||||
{% for agent in agents.value() %}
|
||||
{{ agent.id }}_instance_name:
|
||||
value: { get_attr: [ {{ agent.id }}, instance_name ] }
|
||||
{% if agent.mode == 'master' %}
|
||||
{{ agent.id }}_ip:
|
||||
value: { get_attr: [ {{ agent.id }}, networks, { get_attr: [east_private_net, name] }, 0 ] }
|
||||
{% else %}
|
||||
{{ agent.id }}_ip:
|
||||
value: { get_attr: [ {{ agent.id }}_floating_ip, floating_ip_address ] }
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
@ -43,17 +43,17 @@ resources:
|
||||
router_id: { get_resource: router }
|
||||
subnet_id: { get_resource: private_subnet }
|
||||
|
||||
{% for group in groups %}
|
||||
{% for agent in agents.values() %}
|
||||
|
||||
{{ group.master.name }}:
|
||||
{{ agent.id }}:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
name: {{ group.master.name }}
|
||||
name: {{ agent.id }}
|
||||
image: { get_param: image }
|
||||
flavor: { get_param: flavor }
|
||||
availability_zone: "nova:{{ group.master.node }}"
|
||||
availability_zone: "nova:{{ agent.node }}"
|
||||
networks:
|
||||
- port: { get_resource: {{ group.master.name }}_port }
|
||||
- port: { get_resource: {{ agent.id }}_port }
|
||||
user_data_format: RAW
|
||||
user_data:
|
||||
str_replace:
|
||||
@ -62,9 +62,9 @@ resources:
|
||||
screen -dmS shaker-agent-screen shaker-agent --server-endpoint=$SERVER_ENDPOINT --agent-id=$AGENT_ID
|
||||
params:
|
||||
"$SERVER_ENDPOINT": { get_param: server_endpoint }
|
||||
"$AGENT_ID": {{ group.slave.name }}
|
||||
"$AGENT_ID": {{ agent.id }}
|
||||
|
||||
{{ group.master.name }}_port:
|
||||
{{ agent.id }}_port:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network_id: { get_resource: private_net }
|
||||
@ -74,9 +74,9 @@ resources:
|
||||
{% endfor %}
|
||||
|
||||
outputs:
|
||||
{% for group in groups %}
|
||||
{{ group.master.name }}_ip:
|
||||
value: { get_attr: [ {{ group.master.name }}, networks, { get_attr: [private_net, name] }, 0 ] }
|
||||
{{ group.master.name }}_instance_name:
|
||||
value: { get_attr: [ {{ group.master.name }}, instance_name ] }
|
||||
{% for agent in agents.values() %}
|
||||
{{ agent.id }}_instance_name:
|
||||
value: { get_attr: [ {{ agent.id }}, instance_name ] }
|
||||
{{ agent.id }}_ip:
|
||||
value: { get_attr: [ {{ agent.id }}, networks, { get_attr: [private_net, name] }, 0 ] }
|
||||
{% endfor %}
|
||||
|
@ -26,6 +26,85 @@ from shaker.openstack.clients import openstack
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def generate_agents(compute_nodes, vm_accommodation, unique):
|
||||
cn_count = len(compute_nodes)
|
||||
iterations = cn_count
|
||||
if 'single_room' in vm_accommodation and 'pair' in vm_accommodation:
|
||||
iterations //= 2
|
||||
node_formulae = lambda x: compute_nodes[x % cn_count]
|
||||
|
||||
agents = {}
|
||||
|
||||
for i in range(iterations):
|
||||
if 'pair' in vm_accommodation:
|
||||
master_id = '%s_master_%s' % (unique, i)
|
||||
slave_id = '%s_slave_%s' % (unique, i)
|
||||
master = dict(id=master_id, mode='master', slave_id=slave_id)
|
||||
slave = dict(id=slave_id, mode='slave', master_id=master_id)
|
||||
|
||||
if 'single_room' in vm_accommodation:
|
||||
master['node'] = node_formulae(i * 2)
|
||||
slave['node'] = node_formulae(i * 2 + 1)
|
||||
elif 'double_room' in vm_accommodation:
|
||||
master['node'] = node_formulae(i)
|
||||
slave['node'] = node_formulae(i)
|
||||
elif 'mixed_room' in vm_accommodation:
|
||||
master['node'] = node_formulae(i)
|
||||
slave['node'] = node_formulae(i + 1)
|
||||
|
||||
agents[master['id']] = master
|
||||
agents[slave['id']] = slave
|
||||
else:
|
||||
if 'single_room' in vm_accommodation:
|
||||
agent_id = '%s_agent_%s' % (unique, i)
|
||||
agents[agent_id] = dict(id=agent_id, node=node_formulae(i),
|
||||
mode='alone')
|
||||
|
||||
return agents
|
||||
|
||||
|
||||
def _get_stack_values(stack_outputs, vm_name, params):
|
||||
result = {}
|
||||
for param in params:
|
||||
o = stack_outputs.get(vm_name + '_' + param)
|
||||
if o:
|
||||
result[param] = o
|
||||
return result
|
||||
|
||||
|
||||
def filter_agents(agents, stack_outputs):
|
||||
deployed_agents = {}
|
||||
|
||||
# first pass, ignore non-deployed
|
||||
for agent in agents.values():
|
||||
stack_values = _get_stack_values(stack_outputs, agent['id'],
|
||||
['ip', 'instance_name'])
|
||||
if not stack_values.get('instance_name'):
|
||||
LOG.info('Ignore non-deployed agent: %s', agent)
|
||||
continue
|
||||
|
||||
agent.update(stack_values)
|
||||
|
||||
# workaround of Nova bug 1422686
|
||||
if agent.get('mode') == 'slave' and not agent.get('ip'):
|
||||
LOG.info('IP address is missing in agent: %s', agent)
|
||||
continue
|
||||
|
||||
deployed_agents[agent['id']] = agent
|
||||
|
||||
# second pass, check pairs
|
||||
result = {}
|
||||
for agent in deployed_agents.values():
|
||||
if (agent.get('mode') == 'alone' or
|
||||
(agent.get('mode') == 'master' and
|
||||
agent.get('slave_id') in deployed_agents) or
|
||||
(agent.get('mode') == 'slave' and
|
||||
agent.get('master_id') in deployed_agents)):
|
||||
result[agent['id']] = agent
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class Deployment(object):
|
||||
def __init__(self, os_username, os_password, os_tenant_name, os_auth_url,
|
||||
os_region_name, server_endpoint, external_net, flavor_name,
|
||||
@ -45,87 +124,15 @@ class Deployment(object):
|
||||
self.stack_name = 'shaker_%s' % utils.random_string()
|
||||
self.stack_deployed = False
|
||||
|
||||
def _make_groups(self, vm_accommodation):
|
||||
compute_nodes = nova.get_available_compute_nodes(
|
||||
self.openstack_client.nova)
|
||||
cn_count = len(compute_nodes)
|
||||
iterations = cn_count
|
||||
if 'single_room' in vm_accommodation and 'pair' in vm_accommodation:
|
||||
iterations /= 2
|
||||
node_formulae = lambda x: compute_nodes[x % cn_count]
|
||||
|
||||
groups = []
|
||||
|
||||
for i in range(iterations):
|
||||
group = dict(
|
||||
master=dict(name=('%s_master_%s' % (self.stack_name, i))),
|
||||
slave=dict(name=('%s_slave_%s' % (self.stack_name, i))))
|
||||
|
||||
if 'pair' in vm_accommodation:
|
||||
if 'single_room' in vm_accommodation:
|
||||
group['master']['node'] = node_formulae(i * 2)
|
||||
group['slave']['node'] = node_formulae(i * 2 + 1)
|
||||
elif 'double_room' in vm_accommodation:
|
||||
group['master']['node'] = node_formulae(i)
|
||||
group['slave']['node'] = node_formulae(i)
|
||||
elif 'mixed_room' in vm_accommodation:
|
||||
group['master']['node'] = node_formulae(i)
|
||||
group['slave']['node'] = node_formulae(i + 1)
|
||||
else:
|
||||
if 'single_room' in vm_accommodation:
|
||||
group['master']['node'] = node_formulae(i)
|
||||
groups.append(group)
|
||||
|
||||
return groups
|
||||
|
||||
def _get_outputs(self, stack_outputs, vm_name, params):
|
||||
result = {}
|
||||
for param in params:
|
||||
o = stack_outputs.get(vm_name + '_' + param)
|
||||
if o:
|
||||
result[param] = o
|
||||
return result
|
||||
|
||||
def _make_agents(self, groups, outputs):
|
||||
agents = []
|
||||
|
||||
for group in groups:
|
||||
master = self._get_outputs(outputs, group['master']['name'],
|
||||
['ip', 'instance_name'])
|
||||
if not master.get('instance_name'):
|
||||
LOG.info('Group is not deployed: %s. Ignoring', group)
|
||||
continue
|
||||
|
||||
master.update(group['master'])
|
||||
master.update(dict(mode='master', id=group['master']['name']))
|
||||
|
||||
slave = self._get_outputs(outputs, group['slave']['name'],
|
||||
['ip', 'instance_name'])
|
||||
|
||||
# workaround of Nova bug 1422686
|
||||
if slave.get('instance_name') and not slave.get('ip'):
|
||||
LOG.info('Ignoring group because of missing IP: %s', group)
|
||||
continue
|
||||
|
||||
agents.append(master)
|
||||
|
||||
if slave.get('instance_name'):
|
||||
# slave is deployed
|
||||
slave.update(group['slave'])
|
||||
slave.update(dict(mode='slave', id=group['slave']['name']))
|
||||
|
||||
master['slave_id'] = slave['id']
|
||||
slave['master_id'] = master['id']
|
||||
agents.append(slave)
|
||||
|
||||
return agents
|
||||
|
||||
def _deploy_from_hot(self, specification):
|
||||
groups = self._make_groups(specification['vm_accommodation'])
|
||||
agents = generate_agents(
|
||||
nova.get_available_compute_nodes(self.openstack_client.nova),
|
||||
specification['vm_accommodation'],
|
||||
self.stack_name)
|
||||
|
||||
# render template by jinja
|
||||
vars_values = {
|
||||
'groups': groups,
|
||||
'agents': agents,
|
||||
'unique': self.stack_name,
|
||||
}
|
||||
heat_template = utils.read_file(specification['template'])
|
||||
@ -160,19 +167,18 @@ class Deployment(object):
|
||||
outputs = heat.get_stack_outputs(self.openstack_client.heat,
|
||||
stack['id'])
|
||||
|
||||
# convert groups into agents
|
||||
return self._make_agents(groups, outputs)
|
||||
return filter_agents(agents, outputs)
|
||||
|
||||
def deploy(self, deployment):
|
||||
agents = []
|
||||
agents = {}
|
||||
|
||||
if deployment.get('template'):
|
||||
# deploy topology specified by HOT
|
||||
agents += self._deploy_from_hot(deployment)
|
||||
agents.update(self._deploy_from_hot(deployment))
|
||||
|
||||
if deployment.get('agents'):
|
||||
# agents are specified statically
|
||||
agents += deployment.get('agents')
|
||||
agents.update(dict((a['id'], a) for a in deployment.get('agents')))
|
||||
|
||||
return agents
|
||||
|
||||
|
@ -129,29 +129,28 @@ def read_scenario():
|
||||
return scenario
|
||||
|
||||
|
||||
def _resolve_agent_ids(agents):
|
||||
id_to_agent = dict((ag['id'], ag) for ag in agents)
|
||||
for agent in agents:
|
||||
def _extend_agents(agents):
|
||||
for agent in agents.values():
|
||||
if agent.get('slave_id'):
|
||||
agent['slave'] = id_to_agent[agent['slave_id']]
|
||||
agent['slave'] = utils.copy_dict_kv(agents[agent['slave_id']])
|
||||
if agent.get('master_id'):
|
||||
agent['master'] = id_to_agent[agent['master_id']]
|
||||
agent['master'] = utils.copy_dict_kv(agents[agent['master_id']])
|
||||
|
||||
|
||||
def _pick_agents(agents, size):
|
||||
# tests are executed on master agents only
|
||||
agents = [a for a in agents if a['mode'] == 'master']
|
||||
# slave agents do not execute any tests
|
||||
agents = [a for a in agents.values() if a.get('mode') != 'slave']
|
||||
|
||||
if not size or size == 'full':
|
||||
yield agents
|
||||
elif size == 'linear_progression':
|
||||
for i in range(len(agents)):
|
||||
yield agents[:i]
|
||||
yield agents[:i + 1]
|
||||
elif size == 'quadratic_progression':
|
||||
n = len(agents)
|
||||
seq = [n]
|
||||
while n > 1:
|
||||
n /= 2
|
||||
n //= 2
|
||||
seq.append(n)
|
||||
seq.reverse()
|
||||
for i in seq:
|
||||
@ -159,12 +158,12 @@ def _pick_agents(agents, size):
|
||||
|
||||
|
||||
def execute(execution, agents):
|
||||
_resolve_agent_ids(agents)
|
||||
_extend_agents(agents)
|
||||
|
||||
message_queue = MessageQueue(cfg.CONF.server_endpoint)
|
||||
|
||||
quorum = Quorum(message_queue)
|
||||
quorum.wait_join(set(a['id'] for a in agents))
|
||||
quorum.wait_join(set(agents.keys()))
|
||||
|
||||
result = []
|
||||
|
||||
@ -216,34 +215,37 @@ def main():
|
||||
LOG.info('Logging enabled')
|
||||
conf.log_opt_values(LOG, std_logging.DEBUG)
|
||||
|
||||
scenario = read_scenario()
|
||||
deployment = deploy.Deployment(cfg.CONF.os_username,
|
||||
cfg.CONF.os_password,
|
||||
cfg.CONF.os_tenant_name,
|
||||
cfg.CONF.os_auth_url,
|
||||
cfg.CONF.os_region_name,
|
||||
cfg.CONF.server_endpoint,
|
||||
cfg.CONF.external_net,
|
||||
cfg.CONF.flavor_name,
|
||||
cfg.CONF.image_name)
|
||||
agents = deployment.deploy(scenario['deployment'])
|
||||
deployment = None
|
||||
try:
|
||||
scenario = read_scenario()
|
||||
deployment = deploy.Deployment(cfg.CONF.os_username,
|
||||
cfg.CONF.os_password,
|
||||
cfg.CONF.os_tenant_name,
|
||||
cfg.CONF.os_auth_url,
|
||||
cfg.CONF.os_region_name,
|
||||
cfg.CONF.server_endpoint,
|
||||
cfg.CONF.external_net,
|
||||
cfg.CONF.flavor_name,
|
||||
cfg.CONF.image_name)
|
||||
agents = deployment.deploy(scenario['deployment'])
|
||||
|
||||
if not agents:
|
||||
LOG.info('No agents deployed. Terminating.')
|
||||
return
|
||||
if not agents:
|
||||
LOG.info('No agents deployed. Terminating.')
|
||||
return
|
||||
|
||||
LOG.debug('Agents: %s', agents)
|
||||
LOG.debug('Agents: %s', agents)
|
||||
|
||||
result = execute(scenario['execution'], agents)
|
||||
LOG.debug('Result: %s', result)
|
||||
result = execute(scenario['execution'], agents)
|
||||
LOG.debug('Result: %s', result)
|
||||
|
||||
report.generate_report(cfg.CONF.report_template,
|
||||
cfg.CONF.report,
|
||||
dict(scenario=yaml.dump(scenario),
|
||||
agents=agents,
|
||||
result=result))
|
||||
|
||||
deployment.cleanup()
|
||||
report.generate_report(cfg.CONF.report_template,
|
||||
cfg.CONF.report,
|
||||
dict(scenario=yaml.dump(scenario),
|
||||
agents=agents.values(),
|
||||
result=result))
|
||||
finally:
|
||||
if deployment:
|
||||
deployment.cleanup()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -71,3 +71,7 @@ def read_uri(uri):
|
||||
|
||||
def random_string(length=6):
|
||||
return ''.join(random.sample('adefikmoprstuz', length))
|
||||
|
||||
|
||||
def copy_dict_kv(source):
|
||||
return dict((k, v) for k, v in source.items())
|
||||
|
@ -3,6 +3,7 @@
|
||||
# process, which may cause wedges in the gate later.
|
||||
|
||||
# Hacking already pins down pep8, pyflakes and flake8
|
||||
coverage>=3.6
|
||||
hacking>=0.8.0,<0.9
|
||||
mock>=1.0
|
||||
python-subunit>=0.0.18
|
||||
|
227
tests/test_deploy.py
Normal file
227
tests/test_deploy.py
Normal file
@ -0,0 +1,227 @@
|
||||
# Copyright (c) 2015 Mirantis Inc.
|
||||
#
|
||||
# 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 testtools
|
||||
|
||||
from shaker.engine import deploy
|
||||
|
||||
|
||||
class TestDeploy(testtools.TestCase):
|
||||
|
||||
def test_generate_agents_alone_single_room(self):
|
||||
unique = 'UU1D'
|
||||
expected = {
|
||||
'UU1D_agent_0': {
|
||||
'id': 'UU1D_agent_0',
|
||||
'mode': 'alone',
|
||||
'node': 'uno'},
|
||||
'UU1D_agent_1': {
|
||||
'id': 'UU1D_agent_1',
|
||||
'mode': 'alone',
|
||||
'node': 'dos'},
|
||||
}
|
||||
actual = deploy.generate_agents(['uno', 'dos'],
|
||||
['single_room'],
|
||||
unique)
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_generate_agents_pair_single_room(self):
|
||||
unique = 'UU1D'
|
||||
expected = {
|
||||
'UU1D_master_0': {
|
||||
'id': 'UU1D_master_0',
|
||||
'mode': 'master',
|
||||
'node': 'uno',
|
||||
'slave_id': 'UU1D_slave_0'},
|
||||
'UU1D_slave_0': {
|
||||
'id': 'UU1D_slave_0',
|
||||
'master_id': 'UU1D_master_0',
|
||||
'mode': 'slave',
|
||||
'node': 'dos'},
|
||||
}
|
||||
actual = deploy.generate_agents(['uno', 'dos', 'tre'],
|
||||
['pair', 'single_room'],
|
||||
unique)
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_generate_agents_pair_double_room(self):
|
||||
unique = 'UU1D'
|
||||
expected = {
|
||||
'UU1D_master_0': {
|
||||
'id': 'UU1D_master_0',
|
||||
'mode': 'master',
|
||||
'node': 'uno',
|
||||
'slave_id': 'UU1D_slave_0'},
|
||||
'UU1D_slave_0': {
|
||||
'id': 'UU1D_slave_0',
|
||||
'master_id': 'UU1D_master_0',
|
||||
'mode': 'slave',
|
||||
'node': 'uno'},
|
||||
'UU1D_master_1': {
|
||||
'id': 'UU1D_master_1',
|
||||
'mode': 'master',
|
||||
'node': 'dos',
|
||||
'slave_id': 'UU1D_slave_1'},
|
||||
'UU1D_slave_1': {
|
||||
'id': 'UU1D_slave_1',
|
||||
'master_id': 'UU1D_master_1',
|
||||
'mode': 'slave',
|
||||
'node': 'dos'},
|
||||
'UU1D_master_2': {
|
||||
'id': 'UU1D_master_2',
|
||||
'mode': 'master',
|
||||
'node': 'tre',
|
||||
'slave_id': 'UU1D_slave_2'},
|
||||
'UU1D_slave_2': {
|
||||
'id': 'UU1D_slave_2',
|
||||
'master_id': 'UU1D_master_2',
|
||||
'mode': 'slave',
|
||||
'node': 'tre'},
|
||||
}
|
||||
actual = deploy.generate_agents(['uno', 'dos', 'tre'],
|
||||
['pair', 'double_room'],
|
||||
unique)
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_generate_agents_pair_mixed_room(self):
|
||||
unique = 'UU1D'
|
||||
expected = {
|
||||
'UU1D_master_0': {
|
||||
'id': 'UU1D_master_0',
|
||||
'mode': 'master',
|
||||
'node': 'uno',
|
||||
'slave_id': 'UU1D_slave_0'},
|
||||
'UU1D_slave_0': {
|
||||
'id': 'UU1D_slave_0',
|
||||
'master_id': 'UU1D_master_0',
|
||||
'mode': 'slave',
|
||||
'node': 'dos'},
|
||||
'UU1D_master_1': {
|
||||
'id': 'UU1D_master_1',
|
||||
'mode': 'master',
|
||||
'node': 'dos',
|
||||
'slave_id': 'UU1D_slave_1'},
|
||||
'UU1D_slave_1': {
|
||||
'id': 'UU1D_slave_1',
|
||||
'master_id': 'UU1D_master_1',
|
||||
'mode': 'slave',
|
||||
'node': 'uno'},
|
||||
}
|
||||
actual = deploy.generate_agents(['uno', 'dos'],
|
||||
['pair', 'mixed_room'],
|
||||
unique)
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_filter_agents_all_deployed(self):
|
||||
agents = {
|
||||
'UU1D_agent_0': {
|
||||
'id': 'UU1D_agent_0',
|
||||
'mode': 'alone',
|
||||
'node': 'uno'},
|
||||
'UU1D_agent_1': {
|
||||
'id': 'UU1D_agent_1',
|
||||
'mode': 'alone',
|
||||
'node': 'dos'},
|
||||
}
|
||||
stack_outputs = {
|
||||
'UU1D_agent_0_ip': '10.0.0.1',
|
||||
'UU1D_agent_0_instance_name': 'i-000001',
|
||||
'UU1D_agent_1_ip': '10.0.0.2',
|
||||
'UU1D_agent_1_instance_name': 'i-000002',
|
||||
}
|
||||
filtered = deploy.filter_agents(agents, stack_outputs)
|
||||
self.assertEqual(agents, filtered)
|
||||
|
||||
def test_filter_agents_partial_deployed(self):
|
||||
agents = {
|
||||
'UU1D_agent_0': {
|
||||
'id': 'UU1D_agent_0',
|
||||
'mode': 'alone',
|
||||
'node': 'uno'},
|
||||
'UU1D_agent_1': {
|
||||
'id': 'UU1D_agent_1',
|
||||
'mode': 'alone',
|
||||
'node': 'dos'},
|
||||
}
|
||||
stack_outputs = {
|
||||
'UU1D_agent_0_ip': '10.0.0.1',
|
||||
'UU1D_agent_0_instance_name': 'i-000001',
|
||||
}
|
||||
expected = {'UU1D_agent_0': agents['UU1D_agent_0']}
|
||||
filtered = deploy.filter_agents(agents, stack_outputs)
|
||||
self.assertEqual(expected, filtered)
|
||||
|
||||
def test_filter_agents_pair_single_room(self):
|
||||
agents = {
|
||||
'UU1D_master_0': {
|
||||
'id': 'UU1D_master_0',
|
||||
'mode': 'master',
|
||||
'node': 'uno',
|
||||
'slave_id': 'UU1D_slave_0'},
|
||||
'UU1D_slave_0': {
|
||||
'id': 'UU1D_slave_0',
|
||||
'master_id': 'UU1D_master_0',
|
||||
'mode': 'slave',
|
||||
'node': 'dos'},
|
||||
}
|
||||
stack_outputs = {
|
||||
'UU1D_master_0_ip': '10.0.0.1',
|
||||
'UU1D_master_0_instance_name': 'i-000001',
|
||||
'UU1D_slave_0_ip': '10.0.0.2',
|
||||
'UU1D_slave_0_instance_name': 'i-000002',
|
||||
}
|
||||
expected = {'UU1D_master_0': agents['UU1D_master_0'],
|
||||
'UU1D_slave_0': agents['UU1D_slave_0']}
|
||||
|
||||
filtered = deploy.filter_agents(agents, stack_outputs)
|
||||
self.assertEqual(expected, filtered)
|
||||
|
||||
def test_filter_agents_pair_double_room_partially_deployed(self):
|
||||
agents = {
|
||||
'UU1D_master_0': {
|
||||
'id': 'UU1D_master_0',
|
||||
'mode': 'master',
|
||||
'node': 'uno',
|
||||
'slave_id': 'UU1D_slave_0'},
|
||||
'UU1D_slave_0': {
|
||||
'id': 'UU1D_slave_0',
|
||||
'master_id': 'UU1D_master_0',
|
||||
'mode': 'slave',
|
||||
'node': 'uno'},
|
||||
'UU1D_master_1': {
|
||||
'id': 'UU1D_master_1',
|
||||
'mode': 'master',
|
||||
'node': 'dos',
|
||||
'slave_id': 'UU1D_slave_1'},
|
||||
'UU1D_slave_1': {
|
||||
'id': 'UU1D_slave_1',
|
||||
'master_id': 'UU1D_master_1',
|
||||
'mode': 'slave',
|
||||
'node': 'dos'},
|
||||
}
|
||||
stack_outputs = {
|
||||
'UU1D_master_0_ip': '10.0.0.1',
|
||||
'UU1D_master_0_instance_name': 'i-000001',
|
||||
'UU1D_slave_0_ip': '10.0.0.2',
|
||||
'UU1D_slave_0_instance_name': 'i-000002',
|
||||
'UU1D_master_1_ip': '10.0.0.3',
|
||||
'UU1D_master_1_instance_name': 'i-000003',
|
||||
'UU1D_slave_1_instance_name': 'i-000004',
|
||||
}
|
||||
expected = {'UU1D_master_0': agents['UU1D_master_0'],
|
||||
'UU1D_slave_0': agents['UU1D_slave_0'], }
|
||||
|
||||
filtered = deploy.filter_agents(agents, stack_outputs)
|
||||
self.assertEqual(expected, filtered)
|
88
tests/test_server.py
Normal file
88
tests/test_server.py
Normal file
@ -0,0 +1,88 @@
|
||||
# Copyright (c) 2015 Mirantis Inc.
|
||||
#
|
||||
# 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 testtools
|
||||
|
||||
from shaker.engine import server
|
||||
|
||||
|
||||
class TestServer(testtools.TestCase):
|
||||
|
||||
def test_extend_agents(self):
|
||||
agents = {
|
||||
'UU1D_master_0': {
|
||||
'id': 'UU1D_master_0',
|
||||
'mode': 'master',
|
||||
'node': 'uno',
|
||||
'slave_id': 'UU1D_slave_0'},
|
||||
'UU1D_slave_0': {
|
||||
'id': 'UU1D_slave_0',
|
||||
'master_id': 'UU1D_master_0',
|
||||
'mode': 'slave',
|
||||
'node': 'dos'},
|
||||
}
|
||||
server._extend_agents(agents)
|
||||
self.assertDictContainsSubset(agents['UU1D_master_0']['slave'],
|
||||
agents['UU1D_slave_0'])
|
||||
self.assertDictContainsSubset(agents['UU1D_slave_0']['master'],
|
||||
agents['UU1D_master_0'])
|
||||
|
||||
def test_pick_agents_full(self):
|
||||
agents = {}
|
||||
for i in range(10):
|
||||
agents[i] = {
|
||||
'id': i, 'mode': 'alone', 'node': 'uno',
|
||||
}
|
||||
picked = [set(a['id'] for a in arr)
|
||||
for arr in server._pick_agents(agents, 'full')]
|
||||
self.assertEqual([set(range(10))], picked)
|
||||
|
||||
def test_pick_agents_full_filter_slaves(self):
|
||||
agents = {}
|
||||
for i in range(10):
|
||||
agents['master_%s' % i] = {
|
||||
'id': 'master_%s' % i, 'mode': 'master', 'node': 'uno',
|
||||
}
|
||||
agents['slave_%s' % i] = {
|
||||
'id': 'slave_%s' % i, 'mode': 'slave', 'node': 'uno',
|
||||
}
|
||||
picked = [set(a['id'] for a in arr)
|
||||
for arr in server._pick_agents(agents, 'full')]
|
||||
self.assertEqual([set('master_%s' % i for i in range(10))],
|
||||
picked)
|
||||
|
||||
def test_pick_agents_linear(self):
|
||||
agents = {}
|
||||
for i in range(10):
|
||||
agents[i] = {
|
||||
'id': i, 'mode': 'alone', 'node': 'uno',
|
||||
}
|
||||
picked = [set(a['id'] for a in arr)
|
||||
for arr in server._pick_agents(agents, 'linear_progression')]
|
||||
self.assertEqual([set(range(i + 1)) for i in range(0, 10)],
|
||||
picked)
|
||||
|
||||
def test_pick_agents_quadratic(self):
|
||||
agents = {}
|
||||
for i in range(10):
|
||||
agents[i] = {
|
||||
'id': i, 'mode': 'alone', 'node': 'uno',
|
||||
}
|
||||
picked = [set(a['id'] for a in arr)
|
||||
for arr in server._pick_agents(agents,
|
||||
'quadratic_progression')]
|
||||
self.assertEqual([set(range(1)), set(range(2)),
|
||||
set(range(5)), set(range(10))],
|
||||
picked)
|
Loading…
Reference in New Issue
Block a user