async def test_mutex_are_independant(self): lock_1 = FifoLock() lock_2 = FifoLock() acquisition_history = await mutate_tasks_in_sequence( create_lock_tasks(lock_1(Mutex), lock_2(Mutex)), complete(0), complete(1), ) self.assertEqual(acquisition_history[0], [True, True])
async def test_mutex_blocks_mutex(self): lock = FifoLock() acquisition_history = await mutate_tasks_in_sequence( create_lock_tasks(lock(Mutex), lock(Mutex)), complete(0), complete(1), ) self.assertEqual(acquisition_history[0], [True, False]) self.assertEqual(acquisition_history[1], [True, True])
async def test_read_write_lock_read_allows_read(self): lock = FifoLock() acquisition_history = await mutate_tasks_in_sequence( create_lock_tasks(lock(Read), lock(Read)), complete(0), complete(1), ) self.assertEqual(acquisition_history[0], [True, True]) self.assertEqual(acquisition_history[1], [True, True])
async def test_mutex_mode_can_be_reused(self): lock = FifoLock() mode_instance = lock(Mutex) acquisition_history = await mutate_tasks_in_sequence( create_lock_tasks(mode_instance, mode_instance), complete(0), complete(1), ) self.assertEqual(acquisition_history[0], [True, False]) self.assertEqual(acquisition_history[1], [True, True])
async def test_semaphore_complete_out_of_order(self): lock = FifoLock() Semaphore = type('Semaphore', (SemaphoreBase, ), {'size': 2}) acquisition_history = await mutate_tasks_in_sequence( create_lock_tasks(lock(Semaphore), lock(Semaphore), lock(Semaphore)), complete(1), complete(0), complete(2), ) self.assertEqual(acquisition_history[0], [True, True, False]) self.assertEqual(acquisition_history[1], [True, True, True])
async def test_read_write_lock_write_not_given_priority_over_read(self): lock = FifoLock() acquisition_history = await mutate_tasks_in_sequence( create_lock_tasks(lock(Write), lock(Read), lock(Write)), complete(0), complete(1), complete(2), ) self.assertEqual(acquisition_history[0], [True, False, False]) self.assertEqual(acquisition_history[1], [True, True, False]) self.assertEqual(acquisition_history[2], [True, True, True])
async def test_mutex_cancelled_before_it_acquires_allows_later_mutex(self): lock = FifoLock() acquisition_history = await mutate_tasks_in_sequence( create_lock_tasks(lock(Mutex), lock(Mutex), lock(Mutex)), cancel(1), complete(0), complete(2), ) self.assertEqual(acquisition_history[0], [True, False, False]) self.assertEqual(acquisition_history[1], [True, False, False]) self.assertEqual(acquisition_history[2], [True, False, True])
async def test_read_write_lock_reads_complete_out_of_order_still_block_write( self): lock = FifoLock() acquisition_history = await mutate_tasks_in_sequence( create_lock_tasks(lock(Read), lock(Read), lock(Write)), complete(1), complete(0), complete(2), ) self.assertEqual(acquisition_history[0], [True, True, False]) self.assertEqual(acquisition_history[1], [True, True, False]) self.assertEqual(acquisition_history[2], [True, True, True])
async def test_mutex_raising_exception_bubbles_and_allows_later_mutex( self): lock = FifoLock() tasks = create_lock_tasks(lock(Mutex), lock(Mutex)) exp = Exception('Raised exception') acquisition_history = await mutate_tasks_in_sequence( tasks, exception(0, exp), complete(1), ) self.assertEqual(tasks[0].task.exception(), exp) self.assertEqual(acquisition_history[0], [True, False]) self.assertEqual(acquisition_history[1], [True, True])
async def test_mutex_requested_concurrently_can_acquire(self): lock = FifoLock() tasks_1 = create_lock_tasks(lock(Mutex)) acquisition_history_1 = await mutate_tasks_in_sequence(tasks_1 ) # No mutation tasks_2 = create_lock_tasks(lock(Mutex)) acquisition_history_2 = await mutate_tasks_in_sequence( tasks_1 + tasks_2, complete(0), complete(1), ) self.assertEqual(acquisition_history_2[0], [True, False]) self.assertEqual(acquisition_history_2[1], [True, True])
def with_locks(nodes, mode): return ((node, self._locks.setdefault(node, default=FifoLock()), mode) for node in nodes)