예제 #1
0
    def test_detect_cyclic_graph(self):
        """Test that cyclic graphs are detected"""

        test_matrix = (
            ({
                "A": ["B"],
                "B": ["C"],
                "C": [],
                }, False),
            ({
                "A": [],
                "B": ["C"],
                "C": [],
                }, False),
            ({
                "A": ["C"],
                "B": ["C"],
                "C": ["A"],
                }, True),
            ({
                "A": ["B"],
                "B": ["C"],
                "C": ["A"],
                }, True),
        )

        for g, expected_result in test_matrix:
            if expected_result:
                self.assertRaises(
                    graph.FoundLoopError,
                    graph.build_graph,
                    g.keys(), g.__getitem__,
                )
            else:
                graph.build_graph(g.keys(), g.__getitem__)
예제 #2
0
    def test_detect_cyclic_graph(self):
        """Test that cyclic graphs are detected"""

        test_matrix = (
            ({
                "A": ["B"],
                "B": ["C"],
                "C": [],
                }, False),
            ({
                "A": [],
                "B": ["C"],
                "C": [],
                }, False),
            ({
                "A": ["C"],
                "B": ["C"],
                "C": ["A"],
                }, True),
            ({
                "A": ["B"],
                "B": ["C"],
                "C": ["A"],
                }, True),
        )

        for g, expected_result in test_matrix:
            if expected_result:
                self.assertRaises(
                    graph.FoundLoopError,
                    graph.build_graph,
                    g.keys(), g.__getitem__,
                )
            else:
                graph.build_graph(g.keys(), g.__getitem__)
예제 #3
0
    def test_resource_graph(self):
        bank = bank_plugin.Bank(_InMemoryBankPlugin())
        bank_lease = _InMemoryLeasePlugin()
        checkpoints_section = bank_plugin.BankSection(bank, "/checkpoints")
        indices_section = bank_plugin.BankSection(bank, "/indices")
        owner_id = bank.get_owner_id()
        plan = fake_protection_plan()
        cp = checkpoint.Checkpoint.create_in_section(
            checkpoints_section=checkpoints_section,
            indices_section=indices_section,
            bank_lease=bank_lease,
            owner_id=owner_id,
            plan=plan)

        resource_graph = graph.build_graph([A, B, C, D],
                                           resource_map.__getitem__)
        cp.resource_graph = resource_graph
        cp.commit()
        checkpoint_data = cp._md_cache
        self.assertEqual(
            checkpoint_data,
            bank._plugin.get_object(
                "/checkpoints/%s/%s" %
                (checkpoint_data["id"], checkpoint._INDEX_FILE_NAME)))
        self.assertEqual(len(resource_graph), len(cp.resource_graph))
        for start_node in resource_graph:
            self.assertIn(start_node, cp.resource_graph)
예제 #4
0
    def test_diamond_graph(self):
        def test_node_children(testnode):
            return testnode.children

        TestNode = namedtuple('TestNode', ['id', 'children'])
#          A
#         / \
#        B   C
#         \ /
#          D
        test_diamond_left = TestNode('D', ())
        test_diamond_right = TestNode('D', ())
        print('id left: ', id(test_diamond_left))
        print('id right:', id(test_diamond_right))
        test_left = TestNode('B', (test_diamond_left, ))
        test_right = TestNode('C', (test_diamond_right, ))
        test_root = TestNode('A', (test_left, test_right, ))
        test_nodes = {test_root, }
        result_graph = graph.build_graph(test_nodes, test_node_children)
        test_root_node = result_graph[0]
        self.assertEqual(2, len(test_root_node.child_nodes))
        test_left_node = test_root_node.child_nodes[0]
        test_right_node = test_root_node.child_nodes[1]

        self.assertEqual(id(test_left_node.child_nodes[0]),
                         id(test_right_node.child_nodes[0]))
