Fix build_edges routing to take into account order between events

- Previously order between events for same resource wasnt used
- Unit test that shows this behaviour will be made green
This commit is contained in:
Dmitry Shulyak 2015-09-20 11:04:10 +03:00
parent 28a3bbec4e
commit f0ccbb39d7
6 changed files with 34 additions and 30 deletions

1
.gitignore vendored
View File

@ -36,3 +36,4 @@ vagrant-settings.yaml
.solar_cli_uids
.ssh/
.cache

View File

@ -111,41 +111,47 @@ def bft_events_graph(start):
current_events = all_events(item)
for ev in current_events:
dg.add_edge(ev.parent, ev.dependent, label=ev.state)
dg.add_edge(ev.parent_node, ev.child_node, label=ev.state)
if ev.depend_node in visited:
if ev.child in visited:
continue
# it is possible to have events leading to same resource but
# different action
if ev.depend_node in stack:
if ev.child in stack:
continue
stack.append(ev.depend_node)
visited.add(ev.parent_node)
stack.append(ev.child)
visited.add(ev.parent)
return dg
def build_edges(changed_resources, changes_graph, events):
def build_edges(changes_graph, events):
"""
:param changed_resources: list of resource names that were changed
:param changes_graph: nx.DiGraph object with actions to be executed
:param events: {res: [controls.Event objects]}
"""
stack = changed_resources[:]
visited = []
events_graph = nx.MultiDiGraph()
for res_evts in events.values():
for ev in res_evts:
events_graph.add_edge(ev.parent_node, ev.child_node, event=ev)
stack = changes_graph.nodes()
visited = set()
while stack:
node = stack.pop()
event_name = stack.pop(0)
if node in events:
log.debug('Events %s for resource %s', events[node], node)
if event_name in events_graph:
log.debug('Next events after %s are %s', event_name, events_graph.successors(event_name))
else:
log.debug('No dependencies based on %s', node)
log.debug('No outgoing events based on %s', event_name)
if node not in visited:
for ev in events.get(node, ()):
ev.insert(stack, changes_graph)
if event_name not in visited:
for parent, child, data in events_graph.edges(event_name, data=True):
succ_ev = data['event']
succ_ev.insert(stack, changes_graph)
visited.append(node)
visited.add(event_name)
return changes_graph

View File

@ -101,8 +101,9 @@ class React(Event):
errmsg=None, type='solar_resource',
args=[self.child, self.child_action])
changes_graph.add_edge(self.parent_node, self.child_node, state=self.state)
changed_resources.append(self.child)
changes_graph.add_edge(
self.parent_node, self.child_node, state=self.state)
changed_resources.append(self.child_node)
class StateChange(Event):

View File

@ -90,7 +90,7 @@ def send_to_orchestration():
state_change = evapi.StateChange(res_uid, action)
state_change.insert(changed_nodes, dg)
evapi.build_edges(changed_nodes, dg, events)
evapi.build_edges(dg, events)
# what it should be?
dg.graph['name'] = 'system_log'

View File

@ -76,11 +76,10 @@ def nova_deps():
def test_nova_api_run_after_nova(nova_deps):
changed = ['nova', 'nova_api']
changes_graph = nx.DiGraph()
changes_graph.add_node('nova.run')
changes_graph.add_node('nova_api.run')
evapi.build_edges(changed, changes_graph, nova_deps)
evapi.build_edges(changes_graph, nova_deps)
assert changes_graph.successors('nova.run') == ['nova_api.run']
@ -89,10 +88,9 @@ def test_nova_api_react_on_update(nova_deps):
"""Test that nova_api:update will be called even if there is no changes
in nova_api
"""
changed = ['nova']
changes_graph = nx.DiGraph()
changes_graph.add_node('nova.update')
evapi.build_edges(changed, changes_graph, nova_deps)
evapi.build_edges(changes_graph, nova_deps)
assert changes_graph.successors('nova.update') == ['nova_api.update']
@ -115,7 +113,6 @@ def rmq_deps():
def test_rmq(rmq_deps):
changed = ['rmq.1', 'rmq.2', 'rmq.3', 'rmq_cluster.1', 'rmq_cluster.2', 'rmq_cluster.3']
changes_graph = nx.DiGraph()
changes_graph.add_node('rmq.1.run')
changes_graph.add_node('rmq.2.run')
@ -123,7 +120,7 @@ def test_rmq(rmq_deps):
changes_graph.add_node('rmq_cluster.1.create')
changes_graph.add_node('rmq_cluster.2.join')
changes_graph.add_node('rmq_cluster.3.join')
evapi.build_edges(changed, changes_graph, rmq_deps)
evapi.build_edges(changes_graph, rmq_deps)
assert set(changes_graph.successors('rmq_cluster.1.create')) == {
'rmq_cluster.2.join', 'rmq_cluster.3.join'}
@ -143,8 +140,8 @@ def test_riak():
evapi.React('riak_service2', 'join', 'success', 'riak_service1', 'commit')],
}
changed = ['riak_service1']
changes_graph = nx.DiGraph()
changes_graph = nx.MultiDiGraph()
changes_graph.add_node('riak_service1.run')
evapi.build_edges(changed, changes_graph, events)
evapi.build_edges(changes_graph, events)
assert set(changes_graph.predecessors('riak_service1.commit')) == {'riak_service2.join', 'riak_service3.join'}

View File

@ -229,7 +229,6 @@ class TestResourceORM(BaseResourceTest):
self.assertEqual(len(r.inputs.as_set()), 1)
<<<<<<< HEAD
class TestResourceInputORM(BaseResourceTest):
def test_backtrack_simple(self):
sample_meta_dir = self.make_resource_meta("""