def test_callback_deadlock(self): flag = threading.Event() # try waiting for the future from the callback fut = FluxExecutorFuture(threading.get_ident()).add_jobid_callback( lambda fut: (fut.result(), flag.set()) ) fut._set_jobid(5) # check that flag wasn't set---because the callback raised self.assertFalse(flag.is_set()) # try the same with an event callback log_event = EventLogEvent({"name": "debug", "timestamp": 0}) fut.add_event_callback( log_event.name, lambda fut, event: (fut.result(), flag.set()) ) fut._set_event(log_event) self.assertFalse(flag.is_set()) # now complete the future and try again fut.set_result(21) fut.add_jobid_callback(lambda fut: (fut.result(), flag.set())) self.assertTrue(flag.is_set()) flag.clear() fut.add_event_callback( log_event.name, lambda fut, event: (fut.result(), flag.set()) ) self.assertTrue(flag.is_set())
def test_bad_event(self): fut = FluxExecutorFuture(threading.get_ident()) event = "not an event" log_event = EventLogEvent({"name": event, "timestamp": 0}) with self.assertRaises(ValueError): fut._set_event(log_event) with self.assertRaises(ValueError): fut.add_event_callback(event, None)
def test_adding_callbacks_from_callbacks(self): fut = FluxExecutorFuture(threading.get_ident()) flag = threading.Event() nested_callback = lambda fut, event: flag.set() fut.add_event_callback( "start", lambda fut, event: fut.add_event_callback( "start", nested_callback)) fut._set_event(EventLogEvent({"name": "start", "timestamp": 0})) self.assertTrue(flag.is_set())
def test_multiple_events(self): fut = FluxExecutorFuture(threading.get_ident()) counter = itertools.count() fut.add_event_callback("urgency", lambda fut, event: next(counter)) total_iterations = 5 for _ in range(5): fut._set_event(EventLogEvent({"name": "urgency", "timestamp": 0})) self.assertEqual(next(counter), total_iterations) new_counter = itertools.count() fut.add_event_callback("urgency", lambda fut, event: next(new_counter)) self.assertEqual(next(new_counter), total_iterations) fut._set_event(EventLogEvent({"name": "urgency", "timestamp": 0})) # invoking the callback increments the counter, as does checking the counter self.assertEqual(next(counter), total_iterations + 2) self.assertEqual(next(new_counter), total_iterations + 2)
def test_event_callback(self): fut = FluxExecutorFuture(threading.get_ident()) flag = threading.Event() for state in ("clean", "start", "alloc"): flag.clear() fut.add_event_callback( state, lambda f, log: (flag.set(), self.assertEqual(log.name, state))) log_event = EventLogEvent({"name": state, "timestamp": 0}) fut._set_event(log_event) self.assertTrue(flag.is_set()) # now check that adding callbacks fires them immediately flag.clear() fut.add_event_callback( state, lambda f, log: (flag.set(), self.assertEqual(log.name, state))) self.assertTrue(flag.is_set())