예제 #5
0
    def test_resource_graph(self):
        bank = bank_plugin.Bank(_InMemoryBankPlugin())
        bank_lease = _InMemoryLeasePlugin()
        checkpoints_section = bank_plugin.BankSection(bank, "/checkpoints")
        indices_section = bank_plugin.BankSection(bank, "/indices")
        owner_id = bank.get_owner_id()
        plan = fake_protection_plan()
        cp = checkpoint.Checkpoint.create_in_section(
            checkpoints_section=checkpoints_section,
            indices_section=indices_section,
            bank_lease=bank_lease,
            owner_id=owner_id,
            plan=plan)

        resource_graph = graph.build_graph([A, B, C, D],
                                           resource_map.__getitem__)
        cp.resource_graph = resource_graph
        cp.commit()
        checkpoint_data = cp._md_cache
        self.assertEqual(
            checkpoint_data,
            bank._plugin.get_object(
                "/checkpoints/%s/%s" % (checkpoint_data["id"],
                                        checkpoint._INDEX_FILE_NAME)
            )
        )
        self.assertEqual(len(resource_graph), len(cp.resource_graph))
        for start_node in resource_graph:
            self.assertIn(start_node, cp.resource_graph)
예제 #6
0
    def test_resource_graph_walker_listener_plan(self):
        expected_calls = [
            ("on_resource_start", 'A', True),
            ("on_resource_start", 'C', True),
            ("on_resource_start", 'D', True),
            ("on_resource_end", 'D'),
            ("on_resource_start", 'E', True),
            ("on_resource_end", 'E'),
            ("on_resource_end", 'C'),
            ("on_resource_end", 'A'),
            ("on_resource_start", 'B', True),
            ("on_resource_start", 'C', False),
            ("on_resource_start", 'D', False),
            ("on_resource_end", 'D'),
            ("on_resource_start", 'E', False),
            ("on_resource_end", 'E'),
            ("on_resource_end", 'C'),
            ("on_resource_end", 'B'),
        ]

        fake_cntxt = "fake_cntxt"
        fake_protection_plugin = FakeProtectionPlugin(expected_calls)
        fake_context = ResourceGraphContext(
            fake_cntxt, plugin_map={"fake_plugin": fake_protection_plugin})
        listener = ResourceGraphWalkerListener(fake_context)

        walker = graph.GraphWalker()
        walker.register_listener(listener)
        walker.walk_graph(
            graph.build_graph(plan_resources, resource_map.__getitem__))
        self.assertEqual(len(listener.context.status_getters), 5)
예제 #7
0
    def test_diamond_graph(self):
        def test_node_children(testnode):
            return testnode.children

        TestNode = namedtuple('TestNode', ['id', 'children'])
#          A
#         / \
#        B   C
#         \ /
#          D
        test_diamond_left = TestNode('D', ())
        test_diamond_right = TestNode('D', ())
        print('id left: ', id(test_diamond_left))
        print('id right:', id(test_diamond_right))
        test_left = TestNode('B', (test_diamond_left, ))
        test_right = TestNode('C', (test_diamond_right, ))
        test_root = TestNode('A', (test_left, test_right, ))
        test_nodes = {test_root, }
        result_graph = graph.build_graph(test_nodes, test_node_children)
        test_root_node = result_graph[0]
        self.assertEqual(len(test_root_node.child_nodes), 2)
        test_left_node = test_root_node.child_nodes[0]
        test_right_node = test_root_node.child_nodes[1]

        self.assertEqual(id(test_left_node.child_nodes[0]),
                         id(test_right_node.child_nodes[0]))
예제 #8
0
    def build_graph(self, context, resources):
        def fetch_dependent_resources_context(resource):
            return self.fetch_dependent_resources(context, resource)

        return build_graph(
            start_nodes=resources,
            get_child_nodes_func=fetch_dependent_resources_context,
        )
