Пример #1
0
    def test_suspend_and_revert_even_if_task_is_gone(self):
        flow = lf.Flow('linear').add(utils.ProgressingTask('a'),
                                     utils.ProgressingTask('b'),
                                     utils.FailingTask('c'))
        engine = self._make_engine(flow)

        with SuspendingListener(engine,
                                task_name='b',
                                task_state=states.REVERTED) as capturer:
            engine.run()

        expected = [
            'a.t RUNNING', 'a.t SUCCESS(5)', 'b.t RUNNING', 'b.t SUCCESS(5)',
            'c.t RUNNING', 'c.t FAILURE(Failure: RuntimeError: Woot!)',
            'c.t REVERTING', 'c.t REVERTED(None)', 'b.t REVERTING',
            'b.t REVERTED(None)'
        ]
        self.assertEqual(expected, capturer.values)

        # pretend we are resuming, but task 'c' gone when flow got updated
        flow2 = lf.Flow('linear').add(
            utils.ProgressingTask('a'),
            utils.ProgressingTask('b'),
        )
        engine2 = self._make_engine(flow2, engine.storage._flowdetail)
        with utils.CaptureListener(engine2, capture_flow=False) as capturer2:
            self.assertRaisesRegex(RuntimeError, '^Woot', engine2.run)
        self.assertEqual(states.REVERTED, engine2.storage.get_flow_state())
        expected = ['a.t REVERTING', 'a.t REVERTED(None)']
        self.assertEqual(expected, capturer2.values)
Пример #2
0
def create_flow():
    # Setup the set of things to do (mini-nova).
    flow = lf.Flow("root").add(
        PrintText("Starting vm creation.", no_slow=True),
        lf.Flow('vm-maker').add(
            # First create a specification for the final vm to-be.
            DefineVMSpec("define_spec"),
            # This does all the image stuff.
            gf.Flow("img-maker").add(
                LocateImages("locate_images"),
                DownloadImages("download_images"),
            ),
            # This does all the network stuff.
            gf.Flow("net-maker").add(
                AllocateIP("get_my_ips"),
                CreateNetworkTpl("fetch_net_settings"),
                WriteNetworkSettings("write_net_settings"),
            ),
            # This does all the volume stuff.
            gf.Flow("volume-maker").add(
                AllocateVolumes("allocate_my_volumes", provides='volumes'),
                FormatVolumes("volume_formatter"),
            ),
            # Finally boot it all.
            BootVM("boot-it"),
        ),
        # Ya it worked!
        PrintText("Finished vm create.", no_slow=True),
        PrintText("Instance is running!", no_slow=True))
    return flow
Пример #3
0
    def test_retry_in_nested_flows(self):
        c1 = retry.AlwaysRevert("c1")
        c2 = retry.AlwaysRevert("c2")
        inner_flo = lf.Flow("test2", c2)
        flo = lf.Flow("test", c1).add(inner_flo)

        g = _replicate_graph_with_names(
            compiler.PatternCompiler(flo).compile())
        self.assertEqual(6, len(g))
        self.assertItemsEqual(g.edges(data=True), [
            ('test', 'c1', {
                'invariant': True
            }),
            ('c1', 'test2', {
                'invariant': True,
                'retry': True
            }),
            ('test2', 'c2', {
                'invariant': True
            }),
            ('c2', 'test2[$]', {
                'invariant': True
            }),
            ('test2[$]', 'test[$]', {
                'invariant': True
            }),
        ])
        self.assertIs(c1, g.node['c2']['retry'])
        self.assertItemsEqual(['test'], list(g.no_predecessors_iter()))
        self.assertItemsEqual(['test[$]'], list(g.no_successors_iter()))
Пример #4
0
    def test_nested_prior_linear(self):
        r = lf.Flow("root")
        r.add(test_utils.TaskOneReturn("root.1"),
              test_utils.TaskOneReturn("root.2"))
        sub_r = lf.Flow("subroot")
        sub_r_1 = test_utils.TaskOneReturn("subroot.1")
        sub_r.add(sub_r_1)
        r.add(sub_r)

        c = compiler.PatternCompiler(r).compile()
        self.assertEqual([[], ['root.2', 'root.1']], _get_scopes(c, sub_r_1))
