Пример #1
0
 def test_sanity_run(self):
     (flo, history) = self._make_watched_flow("sanity-test")
     flo.add(utils.ProvidesRequiresTask("do-this",
                                        provides=['a'],
                                        requires=[]))
     flo.add(utils.ProvidesRequiresTask("do-that",
                                        provides=['c'],
                                        requires=['a']))
     flo.add(utils.ProvidesRequiresTask("do-other",
                                        provides=['d'],
                                        requires=[]))
     flo.add(utils.ProvidesRequiresTask("do-thing",
                                        provides=['e'],
                                        requires=['d']))
     self.assertEquals(states.PENDING, flo.state)
     context = {}
     flo.run(context)
     self.assertEquals(states.SUCCESS, flo.state)
     self.assertTrue(len(context) > 0)
     # Even when running in parallel this will be the required order since
     # 'do-that' depends on 'do-this' finishing first.
     expected_order = ['do-this', 'do-that']
     this_that = [t for t in context[utils.ORDER_KEY]
                  if t in expected_order]
     self.assertEquals(expected_order, this_that)
     expected_order = ['do-other', 'do-thing']
     this_that = [t for t in context[utils.ORDER_KEY]
                  if t in expected_order]
     self.assertEquals(expected_order, this_that)
Пример #2
0
    def test_simple_resume(self):
        (flo, history) = self._make_watched_flow("sanity-test")
        f_uuid = flo.add(utils.ProvidesRequiresTask("do-this",
                                                    provides=['a'],
                                                    requires=[]))
        flo.add(utils.ProvidesRequiresTask("do-that",
                                           provides=['c'],
                                           requires=['a']))

        def resume_it(flow, ordering):
            ran_already = []
            not_ran = []
            for r in ordering:
                if r.uuid == f_uuid:
                    ran_already.append((r, {
                        'result': 'b',
                        'states': [states.SUCCESS],
                    }))
                else:
                    not_ran.append(r)
            return (ran_already, not_ran)

        flo.resumer = resume_it
        flo.run({})
        self.assertEquals('b', flo.results[f_uuid])
        self.assertEquals(states.SUCCESS, flo.state)
Пример #3
0
    def test_dependent(self):
        r = gf.Flow("root")

        customer = test_utils.ProvidesRequiresTask("customer",
                                                   provides=['dog'],
                                                   requires=[])
        washer = test_utils.ProvidesRequiresTask("washer",
                                                 requires=['dog'],
                                                 provides=['wash'])
        dryer = test_utils.ProvidesRequiresTask("dryer",
                                                requires=['dog', 'wash'],
                                                provides=['dry_dog'])
        shaved = test_utils.ProvidesRequiresTask("shaver",
                                                 requires=['dry_dog'],
                                                 provides=['shaved_dog'])
        happy_customer = test_utils.ProvidesRequiresTask(
            "happy_customer", requires=['shaved_dog'], provides=['happiness'])

        r.add(customer, washer, dryer, shaved, happy_customer)

        c = compiler.PatternCompiler(r).compile()

        self.assertEqual([], _get_scopes(c, customer))
        self.assertEqual([['washer', 'customer']], _get_scopes(c, dryer))
        self.assertEqual([['shaver', 'dryer', 'washer', 'customer']],
                         _get_scopes(c, happy_customer))
Пример #4
0
    def test_shadow_graph(self):
        r = gf.Flow("root")
        customer = test_utils.ProvidesRequiresTask("customer",
                                                   provides=['dog'],
                                                   requires=[])
        customer2 = test_utils.ProvidesRequiresTask("customer2",
                                                    provides=['dog'],
                                                    requires=[])
        washer = test_utils.ProvidesRequiresTask("washer",
                                                 requires=['dog'],
                                                 provides=['wash'])
        r.add(customer, washer)
        r.add(customer2, resolve_requires=False)
        r.link(customer2, washer)

        c = compiler.PatternCompiler(r).compile()

        # The order currently is *not* guaranteed to be 'customer' before
        # 'customer2' or the reverse, since either can occur before the
        # washer; since *either* is a valid topological ordering of the
        # dependencies...
        #
        # This may be different after/if the following is resolved:
        #
        # https://github.com/networkx/networkx/issues/1181 (and a few others)
        self.assertEqual(set(['customer', 'customer2']),
                         set(_get_scopes(c, washer)[0]))
        self.assertEqual([], _get_scopes(c, customer2))
        self.assertEqual([], _get_scopes(c, customer))
