def test_stopping_start_raises(self): checker = check.DirectioChecker(self.loop, "/path", self.complete) checker.start() try: checker.stop() self.assertRaises(RuntimeError, checker.start) finally: start_thread(self.wait_for_checker, checker) self.loop.run_forever()
def test_stopping_stop_ignored(self): checker = check.DirectioChecker(self.loop, "/path", self.complete) checker.start() try: checker.stop() checker.stop() # Will be ignored self.assertTrue(checker.is_running()) finally: start_thread(self.wait_for_checker, checker) self.loop.run_forever()
def test_stopping_repr(self): checker = check.DirectioChecker(self.loop, "/path", self.complete) checker.start() try: checker.stop() print(checker) self.assertIn("/path", str(checker)) self.assertIn(check.STOPPING, str(checker)) self.assertNotIn("next_check=", str(checker)) finally: start_thread(self.wait_for_checker, checker) self.loop.run_forever()
def test_fairness(self, writers, readers): lock = RWLock() ready = Barrier(writers + readers + 1) done = threading.Event() reads = [0] * readers writes = [0] * writers threads = [] def read(slot): ready.wait() while not done.is_set(): with lock.shared: reads[slot] += 1 def write(slot): ready.wait() while not done.is_set(): with lock.exclusive: writes[slot] += 1 try: for i in range(readers): t = start_thread(read, i) threads.append(t) for i in range(writers): t = start_thread(write, i) threads.append(t) ready.wait(5) time.sleep(1) finally: done.set() for t in threads: t.join() print() # TODO: needed to work around bug in expandPermutations when using # decorated test methods. print("writers: %d readers: %d" % (writers, readers)) avg_writes, med_writes, min_writes, max_writes = stats(writes) print("writes avg=%.2f med=%d min=%d max=%d" % (avg_writes, med_writes, min_writes, max_writes)) avg_reads, med_reads, min_reads, max_reads = stats(reads) print("reads avg=%.2f med=%d min=%d max=%d" % (avg_reads, med_reads, min_reads, max_reads)) avg_all = stats(writes + reads)[0] self.assertAlmostEqual(avg_reads, avg_writes, delta=avg_all / 10)
def test_readers(self, readers): lock = RWLock() ready = Barrier(readers + 1) done = threading.Event() reads = [0] * readers threads = [] def read(slot): ready.wait() while not done.is_set(): with lock.shared: reads[slot] += 1 try: for i in range(readers): t = start_thread(read, i) threads.append(t) ready.wait(5) time.sleep(1) finally: done.set() for t in threads: t.join() print() avg_reads, med_reads, min_reads, max_reads = stats(reads) print("reads avg=%.2f med=%d min=%d max=%d" % (avg_reads, med_reads, min_reads, max_reads))
def test_wakeup_all_blocked_readers(self): lock = RWLock() readers = 10 ready = Barrier(readers + 1) done = Barrier(readers + 1) threads = [] def slow_reader(): ready.wait(2) with lock.shared: time.sleep(0.5) done.wait(2) try: with lock.exclusive: # Start all readers for i in range(readers): t = start_thread(slow_reader) threads.append(t) # Wait until all readers are ready ready.wait(0.5) # Ensure that all readers are blocked time.sleep(0.5) # Releasing the write lock should wake up all the readers, holding # the lock for about 0.5 seconds. with self.assertNotRaises(): done.wait(2) finally: for t in threads: t.join()
def test_abort_during_copy(self, env_type): fmt = sc.RAW_FORMAT with self.get_vols(env_type, fmt, fmt) as (src_chain, dst_chain): src_vol = src_chain[0] dst_vol = dst_chain[0] gen_id = dst_vol.getMetaParam(sc.GENERATION) source = dict(endpoint_type='div', sd_id=src_vol.sdUUID, img_id=src_vol.imgUUID, vol_id=src_vol.volUUID, generation=0) dest = dict(endpoint_type='div', sd_id=dst_vol.sdUUID, img_id=dst_vol.imgUUID, vol_id=dst_vol.volUUID, generation=gen_id) fake_convert = FakeQemuConvertChecker(src_vol, dst_vol, wait_for_abort=True) with MonkeyPatchScope([(qemuimg, 'convert', fake_convert)]): job_id = make_uuid() job = storage.sdm.api.copy_data.Job(job_id, 0, source, dest) t = start_thread(job.run) if not fake_convert.ready_event.wait(1): raise RuntimeError("Timeout waiting for thread") job.abort() t.join(1) if t.isAlive(): raise RuntimeError("Timeout waiting for thread") self.assertEqual(jobs.STATUS.ABORTED, job.status) self.assertEqual(sc.ILLEGAL_VOL, dst_vol.getLegality()) self.assertEqual(gen_id, dst_vol.getMetaParam(sc.GENERATION))
def test_abort_during_copy(self, env_type): fmt = sc.RAW_FORMAT with self.make_env(env_type, fmt, fmt) as env: src_vol = env.src_chain[0] dst_vol = env.dst_chain[0] gen_id = dst_vol.getMetaParam(sc.GENERATION) source = dict(endpoint_type='div', sd_id=src_vol.sdUUID, img_id=src_vol.imgUUID, vol_id=src_vol.volUUID, generation=0) dest = dict(endpoint_type='div', sd_id=dst_vol.sdUUID, img_id=dst_vol.imgUUID, vol_id=dst_vol.volUUID, generation=gen_id) fake_convert = FakeQemuConvertChecker(src_vol, dst_vol, wait_for_abort=True) with MonkeyPatchScope([(qemuimg, 'convert', fake_convert)]): job_id = make_uuid() job = storage.sdm.api.copy_data.Job(job_id, 0, source, dest) t = start_thread(job.run) if not fake_convert.ready_event.wait(1): raise RuntimeError("Timeout waiting for thread") job.abort() t.join(1) if t.isAlive(): raise RuntimeError("Timeout waiting for thread") self.assertEqual(jobs.STATUS.ABORTED, job.status) self.assertEqual(sc.ILLEGAL_VOL, dst_vol.getLegality()) self.assertEqual(gen_id, dst_vol.getMetaParam(sc.GENERATION))
def test_abort_running_job(self): job = StuckJob() jobs.add(job) t = start_thread(job.run) job.event_running.wait(1) self.assertEqual(jobs.STATUS.RUNNING, job.status) jobs.abort(job.id) t.join() self.assertEqual(jobs.STATUS.ABORTED, job.status)
def test_lock_contention(self, writers, readers): lock = RWLock() ready = Barrier(writers + readers + 1) done = threading.Event() reads = [0] * readers writes = [0] * writers threads = [] def read(slot): ready.wait() while not done.is_set(): with lock.shared: reads[slot] += 1 def write(slot): ready.wait() while not done.is_set(): with lock.exclusive: writes[slot] += 1 try: for i in range(readers): t = start_thread(read, i) threads.append(t) for i in range(writers): t = start_thread(write, i) threads.append(t) ready.wait(5) time.sleep(1) finally: done.set() for t in threads: t.join() print() print("writers: %d readers: %d" % (writers, readers)) avg_writes, med_writes, min_writes, max_writes = stats(writes) print("writes avg=%.2f med=%d min=%d max=%d" % (avg_writes, med_writes, min_writes, max_writes)) avg_reads, med_reads, min_reads, max_reads = stats(reads) print("reads avg=%.2f med=%d min=%d max=%d" % (avg_reads, med_reads, min_reads, max_reads))
def test_iterate_while_events(self): """Tests if monitor is able to catch event while iterating. Before the iteration we start _set_and_remove_device, which is delayed for .2 seconds. Then iteration starts and wait for new dummy. """ dummy = Dummy() dummy_name = dummy.create() def _set_and_remove_device(): time.sleep(.2) dummy.up() dummy.remove() with monitor.Monitor(timeout=self.TIMEOUT) as mon: add_device_thread = start_thread(_set_and_remove_device) for event in mon: if event.get('name') == dummy_name: break add_device_thread.join()