Пример #5
0
    def test_linear_flow_stringy(self):
        f = lf.Flow('test')
        expected = 'linear_flow.Flow: test(len=0)'
        self.assertEqual(expected, str(f))

        task1 = _task(name='task1')
        task2 = _task(name='task2')
        task3 = _task(name='task3')
        f = lf.Flow('test')
        f.add(task1, task2, task3)
        expected = 'linear_flow.Flow: test(len=3)'
        self.assertEqual(expected, str(f))
Пример #6
0
 def _make_test_flow(self):
     b = test_utils.TaskWithFailure("Broken")
     h_1 = test_utils.ProgressingTask("Happy-1")
     h_2 = test_utils.ProgressingTask("Happy-2")
     flo = linear_flow.Flow("test")
     flo.add(h_1, h_2, b)
     return flo
Пример #7
0
    def test_graph_nested(self):
        a, b, c, d, e, f, g = test_utils.make_many(7)
        flo = gf.Flow("test")
        flo.add(a, b, c, d)

        flo2 = lf.Flow('test2')
        flo2.add(e, f, g)
        flo.add(flo2)

        g = _replicate_graph_with_names(
            compiler.PatternCompiler(flo).compile())
        self.assertEqual(11, len(g))
        self.assertItemsEqual(g.edges(), [
            ('test', 'a'),
            ('test', 'b'),
            ('test', 'c'),
            ('test', 'd'),
            ('a', 'test[$]'),
            ('b', 'test[$]'),
            ('c', 'test[$]'),
            ('d', 'test[$]'),
            ('test', 'test2'),
            ('test2', 'e'),
            ('e', 'f'),
            ('f', 'g'),
            ('g', 'test2[$]'),
            ('test2[$]', 'test[$]'),
        ])
Пример #8
0
 def _create_engine(**kwargs):
     flow = lf.Flow('test-flow').add(utils.DummyTask())
     backend = backends.fetch({'connection': 'memory'})
     flow_detail = pu.create_flow_detail(flow, backend=backend)
     options = kwargs.copy()
     return engine.ParallelActionEngine(flow, flow_detail,
                                        backend, options)
Пример #9
0
    def test_run_iterations_suspended_failure(self):
        flow = lf.Flow("root")
        sad_tasks = test_utils.make_many(1,
                                         task_cls=test_utils.NastyFailingTask)
        flow.add(*sad_tasks)
        happy_tasks = test_utils.make_many(
            1, task_cls=test_utils.TaskNoRequiresNoReturns, offset=1)
        flow.add(*happy_tasks)

        runtime, machine, memory, machine_runner = self._make_machine(
            flow, initial_state=st.RUNNING)

        transitions = []
        for prior_state, new_state in machine_runner.run_iter(builder.START):
            transitions.append((new_state, memory.failures))
            if new_state == st.ANALYZING:
                runtime.storage.set_flow_state(st.SUSPENDED)
        state, failures = transitions[-1]
        self.assertEqual(st.SUSPENDED, state)
        self.assertEqual([], failures)

        self.assertEqual(st.PENDING,
                         runtime.storage.get_atom_state(happy_tasks[0].name))
        self.assertEqual(st.FAILURE,
                         runtime.storage.get_atom_state(sad_tasks[0].name))
Пример #10
0
    def test_retry_in_linear_flow_with_tasks(self):
        c = retry.AlwaysRevert("c")
        a, b = test_utils.make_many(2)
        flo = lf.Flow("test", c).add(a, b)

        g = _replicate_graph_with_names(
            compiler.PatternCompiler(flo).compile())
        self.assertEqual(5, len(g))
        self.assertItemsEqual(g.edges(data=True), [
            ('test', 'c', {
                'invariant': True
            }),
            ('a', 'b', {
                'invariant': True
            }),
            ('c', 'a', {
                'invariant': True,
                'retry': True
            }),
            ('b', 'test[$]', {
                'invariant': True
            }),
        ])

        self.assertItemsEqual(['test'], g.no_predecessors_iter())
        self.assertItemsEqual(['test[$]'], g.no_successors_iter())
        self.assertIs(c, g.node['a']['retry'])
        self.assertIs(c, g.node['b']['retry'])