Пример #5
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()))
Пример #6
0
    def test_many_empty_in_graph_flow(self):
        flow = gf.Flow('root')

        a = test_utils.ProvidesRequiresTask('a', provides=[], requires=[])
        flow.add(a)

        b = lf.Flow('b')
        b_0 = test_utils.ProvidesRequiresTask('b.0', provides=[], requires=[])
        b_3 = test_utils.ProvidesRequiresTask('b.3', provides=[], requires=[])
        b.add(
            b_0,
            lf.Flow('b.1'),
            lf.Flow('b.2'),
            b_3,
        )
        flow.add(b)

        c = lf.Flow('c')
        c.add(lf.Flow('c.0'), lf.Flow('c.1'), lf.Flow('c.2'))
        flow.add(c)

        d = test_utils.ProvidesRequiresTask('d', provides=[], requires=[])
        flow.add(d)

        flow.link(b, d)
        flow.link(a, d)
        flow.link(c, d)

        compilation = compiler.PatternCompiler(flow).compile()
        g = compilation.execution_graph
        self.assertTrue(g.has_edge(b_0, b_3))
        self.assertTrue(g.has_edge(b_3, d))
        self.assertEqual(4, len(g))
Пример #7
0
    def test_graph_nested_provides(self):
        a = test_utils.ProvidesRequiresTask('a', provides=[], requires=['x'])
        b = test_utils.ProvidesRequiresTask('b', provides=['x'], requires=[])
        c = test_utils.ProvidesRequiresTask('c', provides=[], requires=[])
        inner_flo = lf.Flow("test2").add(b, c)
        flo = gf.Flow("test").add(a, inner_flo)

        compilation = compiler.PatternCompiler(flo).compile()
        graph = compilation.execution_graph
        self.assertEqual(5, len(graph))
        self.assertItemsEqual(graph.edges(data=True), [
            (flo, inner_flo, {
                'invariant': True
            }),
            (inner_flo, b, {
                'invariant': True
            }),
            (b, c, {
                'invariant': True
            }),
            (c, a, {
                'reasons': set(['x'])
            }),
        ])
        self.assertItemsEqual([flo], graph.no_predecessors_iter())
        self.assertItemsEqual([a], graph.no_successors_iter())
Пример #8
0
 def test_no_input_flo(self):
     (flo, history) = self._make_watched_flow("sanity-test")
     flo.add(utils.ProvidesRequiresTask("do-that",
                                        provides=['c'],
                                        requires=['a']))
     flo.add(utils.ProvidesRequiresTask("do-this",
                                        provides=['b'],
                                        requires=['c']))
     self.assertRaises(excp.InvalidStateException, flo.run, {})
Пример #9
0
 def test_recache_on_add_no_deps(self):
     wf = gw.TargetedFlow("test")
     test_1 = utils.ProvidesRequiresTask('test-1', provides=[], requires=[])
     wf.add(test_1)
     wf.set_target(test_1)
     self.assertEqual(1, len(wf.graph))
     test_2 = utils.ProvidesRequiresTask('test-2', provides=[], requires=[])
     wf.add(test_2)
     self.assertEqual(1, len(wf.graph))
Пример #10
0
 def test_recache_on_link(self):
     wf = gw.TargetedFlow("test")
     test_1 = utils.ProvidesRequiresTask('test-1', provides=[], requires=[])
     test_2 = utils.ProvidesRequiresTask('test-2', provides=[], requires=[])
     wf.add(test_1, test_2)
     wf.set_target(test_1)
     self.assertEqual(1, len(wf.graph))
     wf.link(test_2, test_1)
     self.assertEqual(2, len(wf.graph))
     self.assertEqual([(test_2, test_1)], list(wf.graph.edges()))
