Esempio n. 1
0
 def test_deadlock_rw_rw(self):
     # Should pass after 2
     lock_table = {}
     store = InMemoryKVStore()
     t0 = TransactionHandler(lock_table, 0, store)
     t1 = TransactionHandler(lock_table, 1, store)
     t2 = TransactionHandler(lock_table, 2, store)
     coordinator = TransactionCoordinator(lock_table)
     # self.assertEqual(coordinator.detect_deadlocks(), None)
     self.assertEqual(t0.perform_get('a'), 'No such key')
     # self.assertEqual(coordinator.detect_deadlocks(), None)
     self.assertEqual(t0.perform_get('b'), 'No such key')
     self.assertEqual(t0.perform_put('a', 'a0'), 'Success')
     self.assertEqual(t0.perform_put('b', 'b0'), 'Success')
     # self.assertEqual(coordinator.detect_deadlocks(), None)
     self.assertEqual(t0.commit(), 'Transaction Completed')
     # self.assertEqual(coordinator.detect_deadlocks(), None)
     self.assertEqual(t1.perform_get('a'), 'a0')  # T1 R(a)
     self.assertEqual(t2.perform_get('b'), 'b0')  # T2 R(b)
     # self.assertEqual(coordinator.detect_deadlocks(), None)
     self.assertEqual(t1.perform_put('b', 'b1'), None)  # T1 W(b)
     # self.assertEqual(coordinator.detect_deadlocks(), None)
     self.assertEqual(t1.check_lock(), None)
     self.assertEqual(t2.perform_put('a', 'a1'), None)  # T2 W(a)
     abort_id = coordinator.detect_deadlocks()
     self.assertTrue(abort_id == 1 or abort_id == 2)
Esempio n. 2
0
    def test_staff_deadlock_two_cycles(self):
        lock_table = {}
        store = InMemoryKVStore()
        t2 = TransactionHandler(lock_table, 2, store)
        t4 = TransactionHandler(lock_table, 4, store)
        t6 = TransactionHandler(lock_table, 6, store)
        t8 = TransactionHandler(lock_table, 8, store)
        coordinator = TransactionCoordinator(lock_table)
        self.assertEqual(coordinator.detect_deadlocks(), None)
        # t2 has S lock on a; t4 wants X lock
        self.assertEqual(t2.perform_get('a'), 'No such key')
        self.assertEqual(t4.perform_put('a', 'a1'), None)
        # t4 has S lock on b; t2 wants X lock
        self.assertEqual(t4.perform_get('b'), 'No such key')
        self.assertEqual(t2.perform_put('b', 'b1'), None)
        # t6 has S lock on a; t8 wants X lock
        self.assertEqual(t6.perform_get('c'), 'No such key')
        self.assertEqual(t8.perform_put('c', 'c1'), None)
        # t8 has S lock on b; t6 wants X lock
        self.assertEqual(t8.perform_get('d'), 'No such key')
        self.assertEqual(t6.perform_put('d', 'd1'), None)

        abort_id = coordinator.detect_deadlocks()
        self.assertTrue(abort_id == 2 or abort_id == 4 or abort_id == 6 or abort_id == 8)

        abort_id = coordinator.detect_deadlocks()
        self.assertTrue(abort_id == 2 or abort_id == 4 or abort_id == 6 or abort_id == 8)
Esempio n. 3
0
 def test_multi_deadlock(self):
     lock_table = {}
     store = InMemoryKVStore()
     t0 = TransactionHandler(lock_table, 0, store)
     t1 = TransactionHandler(lock_table, 1, store)
     t2 = TransactionHandler(lock_table, 2, store)
     t3 = TransactionHandler(lock_table, 3, store)
     t4 = TransactionHandler(lock_table, 4, store)
     coordinator = TransactionCoordinator(lock_table)
     self.assertEqual(coordinator.detect_deadlocks(), None)
     self.assertEqual(t0.perform_put('a', 'apple'), 'Success')
     self.assertEqual(t0.commit(), 'Transaction Completed')
     self.assertEqual(t1.perform_get('a'), 'apple')
     self.assertEqual(t2.perform_get('a'), 'apple')
     self.assertEqual(coordinator.detect_deadlocks(), None)
     self.assertEqual(t1.perform_put('a', 'banana'), None)
     self.assertEqual(t2.perform_put('a', 'pear'), None)
     self.assertEqual(t3.perform_put('a', 'cherry'), None)
     self.assertEqual(t4.perform_put('a', 'orange'), None)
     aid = coordinator.detect_deadlocks()
     self.assertTrue(aid == 2 or aid == 1)
     self.assertEqual(t2.check_lock(), None)
     self.assertEqual(t1.abort(USER), 'User Abort')
     self.assertEqual(t2.check_lock(), 'Success')
     self.assertEqual(t2.perform_get('a'), 'pear')
     self.assertEqual(t3.check_lock(), None)
     self.assertEqual(t4.check_lock(), None)
     aa = coordinator.detect_deadlocks()
     self.assertEqual(aa, None)