Пример #11
0
    def test_graph_linear_scope(self):
        r = gf.Flow("root")
        r_1 = test_utils.TaskOneReturn("root.1")
        r_2 = test_utils.TaskOneReturn("root.2")
        r.add(r_1, r_2)
        r.link(r_1, r_2)

        s = lf.Flow("subroot")
        s_1 = test_utils.TaskOneReturn("subroot.1")
        s_2 = test_utils.TaskOneReturn("subroot.2")
        s.add(s_1, s_2)
        r.add(s)

        t = gf.Flow("subroot2")
        t_1 = test_utils.TaskOneReturn("subroot2.1")
        t_2 = test_utils.TaskOneReturn("subroot2.2")
        t.add(t_1, t_2)
        t.link(t_1, t_2)
        r.add(t)
        r.link(s, t)

        c = compiler.PatternCompiler(r).compile()
        self.assertEqual([], _get_scopes(c, r_1))
        self.assertEqual([['root.1']], _get_scopes(c, r_2))
        self.assertEqual([], _get_scopes(c, s_1))
        self.assertEqual([['subroot.1']], _get_scopes(c, s_2))
        self.assertEqual([[], ['subroot.2', 'subroot.1']], _get_scopes(c, t_1))
        self.assertEqual([["subroot2.1"], ['subroot.2', 'subroot.1']],
                         _get_scopes(c, t_2))
Пример #12
0
    def test_run_iterations(self):
        flow = lf.Flow("root")
        tasks = test_utils.make_many(
            1, task_cls=test_utils.TaskNoRequiresNoReturns)
        flow.add(*tasks)

        runtime, machine, memory, machine_runner = self._make_machine(
            flow, initial_state=st.RUNNING)

        it = machine_runner.run_iter(builder.START)
        prior_state, new_state = six.next(it)
        self.assertEqual(st.RESUMING, new_state)
        self.assertEqual(0, len(memory.failures))

        prior_state, new_state = six.next(it)
        self.assertEqual(st.SCHEDULING, new_state)
        self.assertEqual(0, len(memory.failures))

        prior_state, new_state = six.next(it)
        self.assertEqual(st.WAITING, new_state)
        self.assertEqual(0, len(memory.failures))

        prior_state, new_state = six.next(it)
        self.assertEqual(st.ANALYZING, new_state)
        self.assertEqual(0, len(memory.failures))

        prior_state, new_state = six.next(it)
        self.assertEqual(builder.GAME_OVER, new_state)
        self.assertEqual(0, len(memory.failures))
        prior_state, new_state = six.next(it)
        self.assertEqual(st.SUCCESS, new_state)
        self.assertEqual(0, len(memory.failures))

        self.assertRaises(StopIteration, six.next, it)
Пример #13
0
    def test_graph_nested_requires(self):
        a = test_utils.ProvidesRequiresTask('a', provides=['x'], requires=[])
        b = test_utils.ProvidesRequiresTask('b', provides=[], requires=[])
        c = test_utils.ProvidesRequiresTask('c', provides=[], requires=['x'])
        inner_flo = lf.Flow("test2").add(b, c)
        flo = gf.Flow("test").add(a, inner_flo)

        g = _replicate_graph_with_names(
            compiler.PatternCompiler(flo).compile())
        self.assertEqual(7, len(g))
        self.assertItemsEqual(g.edges(data=True), [
            ('test', 'a', {
                'invariant': True
            }),
            ('test2', 'b', {
                'invariant': True
            }),
            ('a', 'test2', {
                'reasons': set(['x'])
            }),
            ('b', 'c', {
                'invariant': True
            }),
            ('c', 'test2[$]', {
                'invariant': True
            }),
            ('test2[$]', 'test[$]', {
                'invariant': True
            }),
        ])
        self.assertItemsEqual(['test'], list(g.no_predecessors_iter()))
        self.assertItemsEqual(['test[$]'], list(g.no_successors_iter()))
