From f9686f7c9872e5afc5a42e118018c00412f71b78 Mon Sep 17 00:00:00 2001 From: Przemyslaw Kaminski Date: Fri, 24 Apr 2015 12:39:05 +0200 Subject: [PATCH] Found, fixed and tested simple circular connection --- x/signals.py | 15 ++++++++++----- x/test/test_signals.py | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/x/signals.py b/x/signals.py index 78478d84..111afd68 100644 --- a/x/signals.py +++ b/x/signals.py @@ -19,9 +19,14 @@ class Connections(object): if src not in emitter.args: return + # TODO: implement general circular detection, this one is simple + if [emitter.name, src] in CLIENTS.get(receiver.name, {}).get(dst, []): + raise Exception('Attempted to create cycle in dependencies. Not nice.') + CLIENTS.setdefault(emitter.name, {}) CLIENTS[emitter.name].setdefault(src, []) - CLIENTS[emitter.name][src].append((receiver.name, dst)) + if [receiver.name, dst] not in CLIENTS[emitter.name][src]: + CLIENTS[emitter.name][src].append([receiver.name, dst]) utils.save_to_config_file(CLIENTS_CONFIG_KEY, CLIENTS) @@ -29,7 +34,7 @@ class Connections(object): def remove(emitter, src, receiver, dst): CLIENTS[emitter.name][src] = [ destination for destination in CLIENTS[emitter.name][src] - if destination != (receiver.name, dst) + if destination != [receiver.name, dst] ] utils.save_to_config_file(CLIENTS_CONFIG_KEY, CLIENTS) @@ -45,8 +50,8 @@ class Connections(object): for emitter_input, destinations in dest_dict.items(): for receiver_name, receiver_input in destinations: receiver = db.get_resource(receiver_name) - receiver.args[receiver_input].subscribe( - emitter.args[emitter_input]) + emitter.args[emitter_input].subscribe( + receiver.args[receiver_input]) @staticmethod def clear(): @@ -151,7 +156,7 @@ def assign_connections(receiver, connections): mappings = defaultdict(list) for key, dest in connections.iteritems(): resource, r_key = dest.split('.') - mappings[resource].append((r_key, key)) + mappings[resource].append([r_key, key]) for resource, r_mappings in mappings.iteritems(): connect(resource, receiver, r_mappings) diff --git a/x/test/test_signals.py b/x/test/test_signals.py index facb013c..ecfd099a 100644 --- a/x/test/test_signals.py +++ b/x/test/test_signals.py @@ -120,6 +120,27 @@ input: sample1.update({'ip': '10.0.0.3'}) self.assertEqual(sample2.args['ip'], sample.args['ip']) + def test_circular_connection_prevention(self): + # TODO: more complex cases + sample_meta_dir = self.make_resource_meta(""" +id: sample +handler: ansible +version: 1.0.0 +input: + ip: + """) + + sample1 = self.create_resource( + 'sample1', sample_meta_dir, {'ip': '10.0.0.1'} + ) + sample2 = self.create_resource( + 'sample2', sample_meta_dir, {'ip': '10.0.0.2'} + ) + xs.connect(sample1, sample2) + + with self.assertRaises(Exception): + xs.connect(sample2, sample1) + class TestListInput(base.BaseResourceTest): def test_list_input_single(self):