testRecovery.py 4.19 KB
Newer Older
1
#
Julien Muchembled's avatar
Julien Muchembled committed
2
# Copyright (C) 2009-2019  Nexedi SA
3
#
4 5 6 7
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
8
#
9 10 11 12 13 14
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 17

import unittest
18
from .. import NeoUnitTestBase
19
from neo.lib.protocol import NodeTypes, NodeStates, CellStates
20
from neo.master.recovery import RecoveryManager
21 22
from neo.master.app import Application

23
class MasterRecoveryTests(NeoUnitTestBase):
24 25

    def setUp(self):
26
        NeoUnitTestBase.setUp(self)
27
        # create an application object
28
        config = self.getMasterConfiguration()
29
        self.app = Application(config)
30
        self.app.pt.clear()
31
        self.recovery = RecoveryManager(self.app)
32 33
        self.app.unconnected_master_node_set = set()
        self.app.negotiating_master_node_set = set()
34
        for node in self.app.nm.getMasterList():
35
            self.app.unconnected_master_node_set.add(node.getAddress())
36
            node.setState(NodeStates.RUNNING)
37 38 39 40

        # define some variable to simulate client and storage node
        self.storage_port = 10021
        self.master_port = 10011
41

42 43 44 45
    def _tearDown(self, success):
        self.app.close()
        NeoUnitTestBase._tearDown(self, success)

46
    # Common methods
47
    def identifyToMasterNode(self, node_type=NodeTypes.STORAGE, ip="127.0.0.1",
48 49 50
                             port=10021):
        """Do first step of identification to MN
        """
51
        address = (ip, port)
52
        uuid = self.getNewUUID(node_type)
53 54
        self.app.nm.createFromNodeType(node_type, address=address, uuid=uuid,
            state=NodeStates.RUNNING)
55 56 57
        return uuid

    # Tests
58
    def test_10_answerPartitionTable(self):
59 60 61 62
        # XXX: This test does much less that it seems, because all 'for' loops
        #      iterate over empty lists. Currently, only testRecovery covers
        #      some paths in NodeManager._createNode: apart from that, we could
        #      delete it entirely.
63
        recovery = self.recovery
64
        uuid = self.identifyToMasterNode(NodeTypes.MASTER, port=self.master_port)
65
        # not from target node, ignore
66
        uuid = self.identifyToMasterNode(NodeTypes.STORAGE, port=self.storage_port)
67
        conn = self.getFakeConnection(uuid, self.storage_port)
68
        node = self.app.nm.getByUUID(conn.getUUID())
69
        offset = 1
70
        cell_list = [(offset, uuid, CellStates.UP_TO_DATE)]
71 72
        cells = self.app.pt.getRow(offset)
        for cell, state in cells:
73
            self.assertEqual(state, CellStates.OUT_OF_DATE)
74
        recovery.target_ptid = 2
75
        node.setPending()
76
        recovery.answerPartitionTable(conn, 1, cell_list)
77 78
        cells = self.app.pt.getRow(offset)
        for cell, state in cells:
79
            self.assertEqual(state, CellStates.OUT_OF_DATE)
80 81 82
        # from target node, taken into account
        conn = self.getFakeConnection(uuid, self.storage_port)
        offset = 1
83
        cell_list = [(offset, ((uuid, CellStates.UP_TO_DATE,),),)]
84 85
        cells = self.app.pt.getRow(offset)
        for cell, state in cells:
86
            self.assertEqual(state, CellStates.OUT_OF_DATE)
87
        node.setPending()
88
        recovery.answerPartitionTable(conn, None, cell_list)
89 90
        cells = self.app.pt.getRow(offset)
        for cell, state in cells:
91
            self.assertEqual(state, CellStates.UP_TO_DATE)
92
        # give a bad offset, must send error
93
        self.recovery.target_uuid = uuid
94 95 96
        conn = self.getFakeConnection(uuid, self.storage_port)
        offset = 1000000
        self.assertFalse(self.app.pt.hasOffset(offset))
97
        cell_list = [(offset, ((uuid, NodeStates.UNKNOWN,),),)]
98
        node.setPending()
99
        self.checkProtocolErrorRaised(recovery.answerPartitionTable, conn,
100
            2, cell_list)
101 102


103 104 105
if __name__ == '__main__':
    unittest.main()