예제 #1
0
 def testClientDisconectsAfterBegin(self):
     client_uuid1, node1 = self.makeNode(NodeTypes.CLIENT)
     tm = TransactionManager(None)
     tid1 = self.getNextTID()
     tid2 = self.getNextTID()
     tm.begin(node1, 0, tid1)
     self.assertEqual(1, len(list(tm.clientLost(node1))))
     self.assertNotIn(tid1, tm)
예제 #2
0
 def testClientDisconectsAfterBegin(self):
     client_uuid1, node1 = self.makeNode(NodeTypes.CLIENT)
     tm = TransactionManager(lambda tid, txn: None)
     tid1 = self.getNextTID()
     tid2 = self.getNextTID()
     tm.begin(node1, tid1)
     tm.clientLost(node1)
     self.assertTrue(tid1 not in tm)
예제 #3
0
    def test_storageLost(self):
        client1 = Mock({'__hash__': 1})
        client2 = Mock({'__hash__': 2})
        client3 = Mock({'__hash__': 3})
        storage_1_uuid = self.getStorageUUID()
        storage_2_uuid = self.getStorageUUID()
        oid_list = [
            self.makeOID(1),
        ]

        tm = TransactionManager(lambda tid, txn: None)
        # Transaction 1: 2 storage nodes involved, one will die and the other
        # already answered node lock
        msg_id_1 = 1
        ttid1 = tm.begin(client1)
        tid1 = tm.prepare(ttid1, 1, oid_list, [storage_1_uuid, storage_2_uuid],
                          msg_id_1)
        tm.lock(ttid1, storage_2_uuid)
        t1 = tm[ttid1]
        self.assertFalse(t1.locked())
        # Storage 1 dies:
        # t1 is over
        self.assertTrue(t1.storageLost(storage_1_uuid))
        self.assertEqual(t1.getUUIDList(), [storage_2_uuid])
        del tm[ttid1]

        # Transaction 2: 2 storage nodes involved, one will die
        msg_id_2 = 2
        ttid2 = tm.begin(client2)
        tid2 = tm.prepare(ttid2, 1, oid_list, [storage_1_uuid, storage_2_uuid],
                          msg_id_2)
        t2 = tm[ttid2]
        self.assertFalse(t2.locked())
        # Storage 1 dies:
        # t2 still waits for storage 2
        self.assertFalse(t2.storageLost(storage_1_uuid))
        self.assertEqual(t2.getUUIDList(), [storage_2_uuid])
        self.assertTrue(t2.lock(storage_2_uuid))
        del tm[ttid2]

        # Transaction 3: 1 storage node involved, which won't die
        msg_id_3 = 3
        ttid3 = tm.begin(client3)
        tid3 = tm.prepare(ttid3, 1, oid_list, [
            storage_2_uuid,
        ], msg_id_3)
        t3 = tm[ttid3]
        self.assertFalse(t3.locked())
        # Storage 1 dies:
        # t3 doesn't care
        self.assertFalse(t3.storageLost(storage_1_uuid))
        self.assertEqual(t3.getUUIDList(), [storage_2_uuid])
        self.assertTrue(t3.lock(storage_2_uuid))
        del tm[ttid3]