예제 #9
0
 def test_graph_serialize(self):
     resource_a = resource.Resource('server', 0, 'a', {'name': 'a'})
     resource_b = resource.Resource('volume', 1, 'b', {'name': 'b'})
     test_base = {resource_a: [resource_b], resource_b: []}
     test_graph = graph.build_graph(test_base.keys(), test_base.__getitem__)
     self.assertIn(graph.serialize_resource_graph(test_graph), [
         '[{"0x1": ["server", 0, "a", {"name": "a"}], '
         '"0x0": ["volume", 1, "b", {"name": "b"}]}, '
         '[["0x1", ["0x0"]]]]',
         '[{"0x0": ["volume", 1, "b", {"name": "b"}], '
         '"0x1": ["server", 0, "a", {"name": "a"}]}, '
         '[["0x1", ["0x0"]]]]'
     ])
예제 #10
0
    def setUp(self):
        super(ResourceFlowTest, self).setUp()

        self.resource_graph = {
            parent: [child],
            child: [grandchild],
            grandchild: [],
        }

        self.provider = fakes.FakeProvider()
        self.test_graph = graph.build_graph([parent],
                                            self.resource_graph.__getitem__)
        self.taskflow_engine = TaskFlowEngine()
예제 #11
0
    def setUp(self):
        super(ResourceFlowTest, self).setUp()

        self.resource_graph = {
            parent: [child],
            child: [grandchild],
            grandchild: [],
        }

        self.provider = fakes.FakeProvider()
        self.test_graph = graph.build_graph([parent],
                                            self.resource_graph.__getitem__)
        self.taskflow_engine = TaskFlowEngine()
예제 #12
0
    def test_graph_pack_unpack(self):
        test_base = {
            "A1": ["B1", "B2"],
            "B1": ["C1", "C2"],
            "B2": ["C3", "C2"],
            "C1": [],
            "C2": [],
            "C3": [],
        }

        test_graph = graph.build_graph(test_base.keys(), test_base.__getitem__)
        packed_graph = graph.pack_graph(test_graph)
        unpacked_graph = graph.unpack_graph(packed_graph)
        self.assertEqual(test_graph, unpacked_graph)
예제 #13
0
    def test_graph_pack_unpack(self):
        test_base = {
            "A1": ["B1", "B2"],
            "B1": ["C1", "C2"],
            "B2": ["C3", "C2"],
            "C1": [],
            "C2": [],
            "C3": [],
        }

        test_graph = graph.build_graph(test_base.keys(), test_base.__getitem__)
        packed_graph = graph.pack_graph(test_graph)
        unpacked_graph = graph.unpack_graph(packed_graph)
        self.assertEqual(test_graph, unpacked_graph)
예제 #14
0
    def test_build_protect_task_flow(self, mock_build_graph):
        pr = ProviderRegistry()
        self.assertEqual(len(pr.providers), 1)

        plugable_provider = pr.providers["fake_id1"]
        cntxt = "fake_cntxt"
        plan = fake_protection_plan()
        workflow_engine = FakeWorkflowEngine()
        operation = constants.OPERATION_PROTECT

        ctx = {
            "context": cntxt,
            "plan": plan,
            "workflow_engine": workflow_engine,
            "operation_type": operation,
        }

        expected_calls = [
            ("on_resource_start", 'A', True),
            ("on_resource_start", 'C', True),
            ("on_resource_start", 'D', True),
            ("on_resource_end", 'D'),
            ("on_resource_start", 'E', True),
            ("on_resource_end", 'E'),
            ("on_resource_end", 'C'),
            ("on_resource_end", 'A'),
            ("on_resource_start", 'B', True),
            ("on_resource_start", 'C', False),
            ("on_resource_start", 'D', False),
            ("on_resource_end", 'D'),
            ("on_resource_start", 'E', False),
            ("on_resource_end", 'E'),
            ("on_resource_end", 'C'),
            ("on_resource_end", 'B'),
        ]

        fake_registry = FakeProtectableRegistry()
        plugable_provider.protectable_registry = fake_registry

        fake_registry.build_graph = mock.MagicMock()
        resource_graph = build_graph(plan_resources, resource_map.__getitem__)
        mock_build_graph.return_value = resource_graph

        fake_protection_plugin = FakeProtectionPlugin(expected_calls)
        plugable_provider._plugin_map = {"fake_plugin": fake_protection_plugin}

        result = plugable_provider.build_task_flow(ctx)
        self.assertEqual(len(result["status_getters"]), 5)
        self.assertEqual(len(result["task_flow"]), 5)
