def snapshot(self, directed_graph: DirectedGraph):
        """ Take a snapshot of the current directed graph

        Args:
            directed_graph (DirectedGraph): The directed graph
        """

        dg = nx.DiGraph()
        vertex: Vertex
        for vertex in directed_graph.get_vertices():
            dg.add_node(vertex.get_label())

        edge: Edge
        for edge in directed_graph.get_edges():
            dg.add_edge(edge.get_tail().get_label(),
                        edge.get_head().get_label())

        edges = [(u, v) for (u, v, _) in dg.edges(data=True)]

        pos = nx.planar_layout(dg)

        activated_nodes = self.get_nodes_by_state(directed_graph,
                                                  VizTracing.ACTIVATED)
        visisted_nodes =\
            self.get_nodes_by_state(directed_graph,
                                    VizTracing.VISITED) -\
            activated_nodes

        default_nodes = {vertex.get_label()
                         for vertex in directed_graph.get_vertices()} -\
            visisted_nodes - activated_nodes

        self.draw_nodes(dg, pos, list(activated_nodes), directed_graph,
                        VizTracing.ACTIVATED)
        self.draw_nodes(dg, pos, list(visisted_nodes), directed_graph,
                        VizTracing.VISITED)
        self.draw_nodes(dg, pos, list(default_nodes), directed_graph,
                        VizTracing.DEFAULT)

        nx.draw_networkx_edges(G=dg,
                               pos=pos,
                               edgelist=edges,
                               width=VizTracingNetworkx.EDGE_WIDTH,
                               edge_color=VizTracingNetworkx.EDGE_COLOR,
                               style=VizTracingNetworkx.EDGE_STYLE,
                               arrowsize=VizTracingNetworkx.EDGE_ARROW_SIZE)

        nx.draw_networkx_labels(
            G=dg,
            pos=pos,
            font_size=VizTracingNetworkx.NODE_FONT_SIZE,
            font_family=VizTracingNetworkx.NODE_FONT_FAMILY)

        plt.axis('off')
        plt.show()
        a = 100
    def get_nodes_by_state(self, directed_graph: DirectedGraph,
                           state: str) -> Set[str]:

        return {
            vertex.get_label()
            for vertex in directed_graph.get_vertices()
            if vertex.has_enabled_attr(state)
        }
    def deactivate_graph(self, directed_graph: DirectedGraph):
        """ Method that resets the whole graph

        Args:
            directed_graph (DirectedGraph): The directed graph
        """

        for v in directed_graph.get_vertices():
            self.reset_status(v, VizTracing.ACTIVATED)
    def reset_attrs(self, directed_graph: DirectedGraph):
        """ Method that resets all attributes of a vertex

        Args:
            directed_graph (DirectedGraph): The directed graph
            vertex(Vertex): the vertex to be activated
        """

        for v in directed_graph.get_vertices():
            v.reset_attrs()
    def activate_graph(self, directed_graph: DirectedGraph):
        """ Method that sets the attribute "active" of all vertices to
        true.

        Args:
            directed_graph (DirectedGraph): The directed graph
        """

        for v in directed_graph.get_vertices():
            self.set_status(v, VizTracing.ACTIVATED)
