Example #1
0
 def test_simple_cycle(self):
     a = [0]
     b = [1]
     a.append(b)
     b.append(a)
     graph = ObjectGraph([a, b])
     self.assertCountEqual(graph.references(), [(a, b), (b, a)])
Example #2
0
 def test_single_edge(self):
     a = [0]
     b = [1]
     a.append(b)
     graph = ObjectGraph([a, b])
     self.assertEqual(len(graph), 2)
     self.assertEqual(graph.references(), [(a, b)])
Example #3
0
    def test_sccs(self):
        a, b, c, d = ["A"], ["B"], ["C"], ["D"]
        a.append(b)
        b.append(a)
        c.append(d)
        d.append(c)
        b.append(d)
        graph = ObjectGraph([a, b, c, d])

        sccs = graph.strongly_connected_components()
        self.assertEqual(len(sccs), 2)
        self.assertEqual(len(sccs[0]), 2)
        self.assertEqual(len(sccs[1]), 2)

        # Identify the two sccs.
        scc_ab = next(scc for scc in sccs if a in scc)
        scc_cd = next(scc for scc in sccs if c in scc)
        self.assertIn(a, scc_ab)
        self.assertIn(b, scc_ab)
        self.assertNotIn(c, scc_ab)
        self.assertNotIn(d, scc_ab)

        self.assertNotIn(a, scc_cd)
        self.assertNotIn(b, scc_cd)
        self.assertIn(c, scc_cd)
        self.assertIn(d, scc_cd)

        # Check that they've got the expected edges.
        self.assertEqual(scc_ab.children(a), [b])
        self.assertEqual(scc_ab.children(b), [a])
        self.assertEqual(scc_cd.children(c), [d])
        self.assertEqual(scc_cd.children(d), [c])
Example #4
0
 def test_multiple_edges(self):
     a = [0]
     b = [1]
     a.append(b)
     a.append(b)
     graph = ObjectGraph([a, b])
     self.assertEqual(graph.references(), [(a, b), (a, b)])
Example #5
0
 def test_long_chain(self):
     # The original recursive algorithms failed on long chains.
     objects = [[]]
     for _ in range(10000):
         new_object = []
         objects[-1].append(new_object)
         objects.append(new_object)
     refgraph = ObjectGraph(objects)
     sccs = refgraph.strongly_connected_components()
     self.assertEqual(len(sccs), len(objects))
Example #6
0
 def test_to_dot(self):
     a = []
     b = []
     a.append(b)
     graph = ObjectGraph([a, b])
     dot = graph.to_dot()
     self.assertIn('{} -> {} [label="item[0]"];'.format(id(a), id(b)), dot)
     self.assertIn('{} [label="list[1]"];'.format(id(a)), dot)
     self.assertIn('{} [label="list[0]"];'.format(id(b)), dot)
     self.assertIsInstance(dot, six.text_type)
Example #7
0
 def test_construction_from_iterator(self):
     a = [0]
     b = [1]
     a.append(b)
     b.append(a)
     objects = iter([a, b, a[0], b[0]])
     graph = ObjectGraph(objects)
     self.assertEqual(len(graph), 4)
     # Check that we get all the edges we expect.
     self.assertEqual(len(graph.children(a)), 2)
     self.assertEqual(len(graph.children(b)), 2)
Example #8
0
 def test_to_json(self):
     # XXX Needs a better test.  For now, just exercise the
     # to_json method.
     a = []
     b = []
     a.append(b)
     graph = ObjectGraph([a, b])
     json_graph = graph.to_json()
     self.assertIsInstance(json_graph, six.text_type)
     # Make sure that the result is valid json.
     json.loads(json_graph)
Example #9
0
    def test_analyze_simple_cycle(self):
        original_objects = gc.get_objects()
        create_cycle()
        new_objects = gc.get_objects()

        original_ids = set(map(id, original_objects))
        new_objects = [obj for obj in new_objects if id(obj) not in original_ids if obj is not original_objects]

        refgraph = ObjectGraph(new_objects)
        sccs = list(refgraph.strongly_connected_components())
        self.assertEqual(len(sccs), 1)
        self.assertEqual(len(sccs[0]), 4)
