testStorageHandler.py 8.43 KB
Newer Older
1
#
Grégory Wisniewski's avatar
Grégory Wisniewski committed
2
# Copyright (C) 2009-2010  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 15
# 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
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 18 19 20

import unittest
from mock import Mock
from collections import deque
21
from neo.tests import NeoUnitTestBase
22
from neo.storage.app import Application
23
from neo.storage.handlers.storage import StorageOperationHandler
24
from neo.protocol import INVALID_PARTITION, Packets
25
from neo.protocol import INVALID_TID, INVALID_OID, INVALID_SERIAL
26

27
class StorageStorageHandlerTests(NeoUnitTestBase):
28 29

    def checkHandleUnexpectedPacket(self, _call, _msg_type, _listening=True, **kwargs):
Grégory Wisniewski's avatar
Grégory Wisniewski committed
30 31
        conn = self.getFakeConnection(address=("127.0.0.1", self.master_port),
                is_server=_listening)
32 33
        # hook
        self.operation.peerBroken = lambda c: c.peerBrokendCalled()
34
        self.checkUnexpectedPacketRaised(_call, conn=conn, **kwargs)
35 36

    def setUp(self):
37
        NeoUnitTestBase.setUp(self)
38 39
        self.prepareDatabase(number=1)
        # create an application object
40
        config = self.getStorageConfiguration(master_number=1)
41
        self.app = Application(config)
42 43 44 45 46 47 48 49
        self.app.transaction_dict = {}
        self.app.store_lock_dict = {}
        self.app.load_lock_dict = {}
        self.app.event_queue = deque()
        # handler
        self.operation = StorageOperationHandler(self.app)
        # set pmn
        self.master_uuid = self.getNewUUID()
50
        pmn = self.app.nm.getMasterList()[0]
51 52 53 54
        pmn.setUUID(self.master_uuid)
        self.app.primary_master_node = pmn
        self.master_port = 10010

55
    def test_18_askTransactionInformation1(self):
56
        # transaction does not exists
Grégory Wisniewski's avatar
Grégory Wisniewski committed
57
        conn = self.getFakeConnection()
58
        self.app.dm = Mock({'getNumPartitions': 1})
59
        self.operation.askTransactionInformation(conn, INVALID_TID)
60 61
        self.checkErrorPacket(conn)

62
    def test_18_askTransactionInformation2(self):
63
        # answer
Grégory Wisniewski's avatar
Grégory Wisniewski committed
64
        conn = self.getFakeConnection()
65 66 67
        tid = self.getNextTID()
        oid_list = [self.getOID(1), self.getOID(2)]
        dm = Mock({"getTransaction": (oid_list, 'user', 'desc', '', False), })
68
        self.app.dm = dm
69
        self.operation.askTransactionInformation(conn, tid)
70 71
        self.checkAnswerTransactionInformation(conn)

72
    def test_24_askObject1(self):
73
        # delayed response
Grégory Wisniewski's avatar
Grégory Wisniewski committed
74
        conn = self.getFakeConnection()
75 76 77
        oid = self.getOID(1)
        tid = self.getNextTID()
        serial = self.getNextTID()
78
        self.app.dm = Mock()
79
        self.app.tm = Mock({'loadLocked': True})
80
        self.app.load_lock_dict[oid] = object()
81
        self.assertEquals(len(self.app.event_queue), 0)
82
        self.operation.askObject(conn, oid=oid, serial=serial, tid=tid)
83 84 85 86
        self.assertEquals(len(self.app.event_queue), 1)
        self.checkNoPacketSent(conn)
        self.assertEquals(len(self.app.dm.mockGetNamedCalls('getObject')), 0)

87
    def test_24_askObject2(self):
88 89
        # invalid serial / tid / packet not found
        self.app.dm = Mock({'getObject': None})
Grégory Wisniewski's avatar
Grégory Wisniewski committed
90
        conn = self.getFakeConnection()
91 92 93
        oid = self.getOID(1)
        tid = self.getNextTID()
        serial = self.getNextTID()
94
        self.assertEquals(len(self.app.event_queue), 0)
95
        self.operation.askObject(conn, oid=oid, serial=serial, tid=tid)
96 97 98
        calls = self.app.dm.mockGetNamedCalls('getObject')
        self.assertEquals(len(self.app.event_queue), 0)
        self.assertEquals(len(calls), 1)
99
        calls[0].checkArgs(oid, serial, tid, resolve_data=False)
100 101
        self.checkErrorPacket(conn)

102
    def test_24_askObject3(self):
103 104 105 106
        oid = self.getOID(1)
        tid = self.getNextTID()
        serial = self.getNextTID()
        next_serial = self.getNextTID()
107
        # object found => answer
108
        self.app.dm = Mock({'getObject': (serial, next_serial, 0, 0, '', None)})
Grégory Wisniewski's avatar
Grégory Wisniewski committed
109
        conn = self.getFakeConnection()
110
        self.assertEquals(len(self.app.event_queue), 0)
111
        self.operation.askObject(conn, oid=oid, serial=serial, tid=tid)