Esempio n. 4
0
    def __init__(self,
                 kvstore_class=KVSTORE_CLASS,
                 log_level=logging.WARNING,
                 max_handlers=None):
        """
        Initializes the server. Does not start the polling loop. After the
        constructor returns, there can be no other servers.
        """
        self._logger = logging.getLogger('<%s>' % (self.__class__.__name__))
        self._logger.setLevel(log_level)
        self._remaining_handlers = max_handlers
        self._stats = [0, 0]
        self._lock_table = {}
        self._next_xid = 0
        self._store = kvstore_class()
        self._log_level = log_level
        self._txn_map = {}
        self._coordinator = TransactionCoordinator(self._lock_table)

        # Raise an exception if we can connect to an existing server. If a
        # context switch occurs in the middle of this code segment, or before
        # the socket is bound to the socket file, then this will fail. We
        # assume that the probability that the user constructs two servers in
        # two different processes at the same time is low, and we ignore this
        # edge case. It should not be a problem in any of the test files - most
        # of these only create a single instance of the server class.
        if os.path.exists(SOCKET_FILE):
            test_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            try:
                test_sock.connect(SOCKET_FILE)
                raise KVStoreError('Server seems to be running')
            except socket.error as e:
                pass
            finally:
                test_sock.close()
            os.unlink(SOCKET_FILE)

        try:
            asyncore.dispatcher.__init__(self)

            # Create socket, but do not connect to anything yet
            self.create_socket(socket.AF_UNIX, socket.SOCK_STREAM)
            self.set_reuse_addr()

            self.bind(SOCKET_FILE)
            self.listen(5)
        except Exception as e:
            exc = traceback.format_exc()
            self._logger.error(
                'Uncaught exception in __init__, closing server\n%s', exc[:-1])
            self.close()
            raise e

        self._logger.debug('Constructed server')
Esempio n. 5
0
 def test_deadlock_identical(self):
     # Should pass after 2
     lock_table = {}
     store = InMemoryKVStore()
     t0 = TransactionHandler(lock_table, 0, store)
     t2 = TransactionHandler(lock_table, 2, store)
     coordinator = TransactionCoordinator(lock_table)
     self.assertEqual(coordinator.detect_deadlocks(), None)
     self.assertEqual(t0.perform_put('a', 'a0'), 'Success')
     self.assertEqual(t0.perform_put('b', 'b0'), 'Success')
     self.assertEqual(t2.perform_get('a'), None)
     self.assertEqual(t2.perform_get('b'), None)
Esempio n. 6
0
 def test_unlock_rrr(self):
     # Should pass after 1.3
     lock_table = {}
     store = InMemoryKVStore()
     coordinator = TransactionCoordinator(lock_table)
     self.assertEqual(coordinator.detect_deadlocks(), None)
     t0 = TransactionHandler(lock_table, 0, store)
     t1 = TransactionHandler(lock_table, 1, store)
     t2 = TransactionHandler(lock_table, 2, store)
     t3 = TransactionHandler(lock_table, 3, store)
     self.assertEqual(t0.perform_get('a'), 'No such key')        # T0 R(a)
     self.assertEqual(t1.perform_get('a'), 'No such key')        # T1 R(a)
     self.assertEqual(t2.perform_get('a'), 'No such key')
     self.assertEqual(t3.perform_put('a', '0'), None)            # T0 W(a)
     self.assertEqual(coordinator.detect_deadlocks(), None)
Esempio n. 7
0
    def test_staff_deadlock_upgrade(self):
        lock_table = {}
        store = InMemoryKVStore()
        t2 = TransactionHandler(lock_table, 2, store)
        t4 = TransactionHandler(lock_table, 4, store)
        coordinator = TransactionCoordinator(lock_table)
        self.assertEqual(coordinator.detect_deadlocks(), None)
        # t2, t4 has S lock on a; t2 wants X lock
        self.assertEqual(t2.perform_get('a'), 'No such key')
        self.assertEqual(t4.perform_get('a'), 'No such key')
        self.assertEqual(t2.perform_put('a', 'a1'), None)
        # t4 now wants X lock
        self.assertEqual(t4.perform_put('a', 'a2'), None)

        abort_id = coordinator.detect_deadlocks()
        self.assertTrue(abort_id == 2 or abort_id == 4)
Esempio n. 8
0
    def test_staff_deadlock_ww_rw(self):
        lock_table = {}
        store = InMemoryKVStore()
        t0 = TransactionHandler(lock_table, 0, store)
        t1 = TransactionHandler(lock_table, 1, store)
        coordinator = TransactionCoordinator(lock_table)
        self.assertEqual(coordinator.detect_deadlocks(), None)
        # t0 has X lock on a; t1 wants X lock
        self.assertEqual(t0.perform_put('a', 'a0'), 'Success')
        self.assertEqual(t1.perform_put('a', 'a1'), None)
        # t1 has S lock on b; t0 wants X lock
        self.assertEqual(t1.perform_get('b'), 'No such key')
        self.assertEqual(t0.perform_put('b', 'b0'), None)

        abort_id = coordinator.detect_deadlocks()
        self.assertTrue(abort_id == 0 or abort_id == 1)
Esempio n. 9
0
 def test_deadlock_gap_queue(self):
     lock_table = {}
     store = InMemoryKVStore()
     t0 = TransactionHandler(lock_table, 0, store)
     t1 = TransactionHandler(lock_table, 1, store)
     t2 = TransactionHandler(lock_table, 2, store)
     t3 = TransactionHandler(lock_table, 3, store)
     coordinator = TransactionCoordinator(lock_table)
     self.assertEqual(coordinator.detect_deadlocks(), None)
     self.assertEqual(t2.perform_put('a', 'a0'), 'Success')
     self.assertEqual(t0.perform_get('a'), None)
     self.assertEqual(t3.perform_put('b', 'b0'), 'Success')
     self.assertEqual(t0.perform_get('b'), None)
     self.assertEqual(t1.perform_put('b', 'b1'), None)
     self.assertEqual(t2.perform_get('b'), None)
     abort_id = coordinator.detect_deadlocks()
     self.assertEqual(abort_id, None)