def test_can_merge_relationship_that_does_not_exist(self): alice = Node("Person", name="Alice") bob = Node("Person", name="Bob") ab = Relationship(alice, "KNOWS", bob) old_order = order(self.graph) old_size = size(self.graph) self.graph.merge(ab) assert remote(alice) assert remote(bob) assert remote(ab) assert self.graph.exists(alice | bob | ab) new_order = order(self.graph) new_size = size(self.graph) assert new_order == old_order + 2 assert new_size == old_size + 1
def test_can_construct_simple_path(self): alice = Node(name="Alice") bob = Node(name="Bob") path = Path(alice, "KNOWS", bob) assert order(path) == 2 assert size(path) == 1 assert len(path) == 1
def test_can_merge_long_straight_walkable(self): a = Node("Person", name="Alice") b = Node("Person", name="Bob") c = Node("Person", name="Carol") d = Node("Person", name="Dave") ab = Relationship(a, "KNOWS", b) cb = Relationship(c, "KNOWS", b) cd = Relationship(c, "KNOWS", d) self.graph.create(a) old_order = order(self.graph) old_size = size(self.graph) self.graph.merge(ab + cb + cd) new_order = order(self.graph) new_size = size(self.graph) assert new_order == old_order + 3 assert new_size == old_size + 3
def test_can_merge_relationship_where_all_exist(self): alice = Node("Person", name="Alice") self.graph.create( Relationship(alice, "KNOWS", Node("Person", name="Bob"))) bob = Node("Person", name="Bob") ab = Relationship(alice, "KNOWS", bob) old_order = order(self.graph) old_size = size(self.graph) self.graph.merge(ab) assert remote(alice) assert remote(bob) assert remote(ab) assert self.graph.exists(alice | bob | ab) new_order = order(self.graph) new_size = size(self.graph) assert new_order == old_order assert new_size == old_size
def test_control_path(self): base_node = [x for x in self._adcp.search('TEST_1', operator='=')][0] self.assertIsNotNone(base_node) graph = self._adcp.control_graph(base_node, 'to') # 1 GROUP : Nodes TEST_1 and TEST_10 to TEST_19 self.assertEqual(order(graph), 11) # 1 GROUP Links from (TEST_10 to TEST_19) to TEST_1 self.assertEqual(size(graph), 10)
def test_create_is_idempotent(self): self.graph.delete_all() a = Node() b = Node() r = Relationship(a, "TO", b) with self.graph.begin() as tx: tx.create(r) assert remote(a) assert remote(b) assert remote(r) assert order(self.graph) == 2 assert size(self.graph) == 1 with self.graph.begin() as tx: tx.create(r) assert remote(a) assert remote(b) assert remote(r) assert order(self.graph) == 2 assert size(self.graph) == 1
def test_control_path(self): base_node = [x for x in self._adcp.search('TEST_1', operator='=')][0] self.assertIsNotNone(base_node) graph = self._adcp.control_graph(base_node, 'to') # 9 * GROUPS (9 * 11) self.assertEqual(order(graph), 99) # 9 * GROUPS (9 * 10) + 10 Links + link DENY self.assertEqual(size(graph), 100) self.assertEqual(len([x for x in graph.nodes() if x['NO_LINKS']]), 1) self.assertEqual(len([x for x in graph.relationships() if x['DENY']]), 1)
def test_can_create_nodes_and_relationship_3(self): self.graph.delete_all() with self.graph.begin() as tx: a = Node("Person", name="Alice") b = Node("Person", name="Bob") r = Relationship(a, "KNOWS", b, since=1999) tx.create(a) tx.create(b) tx.create(r) assert remote(a) assert remote(b) assert remote(r) assert r.start_node() == a assert r.end_node() == b assert order(self.graph) == 2 assert size(self.graph) == 1
def test_can_create_nodes_and_relationship_4(self): self.graph.delete_all() with self.graph.begin() as tx: a = Node() b = Node() c = Node() ab = Relationship(a, "TO", b) bc = Relationship(b, "TO", c) ca = Relationship(c, "TO", a) tx.create(ab | bc | ca) assert remote(a) assert remote(b) assert remote(c) assert remote(ab) assert ab.start_node() == a assert ab.end_node() == b assert remote(bc) assert bc.start_node() == b assert bc.end_node() == c assert remote(ca) assert ca.start_node() == c assert ca.end_node() == a assert order(self.graph) == 3 assert size(self.graph) == 3
def control_graph(self, node: Record, direction: str) -> Optional[Subgraph]: graph = None labels = self.neo4j.relationship_types if '@' not in node['name']: labels = [x for x in labels if x not in EXCHANGE_LABELS] nodes = [node['id']] old_nodes = [] dir_arrow = '-[:{}]->'.format( '|'.join(labels)) if direction == 'from' else '<-[:{}]-'.format( '|'.join(labels)) # Step 1 : Find the control nodes (adjacent nodes) up to the defined depth start = timer() for i in range(0, self.__max_depth): query = 'MATCH path = (n)%s(m) WHERE id(n) IN {nodes} AND NOT id(m) IN {old_nodes} RETURN path, id(n) as n, id(m) as m' % dir_arrow result = self.neo4j.run(query, nodes=nodes, old_nodes=old_nodes) nodes = [] count = 0 while result.forward(): count += 1 cur = result.current() cur['path'].start_node()['id'] = cur['n'] cur['path'].end_node()['id'] = cur['m'] subgraph = cur.subgraph() if not cur['m'] in nodes: nodes.append(cur['m']) if graph is None: graph = subgraph else: graph |= subgraph old_nodes += nodes self.logger.info( '{} relations for {} nodes found at depth {}'.format( count, len(nodes), i + 1)) if count == 0: break end = timer() self.logger.debug('[perf] Control nodes : %f', (end - start)) if graph is None: self.logger.info('Empty graph') return graph self.logger.info('Initial graph: %d nodes - %d edges', order(graph), size(graph)) # Step 2 : Apply DENY ACE start = timer() filtered_graph = self.__denyace(graph, node['name']) end = timer() self.logger.debug('[perf] Deny ACE : %f', (end - start)) self.logger.info('Filtered graph: %d nodes - %d edges', order(filtered_graph), size(filtered_graph)) # Step 3 : Simplify the graph start = timer() simplified_graph = self.__simplify_graph(filtered_graph) end = timer() self.logger.debug('[perf] Simplify : %f', (end - start)) self.logger.info('Simplified graph: %d nodes - %d edges', order(simplified_graph), size(simplified_graph)) return simplified_graph
def test_can_construct_path_with_none_node(self): alice = Node(name="Alice") path = Path(alice, "KNOWS", None) assert order(path) == 2 assert size(path) == 1 assert len(path) == 1
def test_only_one_relationship_in_a_relationship(self): rel = Relationship({}, "KNOWS", {}) assert size(rel) == 1
def test_instance_subgraph_is_node_like(self): assert order(self.film_node) == 1 assert size(self.film_node) == 0