Beispiel #6
0
    def snapshot(self, directed_graph: DirectedGraph):
        """ Take a snapshot of the current directed graph

        Args:
            directed_graph (DirectedGraph): The directed graph
        """

        graph = Digraph(format=VizTracingGraphviz.IMAGE_TYPE)
        for vertex in directed_graph.get_vertices():
            found = False
            default_state: Union[Mapping[str, str], None] = {}
            for state in self.vertex_states:
                attr_name, attr_values = next(iter(state.items()))
                if attr_name != VizTracing.DEFAULT and\
                        vertex.get_attr(attr_name):
                    graph.node(name=str(vertex.get_label()),
                               label=self.get_extended_label(vertex),
                               _attributes=None,
                               **attr_values)
                    found = True
                    break
                elif attr_name == VizTracing.DEFAULT:
                    default_state = attr_values
            if not found:
                graph.node(name=str(vertex.get_label()),
                           label=self.get_extended_label(vertex),
                           _attributes=None,
                           **default_state or {})

            for edge in vertex.get_edges():
                found = False
                default_state: Union[Mapping[str, str], None] = {}
                for state in self.edge_states:
                    attr_name, attr_values = next(iter(state.items()))
                    if attr_name != VizTracing.DEFAULT and \
                            edge.get_attr(attr_name):
                        graph.edge(str(edge.get_tail().get_label()),
                                   str(edge.get_head().get_label()),
                                   label=None,
                                   _attributes=None,
                                   **attr_values)
                        found = True
                        break
                    elif attr_name == VizTracing.DEFAULT:
                        default_state = attr_values
                if not found:
                    graph.edge(str(edge.get_tail().get_label()),
                               str(edge.get_head().get_label()))
        graph.render(
            path.join(
                self.path, VizTracingGraphviz.IMAGE_NAME_PREFIX +
                ("{:04d}".format(self.snapshot_no))))
        self.snapshot_no += 1
    def change_activated_vertex(self, directed_graph: DirectedGraph,
                                vertex: Vertex):
        """ Method that sets the attribute "active" of the vertex to true.
        It deactivates all other vertices

        Args:
            directed_graph (DirectedGraph): The directed graph
            vertex(Vertex): the vertex to be activated
        """

        self.set_status(vertex, VizTracing.ACTIVATED)
        for v in directed_graph.get_vertices():
            if str(v.get_label()) != str(vertex.get_label()):
                self.reset_status(v, VizTracing.ACTIVATED)
    def create_node_buckets(self, directed_graph: DirectedGraph) ->\
            Dict[str, List[Vertex]]:
        """ Create different buckets that fit nodes with the
        same characteristics

        Args:
            directed_graph: The directed graph

        Returns:
            A dictionary that contains lists of vertices per
            characteristic
        """

        mapping: Dict[str, List[Vertex]] = dict()
        for vertex in directed_graph.get_vertices():
            if VizTracing.ACTIVATED in vertex.get_attrs():
                mapping[VizTracing.ACTIVATED].append(vertex)
            elif VizTracing.VISITED in vertex.get_attrs():
                mapping[VizTracing.VISITED].append(vertex)
            else:
                mapping[VizTracing.DEFAULT].append(vertex)

        return mapping