Пример #11
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(a, b))
Пример #12
0
 def test_flatten_attribute(self):
     wf = gw.Flow("the-test-action")
     test_1 = utils.ProvidesRequiresTask('test-1', requires=[], provides=[])
     test_2 = utils.ProvidesRequiresTask('test-2', provides=[], requires=[])
     wf.add(test_1, test_2)
     wf.link(test_1, test_2)
     g = fu.flatten(wf)
     self.assertEqual(2, len(g))
     edge_attrs = gu.get_edge_attrs(g, test_1, test_2)
     self.assertTrue(edge_attrs.get('manual'))
     self.assertTrue(edge_attrs.get('flatten'))
Пример #13
0
    def test_empty_flow_in_graph_flow_empty_linkage(self):
        flow = gf.Flow('lf')
        a = test_utils.ProvidesRequiresTask('a', provides=[], requires=[])
        b = test_utils.ProvidesRequiresTask('b', provides=[], requires=[])
        empty_flow = lf.Flow("empty")
        flow.add(a, empty_flow, b)
        flow.link(empty_flow, b)

        compilation = compiler.PatternCompiler(flow).compile()
        g = compilation.execution_graph
        self.assertEqual(0, len(g.edges()))
Пример #14
0
 def test_multi_provider_disallowed(self):
     flo = gw.Flow("test-flow", allow_same_inputs=False)
     flo.add(
         utils.ProvidesRequiresTask('test6', provides=['y'], requires=[]))
     flo.add(
         utils.ProvidesRequiresTask('test7', provides=['y'], requires=[]))
     flo.add(
         utils.ProvidesRequiresTask('test8', provides=[], requires=['y']))
     self.assertEquals(states.PENDING, flo.state)
     self.assertRaises(excp.InvalidStateException, flo.run, {})
     self.assertEquals(states.FAILURE, flo.state)
Пример #15
0
 def test_targeted_flow_bad_target(self):
     wf = gw.TargetedFlow("test")
     test_1 = utils.ProvidesRequiresTask('test-1',
                                         provides=['a'],
                                         requires=[])
     test_2 = utils.ProvidesRequiresTask('test-2',
                                         provides=['b'],
                                         requires=['a'])
     wf.add(test_1)
     self.assertRaisesRegexp(ValueError, '^Item .* not found',
                             wf.set_target, test_2)
Пример #16
0
    def test_linked_edge_reasons(self):
        wf = gw.Flow("the-test-action")
        test_1 = utils.ProvidesRequiresTask('test-1', requires=[], provides=[])
        test_2 = utils.ProvidesRequiresTask('test-2', provides=[], requires=[])
        wf.add(test_1, test_2)
        self.assertFalse(wf.graph.has_edge(test_1, test_2))
        wf.link(test_1, test_2)
        self.assertTrue(wf.graph.has_edge(test_1, test_2))

        edge_attrs = gu.get_edge_attrs(wf.graph, test_1, test_2)
        self.assertTrue(len(edge_attrs) > 0)
        self.assertTrue(edge_attrs.get('manual'))
Пример #17
0
    def test_graph_dependencies(self):
        a = test_utils.ProvidesRequiresTask('a', provides=['x'], requires=[])
        b = test_utils.ProvidesRequiresTask('b', provides=[], requires=['x'])
        flo = gf.Flow("test").add(a, b)

        compilation = compiler.PatternCompiler(flo).compile()
        g = compilation.execution_graph
        self.assertEqual(2, len(g))
        self.assertItemsEqual(g.edges(data=True), [(a, b, {
            'reasons': set(['x'])
        })])
        self.assertItemsEqual([a], g.no_predecessors_iter())
        self.assertItemsEqual([b], g.no_successors_iter())
Пример #18
0
    def test_empty_flow_in_linear_flow(self):
        flow = lf.Flow('lf')
        a = test_utils.ProvidesRequiresTask('a', provides=[], requires=[])
        b = test_utils.ProvidesRequiresTask('b', provides=[], requires=[])
        empty_flow = gf.Flow("empty")
        flow.add(a, empty_flow, b)

        compilation = compiler.PatternCompiler(flow).compile()
        g = compilation.execution_graph
        self.assertItemsEqual(g.edges(data=True), [
            (a, b, {
                'invariant': True
            }),
        ])