예제 #15
0
    def test_pack_unpack_graph(self):
        test_base = {
            "A1": ["B1", "B2", "B3", "B4"],
            "B1": [],
            "B2": [],
            "B3": ["B1"],
            "B4": ["B2"],
        }

        test_graph = graph.build_graph(test_base.keys(), test_base.__getitem__)
        packed_graph = graph.pack_graph(test_graph)
        unpacked_graph = graph.unpack_graph(packed_graph)
        self.assertEqual(len(test_graph), len(unpacked_graph))
        for start_node in test_graph:
            self.assertIn(start_node, unpacked_graph)
예제 #16
0
    def test_pack_unpack_graph(self):
        test_base = {
            "A1": ["B1", "B2", "B3", "B4"],
            "B1": [],
            "B2": [],
            "B3": ["B1"],
            "B4": ["B2"],
        }

        test_graph = graph.build_graph(test_base.keys(), test_base.__getitem__)
        packed_graph = graph.pack_graph(test_graph)
        unpacked_graph = graph.unpack_graph(packed_graph)
        self.assertEqual(len(test_graph), len(unpacked_graph))
        for start_node in test_graph:
            self.assertIn(start_node, unpacked_graph)
예제 #17
0
    def build_graph(self, context, resources):
        def fetch_dependent_resources_context(resource):
            dependent_resources = self.fetch_dependent_resources(
                context, resource)
            # The extra_info field of the resource is a dict
            # The dict can not be handled by build_graph, it will throw a
            # error. TypeError: unhashable type: 'dict'
            return [Resource(type=dependent_resource.type,
                             id=dependent_resource.id,
                             name=dependent_resource.name, extra_info=None)
                    for dependent_resource in dependent_resources]

        return build_graph(
            start_nodes=resources,
            get_child_nodes_func=fetch_dependent_resources_context,
        )
예제 #18
0
 def test_graph_deserialize_unordered_adjacency(self):
     test_base = {
         "A1": ["B1", "B2"],
         "B1": ["C1", "C2"],
         "B2": ["C3", "C2"],
         "C1": [],
         "C2": [],
         "C3": [],
     }
     test_graph = graph.build_graph(test_base.keys(), test_base.__getitem__)
     packed_graph = graph.pack_graph(test_graph)
     reversed_adjacency = tuple(reversed(packed_graph.adjacency))
     packed_graph = graph.PackedGraph(packed_graph.nodes,
                                      reversed_adjacency)
     with self.assertRaisesRegex(exception.InvalidInput, "adjacency list"):
         graph.unpack_graph(packed_graph)
예제 #19
0
 def test_graph_deserialize_unordered_adjacency(self):
     test_base = {
         "A1": ["B1", "B2"],
         "B1": ["C1", "C2"],
         "B2": ["C3", "C2"],
         "C1": [],
         "C2": [],
         "C3": [],
     }
     test_graph = graph.build_graph(test_base.keys(), test_base.__getitem__)
     packed_graph = graph.pack_graph(test_graph)
     reversed_adjacency = tuple(reversed(packed_graph.adjacency))
     packed_graph = graph.PackedGraph(packed_graph.nodes,
                                      reversed_adjacency)
     with self.assertRaisesRegex(exception.InvalidInput, "adjacency list"):
         graph.unpack_graph(packed_graph)
예제 #20
0
    def test_graph_serialize_deserialize(self):
        Format = namedtuple('Format', ['loads', 'dumps'])
        formats = [
            Format(jsonutils.loads, jsonutils.dumps),
            Format(msgpackutils.loads, msgpackutils.dumps),
        ]
        test_base = {
            "A1": ["B1", "B2"],
            "B1": ["C1", "C2"],
            "B2": ["C3", "C2"],
            "C1": [],
            "C2": [],
            "C3": [],
        }

        test_graph = graph.build_graph(test_base.keys(), test_base.__getitem__)
        for fmt in formats:
            serialized = fmt.dumps(graph.pack_graph(test_graph))
            unserialized = graph.unpack_graph(fmt.loads(serialized))
            self.assertEqual(test_graph, unserialized)