class TestDirectedGraph(unittest.TestCase):

    def setUp(self):
        self.vertices = {0: [1], 1: [2, 3], 2: [3],
                         3: [4, 6], 4: [5, 6], 5: [5], 6: [6]}
        self.directed_graph = DirectedGraph(self.vertices)

    def test_init(self):
        self.assertEqual(len(self.vertices.keys()),
                         self.directed_graph.get_vertices_count())

    def test_str(self):
        print(self.directed_graph)

    def test_one_vertex_self_loop(self):
        self.vertices = {0: [0]}
        self.directed_graph = DirectedGraph(self.vertices)

    def test_add_vertex(self):
        label = 7
        self.directed_graph.add_vertex(label)
        vertex = self.directed_graph.get_vertex(label)
        self.assertIsNotNone(vertex)
        self.assertEqual(vertex.get_outdegree(), 0)
        self.assertEqual(vertex.get_indegree(), 0)
        self.assertListEqual(vertex.get_edge_heads(), list())

    def test_add_duplicate_vertex(self):
        label = 7
        self.directed_graph.add_vertex(label)
        with self.assertRaises(RuntimeError):
            self.directed_graph.add_vertex(label)

    def test_add_heads(self):
        vertex_to_test = 7
        self.directed_graph.add_vertex(vertex_to_test)
        vertex = self.directed_graph.get_vertex(vertex_to_test)
        no_heads = 3
        for i in range(no_heads):
            vertex.add_edge(self.directed_graph.get_vertex(i))
        self.assertEqual(len(vertex.get_edge_heads()), no_heads)
        self.assertEqual(vertex.get_outdegree(), len(vertex.get_edge_heads()))

    def test_outdegree(self):
        vertex = self.directed_graph.get_vertex(1)
        self.assertEqual(vertex.get_outdegree(), len(vertex.get_edge_heads()))

    def test_indegree(self):
        vertex_to_test = 6
        self.vertices = {0: [1], 1: [2, 3], 2: [3], 3: [4, vertex_to_test],
                         4: [5, vertex_to_test], 5: [5], vertex_to_test: []}
        self.directed_graph = DirectedGraph(self.vertices)
        vertex = self.directed_graph.get_vertex(vertex_to_test)
        self.assertEqual(vertex.get_indegree(), 2)

    def test_get_reversed_graph(self):
        self.directed_graph = DirectedGraph(self.vertices)
        self.directed_graph.reversed(inplace=True)
        self.check_big_reversed_graph(self.directed_graph)

    def test_get_reversed_small_graph_inplace_false(self):
        self.vertices = {0: [1], 1: [2], 2: []}
        self.directed_graph = DirectedGraph(self.vertices)
        reversed_graph = self.directed_graph.reversed(inplace=False)
        self.assertTrue(reversed_graph !=
                        self.directed_graph.get_direct_graph_core())
        self.check_small_reversed_graph(reversed_graph)

    def test_get_reversed_small_graph_inplace_true(self):
        self.vertices = {0: [1], 1: [2], 2: []}
        self.directed_graph = DirectedGraph(self.vertices)
        reversed_graph = self.directed_graph.reversed(inplace=True)
        self.assertTrue(reversed_graph ==
                        self.directed_graph.get_direct_graph_core())
        self.check_small_reversed_graph(reversed_graph)

    def test_ordering(self):
        self.vertices = {5: [5], 1: [2, 3], 2: [3],
                         3: [4, 6], 4: [5, 6], 0: [1], 6: [6]}
        self.directed_graph = DirectedGraph(self.vertices,
                                            AlgorithmOrdering.ASC)
        self.assertTrue(next(iter(
            self.directed_graph.get_vertices())).get_label() == 0)

        self.directed_graph = DirectedGraph(self.vertices,
                                            AlgorithmOrdering.DESC)
        self.assertTrue(next(iter(
            self.directed_graph.get_vertices())).get_label() == 6)

    def tearDown(self):
        pass

    def check_small_reversed_graph(self, reversed_graph):
        self.assertTrue(self.amount_of_tails2(reversed_graph, 2) == 1)
        self.assertTrue(self.has_vertex_label_as_head2(reversed_graph, 2, 1))
        self.assertTrue(self.amount_of_tails2(reversed_graph, 1) == 1)
        self.assertTrue(self.has_vertex_label_as_head2(reversed_graph, 1, 0))
        self.assertTrue(self.amount_of_tails2(reversed_graph, 0) == 0)

    def check_big_reversed_graph(self, reversed_graph):
        self.assertTrue(self.amount_of_tails2(reversed_graph, 6) == 3)
        self.assertTrue(self.has_vertex_label_as_head2(reversed_graph, 6, 4))
        self.assertTrue(self.has_vertex_label_as_head2(reversed_graph, 6, 6))
        self.assertTrue(self.has_vertex_label_as_head2(reversed_graph, 6, 3))
        self.assertTrue(self.amount_of_tails2(reversed_graph, 5) == 2)
        self.assertTrue(self.has_vertex_label_as_head2(reversed_graph, 5, 5))
        self.assertTrue(self.has_vertex_label_as_head2(reversed_graph, 5, 4))
        self.assertTrue(self.amount_of_tails2(reversed_graph, 4) == 1)
        self.assertTrue(self.has_vertex_label_as_head2(reversed_graph, 4, 3))
        self.assertTrue(self.amount_of_tails2(reversed_graph, 3) == 2)
        self.assertTrue(self.has_vertex_label_as_head2(reversed_graph, 3, 1))
        self.assertTrue(self.has_vertex_label_as_head2(reversed_graph, 3, 2))
        self.assertTrue(self.amount_of_tails2(reversed_graph, 2) == 1)
        self.assertTrue(self.has_vertex_label_as_head2(reversed_graph, 2, 1))
        self.assertTrue(self.amount_of_tails2(reversed_graph, 1) == 1)
        self.assertTrue(self.has_vertex_label_as_head2(reversed_graph, 1, 0))
        self.assertTrue(self.amount_of_tails2(reversed_graph, 0) == 0)

    def has_vertex_label_as_head(
            self,
            graph: DirectedGraphCore,
            vertex_label: Union[str, int],
            head_label: Union[str, int]) -> bool:
        return True if head_label in \
            {v.get_label() for v in
                graph.get_vertex(vertex_label).get_edge_heads()} \
            else False

    def amount_of_heads(
            self,
            graph: DirectedGraphCore,
            vertex_label: Union[str, int]) -> int:
        return len(graph.get_vertex(vertex_label).get_edge_heads())

    def has_vertex_label_as_head2(
            self,
            graph: DirectedGraph,
            vertex_label: Union[str, int],
            head_label: Union[str, int]) -> bool:
        return True if head_label in \
            {v.get_label() for v in
                graph.get_vertex(vertex_label).get_edge_heads()} \
            else False

    def amount_of_tails2(
            self,
            graph: DirectedGraph,
            vertex_label: Union[str, int]) -> int:
        return len(graph.get_vertex(vertex_label).get_edge_heads())