예제 #4
0
    def test_storageLost(self):
        client1 = Mock({'__hash__': 1})
        client2 = Mock({'__hash__': 2})
        client3 = Mock({'__hash__': 3})
        storage_1_uuid = self.getStorageUUID()
        storage_2_uuid = self.getStorageUUID()
        oid_list = [self.makeOID(1), ]

        tm = TransactionManager(lambda tid, txn: None)
        # Transaction 1: 2 storage nodes involved, one will die and the other
        # already answered node lock
        msg_id_1 = 1
        ttid1 = tm.begin(client1)
        tid1 = tm.prepare(ttid1, 1, oid_list,
            [storage_1_uuid, storage_2_uuid], msg_id_1)
        tm.lock(ttid1, storage_2_uuid)
        t1 = tm[ttid1]
        self.assertFalse(t1.locked())
        # Storage 1 dies:
        # t1 is over
        self.assertTrue(t1.storageLost(storage_1_uuid))
        self.assertEqual(t1.getUUIDList(), [storage_2_uuid])
        del tm[ttid1]

        # Transaction 2: 2 storage nodes involved, one will die
        msg_id_2 = 2
        ttid2 = tm.begin(client2)
        tid2 = tm.prepare(ttid2, 1, oid_list,
            [storage_1_uuid, storage_2_uuid], msg_id_2)
        t2 = tm[ttid2]
        self.assertFalse(t2.locked())
        # Storage 1 dies:
        # t2 still waits for storage 2
        self.assertFalse(t2.storageLost(storage_1_uuid))
        self.assertEqual(t2.getUUIDList(), [storage_2_uuid])
        self.assertTrue(t2.lock(storage_2_uuid))
        del tm[ttid2]

        # Transaction 3: 1 storage node involved, which won't die
        msg_id_3 = 3
        ttid3 = tm.begin(client3)
        tid3 = tm.prepare(ttid3, 1, oid_list, [storage_2_uuid, ],
            msg_id_3)
        t3 = tm[ttid3]
        self.assertFalse(t3.locked())
        # Storage 1 dies:
        # t3 doesn't care
        self.assertFalse(t3.storageLost(storage_1_uuid))
        self.assertEqual(t3.getUUIDList(), [storage_2_uuid])
        self.assertTrue(t3.lock(storage_2_uuid))
        del tm[ttid3]
예제 #5
0
 def testClientDisconectsAfterBegin(self):
     client_uuid1, node1 = self.makeNode(NodeTypes.CLIENT)
     tm = TransactionManager(lambda tid, txn: None)
     tid1 = self.getNextTID()
     tid2 = self.getNextTID()
     tm.begin(node1, tid1)
     tm.clientLost(node1)
     self.assertTrue(tid1 not in tm)
예제 #6
0
 def testUnlockPending(self):
     callback = Mock()
     uuid1, node1 = self.makeNode(NodeTypes.CLIENT)
     uuid2, node2 = self.makeNode(NodeTypes.CLIENT)
     storage_uuid = self.getStorageUUID()
     tm = TransactionManager(callback)
     ttid1 = tm.begin(node1)
     ttid2 = tm.begin(node2)
     tid1 = tm.prepare(ttid1, 1, [], [storage_uuid], 0)
     tid2 = tm.prepare(ttid2, 1, [], [storage_uuid], 0)
     tm.lock(ttid2, storage_uuid)
     # txn 2 is still blocked by txn 1
     self.assertEqual(len(callback.getNamedCalls('__call__')), 0)
     tm.lock(ttid1, storage_uuid)
     # both transactions are unlocked when txn 1 is fully locked
     self.assertEqual(len(callback.getNamedCalls('__call__')), 2)
예제 #7
0
 def testUnlockPending(self):
     callback = Mock()
     uuid1, node1 = self.makeNode(NodeTypes.CLIENT)
     uuid2, node2 = self.makeNode(NodeTypes.CLIENT)
     storage_uuid = self.getStorageUUID()
     tm = TransactionManager(callback)
     ttid1 = tm.begin(node1)
     ttid2 = tm.begin(node2)
     tid1 = tm.prepare(ttid1, 1, [], [storage_uuid], 0)
     tid2 = tm.prepare(ttid2, 1, [], [storage_uuid], 0)
     tm.lock(ttid2, storage_uuid)
     # txn 2 is still blocked by txn 1
     self.assertEqual(len(callback.getNamedCalls('__call__')), 0)
     tm.lock(ttid1, storage_uuid)
     # both transactions are unlocked when txn 1 is fully locked
     self.assertEqual(len(callback.getNamedCalls('__call__')), 2)
예제 #8
0
 def testTransactionLock(self):
     """
     Transaction lock is present to ensure invalidation TIDs are sent in
     strictly increasing order.
     Note: this implementation might change later, to allow more paralelism.
     """
     client_uuid, client = self.makeNode(NodeTypes.CLIENT)
     tm = TransactionManager(lambda tid, txn: None)
     # With a requested TID, lock spans from begin to remove
     ttid1 = self.getNextTID()
     ttid2 = self.getNextTID()
     tid1 = tm.begin(client, ttid1)
     self.assertEqual(tid1, ttid1)
     del tm[ttid1]
     # Without a requested TID, lock spans from prepare to remove only
     ttid3 = tm.begin(client)
     ttid4 = tm.begin(client)  # Doesn't raise
     node = Mock({'getUUID': client_uuid, '__hash__': 0})
     tid4 = tm.prepare(ttid4, 1, [], [], 0)
     del tm[ttid4]
     tm.prepare(ttid3, 1, [], [], 0)
