class Test_baseclass:
    # noinspection PyPep8Naming
    def tearDown(self):
        pass

    def setup(self):
        self.db = FlowDatabase("test")
        self.db.collection.delete_many({})
        self.db.add_node({"name": "a", "dependencies": []})
        self.db.start_flow()
        self.flow = SampleFlow("test-flow.py")

    def test_runmethod(self):
        result = self.flow._run("a")
        assert result["name"] == "a"

    def test_database_insertion(self):
        result = self.flow._run("a")
        dbresult = self.db.get_node("a")
        assert dbresult.result["name"] == "a"
        assert dbresult.result["result"]["everything"] == "ok"
Example #2
0
class Test_flowdb:
    def tearDown(self):
        pass

    def setup(self):
        self.db = FlowDatabase("test")
        self.db.collection.delete_many({})

    def test_add_node(self):
        test_node = Node("test test")
        self.db.add_node(test_node.toDict())
        num_nodes = self.db.collection.count_documents({})
        assert num_nodes == 1

    def test_add_edge(self):
        node_1 = Node("testsource")
        node_2 = Node("testdest")
        self.db.add_node(node_1.toDict())
        self.db.add_node(node_2.toDict())
        self.db.add_edge(node_1.name, node_2.name)
        deps = self.db.collection.count_documents(
            {"dependencies.0": {
                "$exists": True
            }})
        assert deps == 1

    def test_set_node_status(self):
        node_name = "status_test"
        status = "testing"
        node_1 = Node(node_name)
        self.db.add_node(node_1.toDict())
        inserted_node = self.db.get_node(node_name)
        print(inserted_node.status)
        self.db.set_node_status(node_name, status)
        reset_node = self.db.get_node(node_name)
        assert reset_node.status == status

    def test_start_flow(self):
        self.db.collection.delete_many({})
        node_1 = Node("node1")
        node_2 = Node("node2")
        node_3 = Node("node3")
        node_1.add_dependency(node_2)
        for node in [node_1, node_2, node_3]:
            self.db.add_node(node.toDict())
        self.db.start_flow()
        new_collection = self.db.collection
        print(new_collection)
        new_nodes = self.db.list_nodes()
        for node in new_nodes:
            print(node.status)
            assert node.status == "pending"
        self.db = FlowDatabase("test")

    def test_remove(self):
        self.db.collection.delete_many({})
        node_1 = Node("testsource")
        node_2 = Node("testdest")
        self.db.add_node(node_1.toDict())
        self.db.add_node(node_2.toDict())
        self.db.add_edge(node_1.name, node_2.name)
        deps = self.db.collection.count_documents(
            {"dependencies.0": {
                "$exists": True
            }})
        assert deps == 1
        self.db.remove_edge(node_1.name, node_2.name)
        deps = self.db.collection.count_documents(
            {"dependencies.0": {
                "$exists": True
            }})
        assert deps == 0
        self.db.remove_node(node_1.name)
        nodes = self.db.collection.count_documents({"name": node_1.name})
        assert nodes == 0

    def test_flowstring_parser(self):
        self.db.collection.delete_many({})
        flowstring = "( pytesta; pytestb ) ; ( pytestc; ( pytestd || pyteste ) ) || pytestf"
        parse_string_to_workflow(flowstring, "test")
        nodes = self.db.list_nodes()
        names = [node.name for node in nodes]
        for node in nodes:
            print(node)
        for flow_string_name in [
                "pytesta", "pytestb", "pytestc", "pytestd", "pyteste",
                "pytestf"
        ]:
            assert flow_string_name in names
        node_a = [node for node in nodes if node.name == "pytesta"][0]
        assert len(node_a.dependencies) == 0
        node_f = [node for node in nodes if node.name == "pytestf"][0]
        assert len(node_f.dependencies) == 0
        node_b = [node for node in nodes if node.name == "pytestb"][0]
        assert len(node_b.dependencies) == 1
        assert "pytesta" in node_b.dependencies
