Пример #1
0
 def test_complex_circular_rev(self):
     d = dependencies.Dependencies([('last', 'e1'), ('last', 'mid1'),
                                    ('last', 'mid2'), ('mid1', 'e2'),
                                    ('mid1', 'mid3'), ('mid2', 'mid3'),
                                    ('mid3', 'e3'), ('e3', 'mid1')])
     self.assertRaises(dependencies.CircularDependencyException, list,
                       reversed(d))
Пример #2
0
    def test_roots(self):
        d = dependencies.Dependencies([('last1', 'mid'), ('last2', 'mid'),
                                       ('mid', 'first1'), ('mid', 'first2')])

        leaves = sorted(list(d.roots()))

        self.assertEqual(['last1', 'last2'], leaves)
Пример #3
0
 def test_circular_rev(self):
     d = dependencies.Dependencies([('first', 'second'),
                                    ('second', 'third'),
                                    ('third', 'first')])
     self.assertRaises(dependencies.CircularDependencyException,
                       list,
                       reversed(d))
Пример #4
0
    def test_noexist_partial(self):
        d = dependencies.Dependencies([('foo', 'bar')])

        def get(i):
            return d[i]

        self.assertRaises(KeyError, get, 'baz')
Пример #5
0
    def _get_dependencies(resources):
        '''Return the dependency graph for a list of resources'''
        deps = dependencies.Dependencies()
        for resource in resources:
            resource.add_dependencies(deps)

        return deps
Пример #6
0
 def test_simple_partial(self):
     d = dependencies.Dependencies([('last', 'middle'),
                                    ('middle', 'first')])
     p = d['middle']
     order = list(iter(p))
     self.assertEqual(2, len(order))
     for n in ('last', 'middle'):
         self.assertIn(n, order, "'%s' not found in dependency order" % n)
     self.assertGreater(order.index('last'), order.index('middle'))
Пример #7
0
 def test_simple_multilevel_partial(self):
     d = dependencies.Dependencies([('last', 'middle'),
                                    ('middle', 'target'),
                                    ('target', 'first')])
     p = d['target']
     order = list(iter(p))
     self.assertEqual(3, len(order))
     for n in ('last', 'middle', 'target'):
         self.assertIn(n, order, "'%s' not found in dependency order" % n)
Пример #8
0
 def test_complex_partial(self):
     d = dependencies.Dependencies([('last', 'e1'), ('last', 'mid1'),
                                    ('last', 'mid2'), ('mid1', 'e2'),
                                    ('mid1', 'mid3'), ('mid2', 'mid3'),
                                    ('mid3', 'e3')])
     p = d['mid3']
     order = list(iter(p))
     self.assertEqual(4, len(order))
     for n in ('last', 'mid1', 'mid2', 'mid3'):
         self.assertIn(n, order, "'%s' not found in dependency order" % n)
Пример #9
0
    def setUp(self):
        super(ResourceDependenciesTest, self).setUp()
        utils.setup_dummy_db()

        resource._register_class('GenericResourceType',
                                 generic_rsrc.GenericResource)
        resource._register_class('ResourceWithPropsType',
                                 generic_rsrc.ResourceWithProps)

        self.deps = dependencies.Dependencies()
Пример #10
0
    def _dep_test(self, *edges):
        dummy = DummyTask(getattr(self, 'steps', 3))

        deps = dependencies.Dependencies(edges)

        tg = scheduler.DependencyTaskGroup(deps, dummy)

        self.mox.StubOutWithMock(dummy, 'do_step')

        yield dummy

        self.mox.ReplayAll()
        scheduler.TaskRunner(tg)(wait_time=None)
        self.mox.VerifyAll()
Пример #11
0
    def _dep_test(self, func, checkorder, deps):
        nodes = set.union(*[set(e) for e in deps])

        d = dependencies.Dependencies(deps)
        order = list(func(d))

        for n in nodes:
            self.assertIn(n, order, '"%s" is not in the sequence' % n)
            self.assertEqual(1, order.count(n))

        self.assertEqual(len(nodes), len(order))

        for l, f in deps:
            checkorder(order.index(f), order.index(l))