예제 #21
0
    def test_graph_serialize_deserialize(self):
        Format = namedtuple('Format', ['loads', 'dumps'])
        formats = [
            Format(jsonutils.loads, jsonutils.dumps),
            Format(msgpackutils.loads, msgpackutils.dumps),
        ]
        test_base = {
            "A1": ["B1", "B2"],
            "B1": ["C1", "C2"],
            "B2": ["C3", "C2"],
            "C1": [],
            "C2": [],
            "C3": [],
        }

        test_graph = graph.build_graph(test_base.keys(), test_base.__getitem__)
        for fmt in formats:
            serialized = fmt.dumps(graph.pack_graph(test_graph))
            unserialized = graph.unpack_graph(fmt.loads(serialized))
            self.assertEqual(test_graph, unserialized)
예제 #22
0
    def test_source_set(self):
        """Test that the source set only contains sources"""

        test_matrix = (
            ({
                "A": ["B"],
                "B": ["C"],
                "C": [],
                }, {"A"}),
            ({
                "A": [],
                "B": ["C"],
                "C": [],
                }, {"A", "B"}),
            ({
                "A": ["C"],
                "B": ["C"],
                "C": [],
                }, {"A", "B"}),
        )

        for g, expected_result in test_matrix:
            result = graph.build_graph(g.keys(), g.__getitem__)
            self.assertEqual({node.value for node in result}, expected_result)
예제 #23
0
    def test_source_set(self):
        """Test that the source set only contains sources"""

        test_matrix = (
            ({
                "A": ["B"],
                "B": ["C"],
                "C": [],
                }, {"A"}),
            ({
                "A": [],
                "B": ["C"],
                "C": [],
                }, {"A", "B"}),
            ({
                "A": ["C"],
                "B": ["C"],
                "C": [],
                }, {"A", "B"}),
        )

        for g, expected_result in test_matrix:
            result = graph.build_graph(g.keys(), g.__getitem__)
            self.assertEqual(expected_result, {node.value for node in result})
예제 #24
0
A = Resource(id='A', type='fake', name='fake')
B = Resource(id='B', type='fake', name='fake')
C = Resource(id='C', type='fake', name='fake')
D = Resource(id='D', type='fake', name='fake')
E = Resource(id='E', type='fake', name='fake')

resource_map = {
    A: [C],
    B: [C],
    C: [D, E],
    D: [],
    E: [],
}

resource_graph = build_graph([A, B, C, D], resource_map.__getitem__)


