Skip to content

Commit

Permalink
Fix bug with inverting dependencies
Browse files Browse the repository at this point in the history
We calculate the dependency graph after updating the database to contain
new dependencies. If any dependencies are inverted in the template with
respect to the old one, this could cause a circular dependency as both
sets of reverse dependencies were added.

The two possible solutions are to calculate the dependencies before
updating any of the existing resources, or to ignore the 'requirers'
list (which has been updated with the new template data) and just base
the reverse dependencies on the requirements list. I chose the latter
because it makes the code tidier.
  • Loading branch information
zaneb committed Dec 4, 2014
1 parent 673ec99 commit 786f367
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
3 changes: 0 additions & 3 deletions converge/stack.py
Expand Up @@ -71,9 +71,6 @@ def make_graph_key(res_name):
deps += (key, False), None

# Note: reversed edges as this is the cleanup part of the graph
for requirer in rsrc.requirers:
if requirer in existing_resources:
deps += (key, False), (requirer, False)
for requirement in rsrc.requirements:
if requirement in existing_resources:
deps += (requirement, False), (key, False)
Expand Down
28 changes: 28 additions & 0 deletions scenarios/update_replace_invert_deps.py
@@ -0,0 +1,28 @@
def check_resource_counts(count_map):
for name, count in count_map.items():
test.assertEqual(count,
len(list(reality.resources_by_logical_name(name))))


example_template = Template({
'A': RsrcDef({'!a': 'initial'}, []),
'B': RsrcDef({'!b': 'first'}, ['A']),
})
engine.create_stack('foo', example_template)
engine.noop(4)
engine.call(verify, example_template)

example_template_inverted = Template({
'A': RsrcDef({'!a': 'updated'}, ['B']),
'B': RsrcDef({'!b': 'second'}, []),
})
engine.update_stack('foo', example_template_inverted)
engine.noop(4)
engine.call(check_resource_counts, {'A': 2, 'B': 1})
engine.noop(2)
engine.call(verify, example_template_inverted)
engine.call(check_resource_counts, {'A': 1, 'B': 1})

engine.delete_stack('foo')
engine.noop(3)
engine.call(verify, Template({}))

0 comments on commit 786f367

Please sign in to comment.