예제 #9
0
 def testTransactionLock(self):
     """
     Transaction lock is present to ensure invalidation TIDs are sent in
     strictly increasing order.
     Note: this implementation might change later, to allow more paralelism.
     """
     client_uuid, client = self.makeNode(NodeTypes.CLIENT)
     tm = TransactionManager(lambda tid, txn: None)
     # With a requested TID, lock spans from begin to remove
     ttid1 = self.getNextTID()
     ttid2 = self.getNextTID()
     tid1 = tm.begin(client, ttid1)
     self.assertEqual(tid1, ttid1)
     del tm[ttid1]
     # Without a requested TID, lock spans from prepare to remove only
     ttid3 = tm.begin(client)
     ttid4 = tm.begin(client) # Doesn't raise
     node = Mock({'getUUID': client_uuid, '__hash__': 0})
     tid4 = tm.prepare(ttid4, 1, [], [], 0)
     del tm[ttid4]
     tm.prepare(ttid3, 1, [], [], 0)
예제 #10
0
 def testManager(self):
     # test data
     node = Mock({'__hash__': 1})
     msg_id = 1
     oid_list = (oid1, oid2) = self.makeOID(1), self.makeOID(2)
     uuid_list = uuid1, uuid2 = self.getStorageUUID(), self.getStorageUUID()
     client_uuid = self.getClientUUID()
     # create transaction manager
     callback = Mock()
     txnman = TransactionManager(on_commit=callback)
     self.assertFalse(txnman.hasPending())
     self.assertEqual(txnman.registerForNotification(uuid1), [])
     # begin the transaction
     ttid = txnman.begin(node)
     self.assertTrue(ttid is not None)
     self.assertEqual(len(txnman.registerForNotification(uuid1)), 1)
     self.assertTrue(txnman.hasPending())
     # prepare the transaction
     tid = txnman.prepare(ttid, 1, oid_list, uuid_list, msg_id)
     self.assertTrue(txnman.hasPending())
     self.assertEqual(txnman.registerForNotification(uuid1), [ttid])
     txn = txnman[ttid]
     self.assertEqual(txn.getTID(), tid)
     self.assertEqual(txn.getUUIDList(), list(uuid_list))
     self.assertEqual(txn.getOIDList(), list(oid_list))
     # lock nodes
     txnman.lock(ttid, uuid1)
     self.assertEqual(len(callback.getNamedCalls('__call__')), 0)
     txnman.lock(ttid, uuid2)
     self.assertEqual(len(callback.getNamedCalls('__call__')), 1)
     self.assertEqual(txnman.registerForNotification(uuid1), [])
예제 #11
0
 def testManager(self):
     # test data
     node = Mock({'__hash__': 1})
     msg_id = 1
     oid_list = (oid1, oid2) = self.makeOID(1), self.makeOID(2)
     uuid_list = uuid1, uuid2 = self.getStorageUUID(), self.getStorageUUID()
     client_uuid = self.getClientUUID()
     # create transaction manager
     callback = Mock()
     txnman = TransactionManager(on_commit=callback)
     self.assertFalse(txnman.hasPending())
     self.assertEqual(txnman.registerForNotification(uuid1), [])
     # begin the transaction
     ttid = txnman.begin(node)
     self.assertTrue(ttid is not None)
     self.assertEqual(len(txnman.registerForNotification(uuid1)), 1)
     self.assertTrue(txnman.hasPending())
     # prepare the transaction
     tid = txnman.prepare(ttid, 1, oid_list, uuid_list, msg_id)
     self.assertTrue(txnman.hasPending())
     self.assertEqual(txnman.registerForNotification(uuid1), [ttid])
     txn = txnman[ttid]
     self.assertEqual(txn.getTID(), tid)
     self.assertEqual(txn.getUUIDList(), list(uuid_list))
     self.assertEqual(txn.getOIDList(), list(oid_list))
     # lock nodes
     txnman.lock(ttid, uuid1)
     self.assertEqual(len(callback.getNamedCalls('__call__')), 0)
     txnman.lock(ttid, uuid2)
     self.assertEqual(len(callback.getNamedCalls('__call__')), 1)
     self.assertEqual(txnman.registerForNotification(uuid1), [])