Пример #19
0
    def test_empty_flow_in_linear_flow(self):
        flo = lf.Flow('lf')
        a = test_utils.ProvidesRequiresTask('a', provides=[], requires=[])
        b = test_utils.ProvidesRequiresTask('b', provides=[], requires=[])
        empty_flo = gf.Flow("empty")
        flo.add(a, empty_flo, b)

        compilation = compiler.PatternCompiler(flo).compile()
        graph = compilation.execution_graph
        self.assertItemsEqual(graph.edges(), [
            (flo, a),
            (a, empty_flo),
            (empty_flo, b),
        ])
Пример #20
0
 def test_looping_flow(self):
     flo = gw.Flow("test-flow")
     flo.add(
         utils.ProvidesRequiresTask('test1',
                                    provides=['a', 'b'],
                                    requires=['c', 'd', 'e']))
     flo.add(
         utils.ProvidesRequiresTask('test2',
                                    provides=['c', 'd', 'e'],
                                    requires=['a', 'b']))
     ctx = collections.defaultdict(list)
     self.assertEquals(states.PENDING, flo.state)
     self.assertRaises(excp.InvalidStateException, flo.run, ctx)
     self.assertEquals(states.FAILURE, flo.state)
Пример #21
0
    def test_flow_bad_order(self):
        wf = lw.Flow("the-test-action")

        wf.add(
            utils.ProvidesRequiresTask('test-1',
                                       requires=set(),
                                       provides=['a', 'b']))

        # This one should fail to add since it requires 'c'
        no_req_task = utils.ProvidesRequiresTask('test-2',
                                                 requires=['c'],
                                                 provides=[])
        wf.add(no_req_task)
        e = _make_engine(wf)
        self.assertRaises(exc.NotFound, e.run)
Пример #22
0
    def test_graph_nested_provides(self):
        a = test_utils.ProvidesRequiresTask('a', provides=[], requires=['x'])
        b = test_utils.ProvidesRequiresTask('b', provides=['x'], requires=[])
        c = test_utils.ProvidesRequiresTask('c', provides=[], requires=[])
        flo = gf.Flow("test").add(a, lf.Flow("test2").add(b, c))

        compilation = compiler.PatternCompiler(flo).compile()
        g = compilation.execution_graph
        self.assertEqual(3, len(g))
        self.assertItemsEqual(g.edges(data=True), [(b, c, {
            'invariant': True
        }), (b, a, {
            'reasons': set(['x'])
        })])
        self.assertItemsEqual([b], g.no_predecessors_iter())
        self.assertItemsEqual([a, c], g.no_successors_iter())
Пример #23
0
    def test_empty_flow_in_linear_flow(self):
        flo = lf.Flow('lf')
        a = test_utils.ProvidesRequiresTask('a', provides=[], requires=[])
        b = test_utils.ProvidesRequiresTask('b', provides=[], requires=[])
        empty_flo = gf.Flow("empty")
        flo.add(a, empty_flo, b)

        g = _replicate_graph_with_names(
            compiler.PatternCompiler(flo).compile())
        self.assertItemsEqual(g.edges(), [
            ("lf", "a"),
            ("a", "empty"),
            ("empty", "empty[$]"),
            ("empty[$]", "b"),
            ("b", "lf[$]"),
        ])
Пример #24
0
 def test_ordering(self):
     wf = gw.Flow("the-test-action")
     test_1 = utils.ProvidesRequiresTask('test-1',
                                         requires=[],
                                         provides=set(['a', 'b']))
     test_2 = utils.ProvidesRequiresTask('test-2',
                                         provides=['c'],
                                         requires=['a', 'b'])
     test_3 = utils.ProvidesRequiresTask('test-3',
                                         provides=[],
                                         requires=['c'])
     wf.add(test_1, test_2, test_3)
     self.assertTrue(wf.graph.has_edge(test_1, test_2))
     self.assertTrue(wf.graph.has_edge(test_2, test_3))
     self.assertEqual(3, len(wf.graph))
     self.assertEqual([test_1], list(gu.get_no_predecessors(wf.graph)))
     self.assertEqual([test_3], list(gu.get_no_successors(wf.graph)))