Example #10
0
 def test_ancestors(self):
     a = []
     b = []
     c = []
     d = []
     a.append(b)
     a.append(c)
     b.append(d)
     c.append(d)
     graph = ObjectGraph([a, b, c, d])
     self.assertCountEqual(graph.ancestors(a), [a])
     self.assertCountEqual(graph.ancestors(b), [b, a])
     self.assertCountEqual(graph.ancestors(c), [c, a])
     self.assertCountEqual(graph.ancestors(d), [d, b, c, a])
Example #11
0
 def test_descendants(self):
     a = []
     b = []
     c = []
     d = []
     a.append(b)
     a.append(c)
     b.append(d)
     c.append(d)
     graph = ObjectGraph([a, b, c, d])
     self.assertCountEqual(graph.descendants(a), [a, b, c, d])
     self.assertCountEqual(graph.descendants(b), [b, d])
     self.assertCountEqual(graph.descendants(c), [c, d])
     self.assertCountEqual(graph.descendants(d), [d])
Example #12
0
 def test_parents(self):
     a = []
     b = []
     c = []
     d = []
     a.append(b)
     a.append(c)
     b.append(d)
     c.append(d)
     graph = ObjectGraph([a, b, c, d])
     self.assertCountEqual(graph.parents(a), [])
     self.assertCountEqual(graph.parents(b), [a])
     self.assertCountEqual(graph.parents(c), [a])
     self.assertCountEqual(graph.parents(d), [b, c])
Example #13
0
 def test_children(self):
     a = []
     b = []
     c = []
     d = []
     a.append(b)
     a.append(c)
     b.append(d)
     c.append(d)
     graph = ObjectGraph([a, b, c, d])
     self.assertCountEqual(graph.children(a), [b, c])
     self.assertCountEqual(graph.children(b), [d])
     self.assertCountEqual(graph.children(c), [d])
     self.assertCountEqual(graph.children(d), [])
Example #14
0
def objects_reachable_from(obj):
    """
    Return graph of objects reachable from *obj* via ``gc.get_referrers``.

    Returns an :class:`~refcycle.object_graph.ObjectGraph` object holding all
    objects reachable from the given one by following the output of
    ``gc.get_referrers``.  Note that unlike the
    :func:`~refcycle.creators.snapshot` function, the output graph may
    include non-gc-tracked objects.

    """
    # Depth-first search.
    found = ObjectGraph.vertex_set()
    to_process = [obj]
    while to_process:
        obj = to_process.pop()
        found.add(obj)
        for referent in gc.get_referents(obj):
            if referent not in found:
                to_process.append(referent)
    return ObjectGraph(found)
Example #15
0
    def test_source_components(self):
        # Single source consisting of two objects.
        a, b, c, d = ["A"], ["B"], ["C"], ["D"]
        a.append(b)
        b.append(a)
        c.append(d)
        d.append(c)
        b.append(d)
        graph = ObjectGraph([a, b, c, d])
        sources = graph.source_components()
        self.assertEqual(len(sources), 1)
        source = sources[0]
        self.assertIn(a, source)
        self.assertIn(b, source)
        self.assertNotIn(c, source)
        self.assertNotIn(d, source)

        # Single source consisting of one object.
        a, b, c, d = ["A"], ["B"], ["C"], ["D"]
        a.append(b)
        b.append(d)
        c.append(a)
        graph = ObjectGraph([a, b, c, d])
        sources = graph.source_components()
        self.assertEqual(len(sources), 1)
        source = sources[0]
        self.assertNotIn(a, source)
        self.assertNotIn(b, source)
        self.assertIn(c, source)
        self.assertNotIn(d, source)

        # Multiple sources.
        a, b, c, d, e, f = ["A"], ["B"], ["C"], ["D"], ["E"], ["F"]
        a.append(b)
        b.append(d)
        c.append(a)
        e.append(d)

        graph = ObjectGraph([a, b, c, d, e, f])
        sources = graph.source_components()
        self.assertEqual(len(sources), 3)
Example #16
0
 def test_self_reference(self):
     a = [0]
     a.append(a)
     graph = ObjectGraph([a])
     self.assertEqual(graph.references(), [(a, a)])