Beispiel #10
0
class TestVizTracingGraphviz(unittest.TestCase):

    DIGRAPH_VIZ = "digraph_viz"
    RESOURCES_PATH = "python-test-resources"
    RESOURCES_PATH_RECYCLE = RESOURCES_PATH + "/recycle"

    @classmethod
    def setUpClass(cls):
        pt.clean_dir_in_user_home(
            TestVizTracingGraphviz.RESOURCES_PATH_RECYCLE)

    def setUp(self):
        self.vertices = {
            0: [1],
            1: [2, 3],
            2: [3],
            3: [4, 6],
            4: [5, 6],
            5: [5],
            6: [6]
        }
        self.directed_graph = DirectedGraph(self.vertices)

    @unittest.skip
    def test_VizTracingGraphviz_vertex_only(self):
        self.vertices = {
            0: [1],
            1: [2, 3],
            2: [3],
            3: [4, 6],
            4: [5, 6],
            5: [5],
            6: [6]
        }
        self.directed_graph = DirectedGraph(self.vertices)
        vertex_1 = self.directed_graph.get_vertex(1)
        vertex_1.set_attr("activated", True)
        vertex_2 = self.directed_graph.get_vertex(2)
        vertex_2.set_attr("in_cycle", True)
        dir = TestVizTracingGraphviz.RESOURCES_PATH_RECYCLE + "/" + \
            inspect.currentframe().f_code.co_name
        pt.create_dir_in_user_home(dir)
        viz_cyclic_tracing: VizCyclicTracing = VizCyclicTracing(
            path=pt.get_dir_in_user_home(dir),
            directed_graph=self.directed_graph,
            vertex_states=[{
                VizTracing.ACTIVATED: {
                    "fillcolor": "red",
                    "style": "filled"
                }
            }, {
                VizCyclicTracing.IN_CYCLE: {
                    "fillcolor": "blue",
                    "style": "filled"
                }
            }])
        viz_cyclic_tracing.snapshot(self.directed_graph)
        self.assertTrue(True)

    @unittest.skip
    def test_VizTracingGraphviz_activate_vertex(self):
        self.vertices = {
            0: [1],
            1: [2, 3],
            2: [3],
            3: [4, 6],
            4: [5, 6],
            5: [5],
            6: [6]
        }
        self.directed_graph = DirectedGraph(self.vertices)
        vertex_1 = self.directed_graph.get_vertex(1)
        dir = TestVizTracingGraphviz.RESOURCES_PATH_RECYCLE + "/" + \
            inspect.currentframe().f_code.co_name
        viz_cyclic_tracing: VizCyclicTracing = VizCyclicTracing(
            path=pt.get_dir_in_user_home(dir),
            directed_graph=self.directed_graph,
            vertex_states=[{
                VizTracing.ACTIVATED: {
                    "fillcolor": "red",
                    "style": "filled"
                }
            }, {
                VizCyclicTracing.IN_CYCLE: {
                    "fillcolor": "blue",
                    "style": "filled"
                }
            }])
        viz_cyclic_tracing.change_activated_vertex(self.directed_graph,
                                                   vertex_1)
        for vertex in self.directed_graph.get_vertices():
            if str(vertex_1.get_label()) == str(vertex.get_label()):
                self.assertTrue(vertex.get_attr(VizTracing.ACTIVATED))
            else:
                self.assertFalse(vertex.get_attr(VizTracing.ACTIVATED))

    @unittest.skip
    def test_VizTracingGraphviz_set_status(self):
        self.vertices = {
            0: [1],
            1: [2, 3],
            2: [3],
            3: [4, 6],
            4: [5, 6],
            5: [5],
            6: [6]
        }
        self.directed_graph = DirectedGraph(self.vertices)
        vertex_5 = self.directed_graph.get_vertex(5)
        vertex_6 = self.directed_graph.get_vertex(6)
        dir = TestVizTracingGraphviz.RESOURCES_PATH_RECYCLE + "/" + \
            inspect.currentframe().f_code.co_name
        viz_cyclic_tracing: VizCyclicTracing = VizCyclicTracing(
            path=pt.get_dir_in_user_home(dir),
            directed_graph=self.directed_graph,
            vertex_states=[{
                VizTracing.ACTIVATED: {
                    "fillcolor": "red",
                    "style": "filled"
                }
            }, {
                VizCyclicTracing.IN_CYCLE: {
                    "fillcolor": "blue",
                    "style": "filled"
                }
            }])
        viz_cyclic_tracing.set_status(vertex_5, VizCyclicTracing.IN_CYCLE)
        viz_cyclic_tracing.set_status(vertex_6, VizCyclicTracing.IN_CYCLE)
        for vertex in self.directed_graph.get_vertices():
            if str(vertex_5.get_label()) == str(vertex.get_label()) or \
                    str(vertex_6.get_label()) == str(vertex.get_label()):
                self.assertTrue(vertex.get_attr(VizCyclicTracing.IN_CYCLE))
            else:
                self.assertFalse(vertex.get_attr(VizCyclicTracing.IN_CYCLE))

    @unittest.skip
    def test_VizTracingGraphviz_snapshot(self):
        dir = TestVizTracingGraphviz.RESOURCES_PATH_RECYCLE + "/" + \
            inspect.currentframe().f_code.co_name
        viz_cyclic_tracing: VizCyclicTracing = VizCyclicTracing(
            path=pt.get_dir_in_user_home(dir),
            directed_graph=self.directed_graph)
        viz_cyclic_tracing.snapshot(self.directed_graph)
        self.assertTrue(
            os.path.exists(
                path.join(
                    pt.get_dir_in_user_home(dir),
                    VizCyclicTracing.IMAGE_NAME_PREFIX +
                    ("{:04d}".format(viz_cyclic_tracing.snapshot_no - 1)) +
                    "." + VizCyclicTracing.IMAGE_TYPE)))
        viz_cyclic_tracing.snapshot(self.directed_graph)
        self.assertTrue(
            os.path.exists(
                path.join(
                    pt.get_dir_in_user_home(dir),
                    VizCyclicTracing.IMAGE_NAME_PREFIX +
                    ("{:04d}".format(viz_cyclic_tracing.snapshot_no - 1)) +
                    "." + VizCyclicTracing.IMAGE_TYPE)))

    def tearDown(self):
        dir = TestVizTracingGraphviz.RESOURCES_PATH_RECYCLE
        pt.clean_dir_in_user_home(dir)
        self.assertFalse(os.path.exists(pt.get_dir_in_user_home(dir)))