예제 #1
0
def test_simple_execution_context():
    graph = Graph()
    graph.add_chain(*chain)

    context = GraphExecutionContext(graph)
    assert len(context.nodes) == len(chain)
    assert not len(context.plugins)

    for i, node in enumerate(chain):
        assert context[i].wrapped is node

    assert not context.alive
    assert not context.started
    assert not context.stopped

    context.write(BEGIN, (), END)

    assert not context.alive
    assert not context.started
    assert not context.stopped

    context.start()

    assert context.alive
    assert context.started
    assert not context.stopped

    context.stop()

    assert not context.alive
    assert context.started
    assert context.stopped
예제 #2
0
def test_graph_topological_sort():
    g = Graph()

    g.add_chain(
        sentinel.a1,
        sentinel.a2,
        sentinel.a3,
        _input=None,
        _output=None,
    )

    assert g.topologically_sorted_indexes == (0, 1, 2)
    assert g[0] == sentinel.a1
    assert g[1] == sentinel.a2
    assert g[2] == sentinel.a3

    g.add_chain(
        sentinel.b1,
        sentinel.b2,
        _output=sentinel.a2,
    )

    assert g.topologically_sorted_indexes[-2:] == (1, 2)
    assert g.topologically_sorted_indexes.index(
        3) < g.topologically_sorted_indexes.index(4)
    assert g[3] == sentinel.b1
    assert g[4] == sentinel.b2
예제 #3
0
def test_simple_execution_context():
    graph = Graph()
    graph.add_chain(*chain)

    ctx = GraphExecutionContext(graph)
    assert len(ctx.nodes) == len(chain)
    assert not len(ctx.plugins)

    for i, node in enumerate(chain):
        assert ctx[i].wrapped is node

    assert not ctx.alive
    assert not ctx.started
    assert not ctx.stopped

    ctx.recv(BEGIN, Bag(), END)

    assert not ctx.alive
    assert not ctx.started
    assert not ctx.stopped

    ctx.start()

    assert ctx.alive
    assert ctx.started
    assert not ctx.stopped

    ctx.stop()

    assert not ctx.alive
    assert ctx.started
    assert ctx.stopped
예제 #4
0
def test_execution():
    graph = Graph()
    graph.add_chain(*chain)

    strategy = NaiveStrategy()
    ctx = strategy.execute(graph)

    assert ctx.results == [1, 4, 9, 16, 25, 36, 49, 64, 81]
예제 #5
0
def test_empty_execution_context():
    graph = Graph()

    ctx = GraphExecutionContext(graph)
    assert not len(ctx.nodes)
    assert not len(ctx.plugins)

    assert not ctx.alive
예제 #6
0
def test_graph_add_chain():
    g = Graph()

    assert len(g.nodes) == 0

    g.add_chain(identity, identity, identity)
    assert len(g.nodes) == 3
    assert len(g.outputs_of(BEGIN)) == 1
예제 #7
0
def test_graph_add_component():
    g = Graph()

    assert len(g.nodes) == 0

    g.add_node(identity)
    assert len(g.nodes) == 1

    g.add_node(identity)
    assert len(g.nodes) == 2
예제 #8
0
def test_graph_outputs_of():
    g = Graph()

    # default graph only node
    assert len(g.outputs_of(BEGIN)) == 0

    # unexisting node
    with pytest.raises(KeyError):
        g.outputs_of(0)

    # create node
    assert len(g.outputs_of(0, create=True)) == 0
    assert len(g.outputs_of(0)) == 0
예제 #9
0
def test_copy():
    g1 = Graph()
    g2 = g1.copy()

    assert g1 is not g2

    assert len(g1) == 0
    assert len(g2) == 0

    g1.add_chain([])

    assert len(g1) == 1
    assert len(g2) == 0

    g2.add_chain([], identity)

    assert len(g1) == 1
    assert len(g2) == 2
예제 #10
0
def run(graph, *chain, strategy=None, plugins=None, services=None):
    """
    Main entry point of bonobo. It takes a graph and creates all the necessary plumbery around to execute it.
    
    The only necessary argument is a :class:`Graph` instance, containing the logic you actually want to execute.
    
    By default, this graph will be executed using the "threadpool" strategy: each graph node will be wrapped in a
    thread, and executed in a loop until there is no more input to this node.
    
    You can provide plugins factory objects in the plugins list, this function will add the necessary plugins for
    interactive console execution and jupyter notebook execution if it detects correctly that it runs in this context.
    
    You'll probably want to provide a services dictionary mapping service names to service instances.
    
    :param Graph graph: The :class:`Graph` to execute.
    :param str strategy: The :class:`bonobo.strategies.base.Strategy` to use.
    :param list plugins: The list of plugins to enhance execution.
    :param dict services: The implementations of services this graph will use.
    :return bonobo.execution.graph.GraphExecutionContext:
    """
    if len(chain):
        warnings.warn(
            'DEPRECATED. You should pass a Graph instance instead of a chain.')
        from bonobo import Graph
        graph = Graph(graph, *chain)

    strategy = create_strategy(strategy)

    plugins = plugins or []

    if _is_interactive_console():
        from bonobo.ext.console import ConsoleOutputPlugin
        if ConsoleOutputPlugin not in plugins:
            plugins.append(ConsoleOutputPlugin)

    if _is_jupyter_notebook():
        from bonobo.ext.jupyter import JupyterOutputPlugin
        if JupyterOutputPlugin not in plugins:
            plugins.append(JupyterOutputPlugin)

    return strategy.execute(graph, plugins=plugins, services=services)