112 113 114
        self.assertEquals(len(self.app.event_queue), 0)
        self.checkAnswerObject(conn)

115
    def test_25_askTIDsFrom(self):
116
        # well case => answer
Grégory Wisniewski's avatar
Grégory Wisniewski committed
117
        conn = self.getFakeConnection()
118
        self.app.dm = Mock({'getReplicationTIDList': (INVALID_TID, )})
119
        self.app.pt = Mock({'getPartitions': 1})
120
        tid = self.getNextTID()
121
        tid2 = self.getNextTID()
122
        self.operation.askTIDsFrom(conn, tid, tid2, 2, [1])
123
        calls = self.app.dm.mockGetNamedCalls('getReplicationTIDList')
124
        self.assertEquals(len(calls), 1)
125
        calls[0].checkArgs(tid, tid2, 2, 1, 1)
126
        self.checkAnswerTidsFrom(conn)
127

128
    def test_26_askObjectHistoryFrom(self):
129 130
        min_oid = self.getOID(2)
        min_serial = self.getNextTID()
131
        max_serial = self.getNextTID()
132 133 134
        length = 4
        partition = 8
        num_partitions = 16
135
        tid = self.getNextTID()
Grégory Wisniewski's avatar
Grégory Wisniewski committed
136
        conn = self.getFakeConnection()
137 138 139 140
        self.app.dm = Mock({'getObjectHistoryFrom': {min_oid: [tid]},})
        self.app.pt = Mock({
            'getPartitions': num_partitions,
        })
141 142
        self.operation.askObjectHistoryFrom(conn, min_oid, min_serial,
            max_serial, length, partition)
143 144 145
        self.checkAnswerObjectHistoryFrom(conn)
        calls = self.app.dm.mockGetNamedCalls('getObjectHistoryFrom')
        self.assertEquals(len(calls), 1)
146 147
        calls[0].checkArgs(min_oid, min_serial, max_serial, length,
            num_partitions, partition)
148

149 150 151 152 153 154 155 156 157 158
    def test_askCheckTIDRange(self):
        count = 1
        tid_checksum = 2
        min_tid = self.getNextTID()
        num_partitions = 4
        length = 5
        partition = 6
        max_tid = self.getNextTID()
        self.app.dm = Mock({'checkTIDRange': (count, tid_checksum, max_tid)})
        self.app.pt = Mock({'getPartitions': num_partitions})
Grégory Wisniewski's avatar
Grégory Wisniewski committed
159
        conn = self.getFakeConnection()
160
        self.operation.askCheckTIDRange(conn, min_tid, max_tid, length, partition)
161 162
        calls = self.app.dm.mockGetNamedCalls('checkTIDRange')
        self.assertEqual(len(calls), 1)
163
        calls[0].checkArgs(min_tid, max_tid, length, num_partitions, partition)
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
        pmin_tid, plength, pcount, ptid_checksum, pmax_tid = \
            self.checkAnswerPacket(conn, Packets.AnswerCheckTIDRange,
            decode=True)
        self.assertEqual(min_tid, pmin_tid)
        self.assertEqual(length, plength)
        self.assertEqual(count, pcount)
        self.assertEqual(tid_checksum, ptid_checksum)
        self.assertEqual(max_tid, pmax_tid)

    def test_askCheckSerialRange(self):
        count = 1
        oid_checksum = 2
        min_oid = self.getOID(1)
        num_partitions = 4
        length = 5
        partition = 6
        serial_checksum = 7
        min_serial = self.getNextTID()
        max_serial = self.getNextTID()
        max_oid = self.getOID(2)
        self.app.dm = Mock({'checkSerialRange': (count, oid_checksum, max_oid,
            serial_checksum, max_serial)})
        self.app.pt = Mock({'getPartitions': num_partitions})
Grégory Wisniewski's avatar
Grégory Wisniewski committed
187
        conn = self.getFakeConnection()
188 189
        self.operation.askCheckSerialRange(conn, min_oid, min_serial,
            max_serial, length, partition)
190 191
        calls = self.app.dm.mockGetNamedCalls('checkSerialRange')
        self.assertEqual(len(calls), 1)
192 193
        calls[0].checkArgs(min_oid, min_serial, max_serial, length,
            num_partitions, partition)
194 195 196 197 198 199 200 201 202 203 204
        pmin_oid, pmin_serial, plength, pcount, poid_checksum, pmax_oid, \
            pserial_checksum, pmax_serial = self.checkAnswerPacket(conn,
            Packets.AnswerCheckSerialRange, decode=True)
        self.assertEqual(min_oid, pmin_oid)
        self.assertEqual(min_serial, pmin_serial)
        self.assertEqual(length, plength)
        self.assertEqual(count, pcount)
        self.assertEqual(oid_checksum, poid_checksum)
        self.assertEqual(max_oid, pmax_oid)
        self.assertEqual(serial_checksum, pserial_checksum)
        self.assertEqual(max_serial, pmax_serial)
205 206 207

if __name__ == "__main__":
    unittest.main()