Example #3
0
    def do_flow(self, args, arguments):
        """
        ::

          Usage:
                flow list [--flow=NAME] [--output=FORMAT]
                flow add [--flowname=FLOWNAME] --flowfile=FILENAME
                flow run [--flowname=FLOWNAME] [--flowfile=FILENAME]
                flow node add NODENAME [--flowname=FLOWNAME]
                flow edge add FROM TO [--flowname=FLOWNAME]
                flow node delete NODENAME
                flow edge delete FROM TO
                flow edge invert FROM TO
                flow visualize start
                flow visualize stop
                flow refresh

          This command manages and executes workflows
          The default workflow is just named "workflow" but you can specify multiple

          Arguments:
              NAME       the name of the workflow
              FILENAME   a file name
              NODENAME   the name of the node
              FROM       the edge source (a node name)
              TO         the edge destination (a node name)
              NODE       the name of the node

          Options:
              --flow=NAME   the name or the flow
              --file    specify the file
              --log     specify the log file
              --flowname=FLOWNAME   the name or the workflow
              --output=OUTPUT       the output format [default: table]
        """

        arguments.FLOWNAME = arguments["--flowname"] or "workflow"
        arguments.FLOWFILE = arguments[
            "--flowfile"] or f"{arguments.FLOWNAME}-flow.py"
        arguments.output = arguments["--output"]

        VERBOSE(arguments, verbose=0)

        if arguments["add"] and arguments.edge:

            db = FlowDatabase(arguments.FLOWNAME)
            db.add_edge(arguments.FROM, arguments.TO)

        elif arguments["add"]:

            print("adding a node")

            if arguments.NODENAME:

                node = Node(arguments.NODENAME)
                node.workflow = arguments.FLOWNAME
                try:
                    db = FlowDatabase(arguments.FLOWNAME)
                    db.add_node(node.toDict())
                except Exception as e:
                    print("error executing", e)

            elif arguments["--flowfile"]:

                filename = arguments["--flowfile"]
                print("load from file", filename)
                parse_yaml_to_workflow(filename)

        elif arguments["list"]:

            arguments.flow = arguments["--flow"] or "workflow"
            db = CmDatabase()

            name = arguments["--flow"]

            if name is not None:
                flows = [name]
            else:
                candidates = db.collections()
                flows = []
                for flow in candidates:
                    if flow.endswith("-flow"):
                        flows.append(flow)

            entries = []
            for name in flows:
                nodes = db.find(collection=f"{name}-flow")

                for node in nodes:
                    node["dependencies"] = ", ".join(node["dependencies"])
                entries = entries + nodes

            order = ["name", "workflow", "dependencies", "cm.modified"]
            header = ["Name", "Workflow", "Dependencies", "Modified"]

            print(
                Printer.flatwrite(nodes,
                                  order=order,
                                  header=header,
                                  output=arguments.output))

        elif arguments._run:

            runner = FlowRunner(arguments.FLOWNAME, arguments.FLOWFILE)
            runner.start_flow()

        elif arguments.visualize:

            if arguments["start"]:
                manager.start()
                print(
                    "The visualization servive started at http://127.0.0.1:8080/flow/"
                )

            elif arguments["stop"]:
                manager.stop()

        elif arguments["delete"] and arguments.edge:
            db = FlowDatabase(arguments.FLOWNAME)
            db.remove_edge(arguments.FROM, arguments.TO)

        elif arguments["delete"] and arguments.node:
            db = FlowDatabase(arguments.FLOWNAME)
            db.remove_node(arguments.NODENAME)

        elif arguments["invert"] and arguments.edge:
            db = FlowDatabase(arguments.FLOWNAME)
            db.remove_edge(arguments.TO, arguments.FROM)
            db.add_edge(arguments.FROM, arguments.TO)

        elif arguments.refresh:

            raise NotImplementedError