Пример #14
0
    def test_retries_hierarchy(self):
        c1 = retry.AlwaysRevert("c1")
        c2 = retry.AlwaysRevert("c2")
        a, b, c, d = test_utils.make_many(4)
        inner_flo = lf.Flow("test2", c2).add(b, c)
        flo = lf.Flow("test", c1).add(a, inner_flo, d)

        g = _replicate_graph_with_names(
            compiler.PatternCompiler(flo).compile())
        self.assertEqual(10, len(g))
        self.assertItemsEqual(g.edges(data=True), [
            ('test', 'c1', {
                'invariant': True
            }),
            ('c1', 'a', {
                'invariant': True,
                'retry': True
            }),
            ('a', 'test2', {
                'invariant': True
            }),
            ('test2', 'c2', {
                'invariant': True
            }),
            ('c2', 'b', {
                'invariant': True,
                'retry': True
            }),
            ('b', 'c', {
                'invariant': True
            }),
            ('c', 'test2[$]', {
                'invariant': True
            }),
            ('test2[$]', 'd', {
                'invariant': True
            }),
            ('d', 'test[$]', {
                'invariant': True
            }),
        ])
        self.assertIs(c1, g.node['a']['retry'])
        self.assertIs(c1, g.node['d']['retry'])
        self.assertIs(c2, g.node['b']['retry'])
        self.assertIs(c2, g.node['c']['retry'])
        self.assertIs(c1, g.node['c2']['retry'])
        self.assertIsNone(g.node['c1'].get('retry'))
Пример #15
0
 def test_linear_flow_multi_provides_and_requires_values(self):
     flow = lf.Flow('lf').add(
         utils.TaskMultiArgMultiReturn('task1',
                                       rebind=['a', 'b', 'c'],
                                       provides=['x', 'y', 'q']),
         utils.TaskMultiArgMultiReturn('task2', provides=['i', 'j', 'k']))
     self.assertEqual(set(['a', 'b', 'c', 'z']), flow.requires)
     self.assertEqual(set(['x', 'y', 'q', 'i', 'j', 'k']), flow.provides)
Пример #16
0
def return_from_flow(pool):
    wf = lf.Flow("root").add(Hi("hi"), Bye("bye"))
    eng = zag.engines.load(wf, engine='serial')
    f = futures.Future()
    watcher = PokeFutureListener(eng, f, 'hi')
    watcher.register()
    pool.submit(eng.run)
    return (eng, f.result())
Пример #17
0
    def test_linear_flow_with_retry(self):
        ret = retry.AlwaysRevert(requires=['a'], provides=['b'])
        f = lf.Flow('test', ret)
        self.assertIs(f.retry, ret)
        self.assertEqual('test_retry', ret.name)

        self.assertEqual(set(['a']), f.requires)
        self.assertEqual(set(['b']), f.provides)
Пример #18
0
 def test_basic_do_not_capture(self):
     flow = lf.Flow("test")
     flow.add(test_utils.ProgressingTask("task1"))
     e = self._make_engine(flow)
     with test_utils.CaptureListener(e, capture_task=False) as capturer:
         e.run()
     expected = ['test.f RUNNING', 'test.f SUCCESS']
     self.assertEqual(expected, capturer.values)
Пример #19
0
    def test_unknown(self):
        r = lf.Flow("root")
        r_1 = test_utils.TaskOneReturn("root.1")
        r.add(r_1)

        r_2 = test_utils.TaskOneReturn("root.2")
        c = compiler.PatternCompiler(r).compile()
        self.assertRaises(ValueError, _get_scopes, c, r_2)
Пример #20
0
    def test_linear_flow_starts_as_empty(self):
        f = lf.Flow('test')

        self.assertEqual(0, len(f))
        self.assertEqual([], list(f))
        self.assertEqual([], list(f.iter_links()))

        self.assertEqual(set(), f.requires)
        self.assertEqual(set(), f.provides)
Пример #21
0
    def test_it_runs(self):
        values = []
        bof = BunchOfFunctions(values)
        t = base.FunctorTask

        flow = linear_flow.Flow('test')
        flow.add(t(bof.run_one, revert=bof.revert_one), t(bof.run_fail))
        self.assertRaisesRegex(RuntimeError, '^Woot', zag.engines.run, flow)
        self.assertEqual(['one', 'fail', 'revert one'], values)
Пример #22
0
    def test_linear_flow_two_dependent_tasks_two_different_calls(self):
        task1 = _task(name='task1', provides=['a'])
        task2 = _task(name='task2', requires=['a'])
        f = lf.Flow('test').add(task1).add(task2)

        self.assertEqual(2, len(f))
        self.assertEqual([task1, task2], list(f))
        self.assertEqual([(task1, task2, {'invariant': True})],
                         list(f.iter_links()), )
Пример #23
0
    def test_linear_flow_two_independent_tasks(self):
        task1 = _task(name='task1')
        task2 = _task(name='task2')
        f = lf.Flow('test').add(task1, task2)

        self.assertEqual(2, len(f))
        self.assertEqual([task1, task2], list(f))
        self.assertEqual([(task1, task2, {'invariant': True})],
                         list(f.iter_links()))