Пример #12
0
 def test_delete_retrigger_check_resource_new_traversal_updates_rsrc(
         self, mock_cru, mock_crc, mock_pcr, mock_csc):
     # mock dependencies to indicate a rsrc with id 2 has an update
     # in latest traversal
     self.stack._convg_deps = dependencies.Dependencies([
         [(1, False), (1, True)], [(2, False), (2, True)]])
     # simulate rsrc 2 completing its delete for old traversal
     # and calling rcr
     self.cr.retrigger_check_resource(self.ctx, 2, self.stack)
     # Ensure that pcr was called with proper delete traversal
     mock_pcr.assert_called_once_with(self.ctx, mock.ANY, 2,
                                      self.stack.current_traversal,
                                      mock.ANY, (2, True), None,
                                      True, None)
Пример #13
0
    def _dep_test(self, *edges):
        dummy = DummyTask(getattr(self, 'steps', 3))

        deps = dependencies.Dependencies(edges)

        tg = scheduler.DependencyTaskGroup(
            deps, dummy, aggregate_exceptions=self.aggregate_exceptions,
            reverse=self.reverse_order)

        self.m.StubOutWithMock(dummy, 'do_step')

        yield dummy

        self.m.ReplayAll()
        scheduler.TaskRunner(tg)(wait_time=None)
Пример #14
0
    def test_required_by(self):
        d = dependencies.Dependencies([('last', 'e1'), ('last', 'mid1'),
                                       ('last', 'mid2'), ('mid1', 'e2'),
                                       ('mid1', 'mid3'), ('mid2', 'mid3'),
                                       ('mid3', 'e3')])

        self.assertEqual(0, len(list(d.required_by('last'))))

        required_by = list(d.required_by('mid3'))
        self.assertEqual(2, len(required_by))
        for n in ('mid1', 'mid2'):
            self.assertIn(n, required_by, "'%s' not found in required_by" % n)

        required_by = list(d.required_by('e2'))
        self.assertEqual(1, len(required_by))
        self.assertIn('mid1', required_by, "'%s' not found in required_by" % n)

        self.assertRaises(KeyError, d.required_by, 'foo')
Пример #15
0
    def dependencies(self):
        '''
        Return a Dependencies object representing the dependencies between
        update operations to move from an existing stack definition to a new
        one.
        '''
        existing_deps = self.existing_stack.dependencies
        new_deps = self.new_stack.dependencies

        def edges():
            # Create/update the new stack's resources in create order
            for e in new_deps.graph().edges():
                yield e
            # Destroy/cleanup the old stack's resources in delete order
            for e in existing_deps.graph(reverse=True).edges():
                yield e
            # Don't cleanup old resources until after they have been replaced
            for name, res in six.iteritems(self.existing_stack):
                if name in self.new_stack:
                    yield (res, self.new_stack[name])

        return dependencies.Dependencies(edges())
Пример #16
0
    def _dep_test(self, *edges):
        dummy = DummyTask()

        class TaskMaker(object):
            def __init__(self, name):
                self.name = name

            def __repr__(self):
                return 'Dummy task "%s"' % self.name

            def __call__(self, *args, **kwargs):
                return dummy(self.name, *args, **kwargs)

        deps = dependencies.Dependencies(edges)

        tg = scheduler.DependencyTaskGroup(deps, TaskMaker)

        self.mox.StubOutWithMock(dummy, 'do_step')

        yield dummy

        self.mox.ReplayAll()
        scheduler.TaskRunner(tg)(wait_time=None)
        self.mox.VerifyAll()
Пример #17
0
 def test_circular_deps(self):
     d = dependencies.Dependencies([('first', 'second'),
                                    ('second', 'third'),
                                    ('third', 'first')])
     self.assertRaises(dependencies.CircularDependencyException,
                       scheduler.DependencyTaskGroup, d)
Пример #18
0
 def test_disjoint(self):
     d = dependencies.Dependencies([('1', None), ('2', None)])
     l = list(iter(d))
     self.assertEqual(2, len(l))
     self.assertIn('1', l)
     self.assertIn('2', l)