Пример #25
0
    def test_many_empty_in_graph_flow(self):
        flo = gf.Flow('root')

        a = test_utils.ProvidesRequiresTask('a', provides=[], requires=[])
        flo.add(a)

        b = lf.Flow('b')
        b_0 = test_utils.ProvidesRequiresTask('b.0', provides=[], requires=[])
        b_1 = lf.Flow('b.1')
        b_2 = lf.Flow('b.2')
        b_3 = test_utils.ProvidesRequiresTask('b.3', provides=[], requires=[])
        b.add(b_0, b_1, b_2, b_3)
        flo.add(b)

        c = lf.Flow('c')
        c_0 = lf.Flow('c.0')
        c_1 = lf.Flow('c.1')
        c_2 = lf.Flow('c.2')
        c.add(c_0, c_1, c_2)
        flo.add(c)

        d = test_utils.ProvidesRequiresTask('d', provides=[], requires=[])
        flo.add(d)

        flo.link(b, d)
        flo.link(a, d)
        flo.link(c, d)

        g = _replicate_graph_with_names(
            compiler.PatternCompiler(flo).compile())

        self.assertTrue(g.has_edge('root', 'a'))
        self.assertTrue(g.has_edge('root', 'b'))
        self.assertTrue(g.has_edge('root', 'c'))

        self.assertTrue(g.has_edge('b.0', 'b.1'))
        self.assertTrue(g.has_edge('b.1[$]', 'b.2'))
        self.assertTrue(g.has_edge('b.2[$]', 'b.3'))

        self.assertTrue(g.has_edge('c.0[$]', 'c.1'))
        self.assertTrue(g.has_edge('c.1[$]', 'c.2'))

        self.assertTrue(g.has_edge('a', 'd'))
        self.assertTrue(g.has_edge('b[$]', 'd'))
        self.assertTrue(g.has_edge('c[$]', 'd'))
        self.assertEqual(20, len(g))
Пример #26
0
    def test_flow_add_order(self):
        wf = lw.Flow("the-test-action")

        wf.add(
            utils.ProvidesRequiresTask('test-1',
                                       requires=set(),
                                       provides=['a', 'b']))
        # This one should fail to add since it requires 'c'
        self.assertRaises(
            exc.InvalidStateException, wf.add,
            utils.ProvidesRequiresTask('test-2', requires=['c'], provides=[]))
        wf.add(
            utils.ProvidesRequiresTask('test-2',
                                       requires=['a', 'b'],
                                       provides=['c', 'd']))
        wf.add(
            utils.ProvidesRequiresTask('test-3',
                                       requires=['c', 'd'],
                                       provides=[]))
        wf.add(
            utils.ProvidesRequiresTask('test-4', requires=[], provides=['d']))
        wf.add(
            utils.ProvidesRequiresTask('test-5', requires=[], provides=['d']))
        wf.add(
            utils.ProvidesRequiresTask('test-6', requires=['d'], provides=[]))
Пример #27
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))
Пример #28
0
 def test_no_requires_provider(self):
     flo = gw.Flow("test-flow")
     flo.add(
         utils.ProvidesRequiresTask('test1',
                                    provides=['a', 'b'],
                                    requires=['c', 'd']))
     self.assertEquals(states.PENDING, flo.state)
     self.assertRaises(excp.InvalidStateException, flo.run, {})
     self.assertEquals(states.FAILURE, flo.state)
Пример #29
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)

        compilation = compiler.PatternCompiler(flow).compile()
        g = compilation.execution_graph

        self.assertTrue(g.has_edge(a, c))
        self.assertTrue(g.has_edge(c, d))
        self.assertTrue(g.has_edge(d, b))
Пример #30
0
    def test_shadow_linear(self):
        r = lf.Flow("root")

        customer = test_utils.ProvidesRequiresTask("customer",
                                                   provides=['dog'],
                                                   requires=[])
        customer2 = test_utils.ProvidesRequiresTask("customer2",
                                                    provides=['dog'],
                                                    requires=[])
        washer = test_utils.ProvidesRequiresTask("washer",
                                                 requires=['dog'],
                                                 provides=['wash'])
        r.add(customer, customer2, washer)

        c = compiler.PatternCompiler(r).compile()

        # This order is guaranteed...
        self.assertEqual(['customer2', 'customer'], _get_scopes(c, washer)[0])