Пример #24
0
 def test_iter_nodes(self):
     task1 = _task(name='task1')
     task2 = _task(name='task2')
     task3 = _task(name='task3')
     f = lf.Flow('test').add(task1, task2, task3)
     tasks = set([task1, task2, task3])
     for (node, data) in f.iter_nodes():
         self.assertTrue(node in tasks)
         self.assertDictEqual({}, data)
Пример #25
0
    def test_empty_flow_in_nested_flow(self):
        flow = lf.Flow('lf')
        a = test_utils.ProvidesRequiresTask('a', provides=[], requires=[])
        b = test_utils.ProvidesRequiresTask('b', provides=[], requires=[])

        flow2 = lf.Flow("lf-2")
        c = test_utils.ProvidesRequiresTask('c', provides=[], requires=[])
        d = test_utils.ProvidesRequiresTask('d', provides=[], requires=[])
        empty_flow = gf.Flow("empty")
        flow2.add(c, empty_flow, d)
        flow.add(a, flow2, b)

        g = _replicate_graph_with_names(
            compiler.PatternCompiler(flow).compile())
        for u, v in [('lf', 'a'), ('a', 'lf-2'), ('lf-2', 'c'), ('c', 'empty'),
                     ('empty[$]', 'd'), ('d', 'lf-2[$]'), ('lf-2[$]', 'b'),
                     ('b', 'lf[$]')]:
            self.assertTrue(g.has_edge(u, v))
Пример #26
0
def run(engine_options):
    flow = lf.Flow('simple-linear').add(
        utils.TaskOneArgOneReturn(provides='result1'),
        utils.TaskMultiArgOneReturn(provides='result2'))
    eng = engines.load(flow,
                       store=dict(x=111, y=222, z=333),
                       engine='worker-based',
                       **engine_options)
    eng.run()
    return eng.storage.fetch_all()
Пример #27
0
 def test_deregister(self):
     """Verify that register and deregister don't blow up"""
     with contextlib.closing(impl_memory.MemoryBackend()) as be:
         flow = lf.Flow("test")
         flow.add(SleepyTask("test-1", sleep_for=0.1))
         (lb, fd) = persistence_utils.temporary_flow_detail(be)
         e = self._make_engine(flow, fd, be)
         l = timing.DurationListener(e)
         l.register()
         l.deregister()
Пример #28
0
    def test_linear_flow_retry_and_task(self):
        flow = lf.Flow(
            'lf',
            retry.AlwaysRevert('rt', requires=['x', 'y'], provides=['a', 'b']))
        flow.add(
            utils.TaskMultiArgOneReturn(rebind=['a', 'x', 'c'],
                                        provides=['z']))

        self.assertEqual(set(['x', 'y', 'c']), flow.requires)
        self.assertEqual(set(['a', 'b', 'z']), flow.provides)
Пример #29
0
    def test_builtin_retry_args(self):
        class FullArgsRetry(retry.AlwaysRevert):
            def execute(self, history, **kwargs):
                pass

            def revert(self, history, **kwargs):
                pass

        flow = lf.Flow('lf', retry=FullArgsRetry(requires='a'))
        self.assertEqual(set(['a']), flow.requires)
Пример #30
0
    def test_empty_flow_in_graph_flow(self):
        flow = lf.Flow('lf')
        a = test_utils.ProvidesRequiresTask('a', provides=['a'], requires=[])
        b = test_utils.ProvidesRequiresTask('b', provides=[], requires=['a'])
        empty_flow = lf.Flow("empty")
        flow.add(a, empty_flow, b)

        compilation = compiler.PatternCompiler(flow).compile()
        g = compilation.execution_graph
        self.assertTrue(g.has_edge(flow, a))
        self.assertTrue(g.has_edge(a, empty_flow))

        empty_flow_successors = list(g.successors(empty_flow))
        self.assertEqual(1, len(empty_flow_successors))
        empty_flow_terminal = empty_flow_successors[0]
        self.assertIs(empty_flow, empty_flow_terminal.flow)
        self.assertEqual(compiler.FLOW_END,
                         g.node[empty_flow_terminal]['kind'])
        self.assertTrue(g.has_edge(empty_flow_terminal, b))