Пример #19
0
 def test_single_node(self):
     d = dependencies.Dependencies([('only', None)])
     l = list(iter(d))
     self.assertEqual(1, len(l))
     self.assertEqual('only', l[0])
Пример #20
0
 def test_repr(self):
     dp = dependencies.Dependencies([('1', None), ('2', '3'), ('2', '4')])
     s = "Dependencies([('1', None), ('2', '3'), ('2', '4')])"
     self.assertEqual(s, repr(dp))
Пример #21
0
 def test_edges(self):
     input_edges = [('1', None), ('2', '3'), ('2', '4')]
     dp = dependencies.Dependencies(input_edges)
     self.assertEqual(set(input_edges), set(dp.graph().edges()))
Пример #22
0
 def test_noexist_partial(self):
     d = dependencies.Dependencies([('foo', 'bar')])
     get = lambda i: d[i]
     self.assertRaises(KeyError, get, 'baz')
Пример #23
0
    def check_resource(self, cnxt, resource_id, current_traversal, data,
                       is_update):
        '''
        Process a node in the dependency graph.

        The node may be associated with either an update or a cleanup of its
        associated resource.
        '''
        try:
            rsrc, stack = resource.Resource.load(cnxt, resource_id, data)
        except exception.NotFound:
            return
        tmpl = stack.t

        if current_traversal != rsrc.stack.current_traversal:
            LOG.debug('[%s] Traversal cancelled; stopping.', current_traversal)
            return

        current_deps = ([tuple(i), (tuple(j) if j is not None else None)]
                        for i, j in rsrc.stack.current_deps['edges'])
        deps = dependencies.Dependencies(edges=current_deps)
        graph = deps.graph()

        if is_update:
            if (rsrc.replaced_by is not None
                    and rsrc.current_template_id != tmpl.id):
                return

            try:
                check_resource_update(rsrc, tmpl.id, data)
            except resource.UpdateReplace:
                # NOTE(sirushtim): Implemented by spec
                # convergence-resource-replacement.
                rsrc.make_replacement()
                return
            except resource.UpdateInProgress:
                return

            input_data = construct_input_data(rsrc)
        else:
            try:
                check_resource_cleanup(rsrc, tmpl.id, data)
            except resource.UpdateInProgress:
                return

        graph_key = (rsrc.id, is_update)
        if graph_key not in graph and rsrc.replaces is not None:
            # If we are a replacement, impersonate the replaced resource for
            # the purposes of calculating whether subsequent resources are
            # ready, since everybody has to work from the same version of the
            # graph. Our real resource ID is sent in the input_data, so the
            # dependencies will get updated to point to this resource in time
            # for the next traversal.
            graph_key = (rsrc.replaces, is_update)

        try:
            for req, fwd in deps.required_by(graph_key):
                propagate_check_resource(cnxt, self._rpc_client, req,
                                         current_traversal,
                                         set(graph[(req, fwd)]), graph_key,
                                         input_data if fwd else rsrc.id, fwd)

            check_stack_complete(cnxt, rsrc.stack, current_traversal, rsrc.id,
                                 graph, is_update)
        except sync_point.SyncPointNotFound:
            # NOTE(sirushtim): Implemented by spec
            # convergence-concurrent-workflow
            pass
Пример #24
0
 def _compute_dependencies(self, stack):
     current_deps = ([tuple(i), (tuple(j) if j is not None else None)]
                     for i, j in stack.current_deps['edges'])
     return dependencies.Dependencies(edges=current_deps)
Пример #25
0
 def test_self_ref(self):
     d = dependencies.Dependencies([('node', 'node')])
     self.assertRaises(dependencies.CircularDependencyException, list,
                       iter(d))
Пример #26
0
 def test_single_partial(self):
     d = dependencies.Dependencies([('last', 'first')])
     p = d['last']
     l = list(iter(p))
     self.assertEqual(1, len(l))
     self.assertEqual('last', l[0])