def fake_protection_plan():
    protection_plan = {
        'id':
        'fake_id',
        'is_enabled':
        True,
        'name':
        'fake_protection_plan',
        'comments':
        '',
        'revision':
        0,
        'resources': [{
예제 #25
0
파일: fakes.py 프로젝트: openstack/smaug
A = Resource(id='A', type='fake', name='fake')
B = Resource(id='B', type='fake', name='fake')
C = Resource(id='C', type='fake', name='fake')
D = Resource(id='D', type='fake', name='fake')
E = Resource(id='E', type='fake', name='fake')


resource_map = {
    A: [C],
    B: [C],
    C: [D, E],
    D: [],
    E: [],
}

resource_graph = build_graph([A, B, C, D], resource_map.__getitem__)


def fake_protection_plan():
    protection_plan = {'id': 'fake_id',
                       'is_enabled': True,
                       'name': 'fake_protection_plan',
                       'comments': '',
                       'revision': 0,
                       'resources': [
                           {"id": "A", "type": "fake", "name": "fake"},
                           {"id": "B", "type": "fake", "name": "fake"},
                           {"id": "C", "type": "fake", "name": "fake"},
                           {"id": "D", "type": "fake", "name": "fake"}],
                       'protection_provider': None,
                       'parameters': {},
예제 #26
0
    def test_graph_walker(self):
        test_matrix = (
            ({
                'A': ['B'],
                'B': ['C'],
                'C': [],
            }, (
                ("on_node_enter", 'A', False),
                ("on_node_enter", 'B', False),
                ("on_node_enter", 'C', False),
                ("on_node_exit", 'C'),
                ("on_node_exit", 'B'),
                ("on_node_exit", 'A'),
            )),
            ({
                'A': ['C'],
                'B': ['C'],
                'C': [],
            }, (
                ("on_node_enter", 'A', False),
                ("on_node_enter", 'C', False),
                ("on_node_exit", 'C'),
                ("on_node_exit", 'A'),
                ("on_node_enter", 'B', False),
                ("on_node_enter", 'C', True),
                ("on_node_exit", 'C'),
                ("on_node_exit", 'B'),
            )),
            ({
                'A': ['C'],
                'B': ['C'],
                'C': ['D', 'E'],
                'D': [],
                'E': [],
            }, (
                ("on_node_enter", 'A', False),
                ("on_node_enter", 'C', False),
                ("on_node_enter", 'D', False),
                ("on_node_exit", 'D'),
                ("on_node_enter", 'E', False),
                ("on_node_exit", 'E'),
                ("on_node_exit", 'C'),
                ("on_node_exit", 'A'),
                ("on_node_enter", 'B', False),
                ("on_node_enter", 'C', True),
                ("on_node_enter", 'D', True),
                ("on_node_exit", 'D'),
                ("on_node_enter", 'E', True),
                ("on_node_exit", 'E'),
                ("on_node_exit", 'C'),
                ("on_node_exit", 'B'),
            )),
        )

        for g, expected_calls in test_matrix:
            listener = _TestGraphWalkerListener(expected_calls, self)
            walker = graph.GraphWalker()
            walker.register_listener(listener)
            keys = list(g.keys())
            keys.sort()
            walker.walk_graph(graph.build_graph(keys, g.__getitem__))
예제 #27
0
 def build_graph(self, context, resources):
     return build_graph(
         start_nodes=resources,
         get_child_nodes_func=self.fetch_dependent_resources,
     )
예제 #28
0
    def test_graph_walker(self):
        test_matrix = (
            ({
                'A': ['B'],
                'B': ['C'],
                'C': [],
            }, (
                ("on_node_enter", 'A', False),
                ("on_node_enter", 'B', False),
                ("on_node_enter", 'C', False),
                ("on_node_exit", 'C'),
                ("on_node_exit", 'B'),
                ("on_node_exit", 'A'),
            )),
            ({
                'A': ['C'],
                'B': ['C'],
                'C': [],
            }, (
                ("on_node_enter", 'A', False),
                ("on_node_enter", 'C', False),
                ("on_node_exit", 'C'),
                ("on_node_exit", 'A'),
                ("on_node_enter", 'B', False),
                ("on_node_enter", 'C', True),
                ("on_node_exit", 'C'),
                ("on_node_exit", 'B'),
            )),
            ({
                'A': ['C'],
                'B': ['C'],
                'C': ['D', 'E'],
                'D': [],
                'E': [],
            }, (
                ("on_node_enter", 'A', False),
                ("on_node_enter", 'C', False),
                ("on_node_enter", 'D', False),
                ("on_node_exit", 'D'),
                ("on_node_enter", 'E', False),
                ("on_node_exit", 'E'),
                ("on_node_exit", 'C'),
                ("on_node_exit", 'A'),
                ("on_node_enter", 'B', False),
                ("on_node_enter", 'C', True),
                ("on_node_enter", 'D', True),
                ("on_node_exit", 'D'),
                ("on_node_enter", 'E', True),
                ("on_node_exit", 'E'),
                ("on_node_exit", 'C'),
                ("on_node_exit", 'B'),
            )),
        )

        for g, expected_calls in test_matrix:
            listener = _TestGraphWalkerListener(expected_calls, self)
            walker = graph.GraphWalker()
            walker.register_listener(listener)
            keys = list(g.keys())
            keys.sort()
            walker.walk_graph(graph.build_graph(keys, g.__getitem__))