示例#1
0
class TestGraph(unittest.TestCase):
    """ Test sort on graph.
    """

    def setUp(self):
        """ Initialize the TestGraph class.
        """
        self.objects = ["chaussures", "chaussettes", "slip", "pantalon",
                        "ceinture", "chemise", "veste", "cravate"]
        self.dependancies = [
            ("slip", "pantalon"),
            ("chemise", "cravate"),
            ("chemise", "pantalon"),
            ("pantalon", "ceinture"),
            ("chaussettes", "chaussures"),
            ("pantalon", "chaussures"),
            ("ceinture", "chaussures"),
            ("chemise", "veste"),
        ]
        self.sorted_objects = ["slip", "chaussettes", "chemise", "veste",
                               "pantalon", "ceinture", "chaussures", "cravate"]
        self.graph = Graph()
        for o in self.objects:
            self.graph.add_node(GraphNode(o, None))
        for d in self.dependancies:
            self.graph.add_link(d[0], d[1])

    def test_raises(self):
        """ Method to test the raises.
        """
        self.assertRaises(Exception, self.graph.add_node, object())
        self.assertEqual(self.graph.find_node("bad"), None)
        self.assertRaises(Exception, self.graph.remove_node, "bad")
        self.assertRaises(ValueError, self.graph.add_node,
                          self.graph._nodes[self.objects[0]])
        self.assertRaises(Exception, self.graph.add_link, "bad", "bad")
        self.assertRaises(Exception, self.graph.add_link,
                          self.sorted_objects[0], "bad")

    def test_static_sort(self):
        """ Method to test the static node sort.
        """
        static_sort = [node[0] for node in self.graph.topological_sort()]
        self.assertTrue(set(static_sort).issubset(self.sorted_objects))

    def test_dynamic_sort(self):
        """ Method to test the dynamic node sort.
        """
        nnil = sorted([node.name for node in self.graph.available_nodes()])
        self.assertEqual(nnil, ["chaussettes", "chemise", "slip"])
        self.graph.remove_node("slip")
        nnil = sorted([node.name for node in self.graph.available_nodes()])
        self.assertEqual(nnil, ["chaussettes", "chemise"])
        self.graph.remove_node("chemise")
        nnil = sorted([node.name for node in self.graph.available_nodes()])
        self.assertEqual(nnil, ["chaussettes", "cravate", "pantalon", "veste"])
        self.graph.remove_node("ceinture")

    def test_layout(self):
        """ Method to test the layout creation.
        """
        graph = Graph()
        self.assertEqual(sorted(graph.layout().keys()), [])
        graph.add_node(GraphNode("node1", None))
        self.assertEqual(sorted(graph.layout().keys()), ["node1"])
        graph.add_node(GraphNode("node2", None))
        self.assertEqual(sorted(graph.layout().keys()), ["node1", "node2"])
        self.assertTrue(set(self.graph.layout()).issubset(self.sorted_objects))
示例#2
0
文件: pbox.py 项目: AGrigis/casper
    def _create_graph(self, box, prefix="", flatten=True, add_io=False,
                      filter_inactive=False):
        """ Create a graph repesentation of a box.

        Parameters
        ----------
        box: Pbox or Bbox (mandatory)
            a box from which we want to extract the graph representation.
        prefix: str (optional, default '')
            a prefix for the box names.
        flatten: bool (optional, default True)
            If True iterate through the sub-graph structures.
        add_io: bool (optional, default False)
            If True add the 'inputs' and 'outputs' nodes.
        filter_inactive: bool (optional, default False)
            If True filter inactive boxes.

        Returns
        -------
        graph: Graph
            a graph representation of the input box.
        """
        # Add the graph nodes
        graph = Graph()
        pboxes = {}
        for box_name in list(box._boxes.keys()):
            inner_box = box._boxes[box_name]
            if filter_inactive and not inner_box.active:
                continue
            if isinstance(inner_box, Pbox):
                if flatten:
                    inner_prefix = prefix + "{0}.".format(box_name)
                    sub_graph, inlinkreps, outlinkreps = self._create_graph(
                        inner_box, inner_prefix,
                        filter_inactive=filter_inactive)
                    graph.add_graph(sub_graph)
                    pboxes[box_name] = (sub_graph, inlinkreps, outlinkreps)
                else:
                    graph.add_node(GraphNode(prefix + box_name, inner_box))
            elif isinstance(inner_box, Bbox) or isinstance(inner_box, Ibox):
                graph.add_node(GraphNode(prefix + box_name, inner_box))
            else:
                raise ValueError(
                    "'{0}' is not a valid box type. Allowed types are '{1}', "
                    "'{2}' or '{3}'.".format(type(inner_box), Bbox, Pbox,
                                             Ibox))

        # Add io nodes if requested
        if add_io:
            graph.add_node(GraphNode(prefix + "inputs", None))
            graph.add_node(GraphNode(prefix + "outputs", None))

        # Add the graph links
        input_linkreps = {}
        output_linkreps = {}
        for linkrep in box._links:

            # Parse link
            src_box_name, src_ctrl, dest_box_name, dest_ctrl = parse_link(
                linkrep)

            # Pbox special case: flatening
            if src_box_name in pboxes:
                src_box_name = "{0}.{1}".format(
                    src_box_name, pboxes[src_box_name][2][src_ctrl][0])
            if dest_box_name in pboxes:
                dest_box_name = "{0}.{1}".format(
                    dest_box_name, pboxes[dest_box_name][1][dest_ctrl][0])

            # Add an inner link, skip inpout/output links, check that no
            # inactive box is involved in this link
            if src_box_name == "":
                input_linkreps[src_ctrl] = (dest_box_name, dest_ctrl)
                if add_io:
                    graph.add_link(prefix + "inputs", prefix + dest_box_name)
            elif dest_box_name == "":
                output_linkreps[dest_ctrl] = (src_box_name, src_ctrl)
                if add_io:
                    graph.add_link(prefix + src_box_name, prefix + "outputs")
            elif (filter_inactive and (
                    prefix + src_box_name not in graph._nodes or
                    prefix + dest_box_name not in graph._nodes)):
                continue
            else:
                graph.add_link(prefix + src_box_name, prefix + dest_box_name)
        return graph, input_linkreps, output_linkreps