def test_dequeue(self): """Test that we can enqueue and dequeue on different threads""" queue = ScriptRequestQueue() # This should return immediately self.assertEqual((None, None), queue.dequeue()) lock = Lock() dequeued_evt = [None] def get_event(): with lock: return dequeued_evt[0] def set_event(value): with lock: dequeued_evt[0] = value def do_dequeue(): event = None while event is None: event, _ = queue.dequeue() set_event(event) thread = Thread(target=do_dequeue, name="test_dequeue") thread.start() self.assertIsNone(get_event()) queue.enqueue(ScriptRequest.STOP) time.sleep(0.1) self.assertEqual(ScriptRequest.STOP, get_event()) thread.join(timeout=0.25) self.assertFalse(thread.is_alive())
def test_rerun_data_coalescing(self): """Test that multiple RERUN requests get coalesced with expected values. (This is similar to widgets_test.test_coalesce_widget_states - it's testing the same thing, but through the ScriptEventQueue interface.) """ queue = ScriptRequestQueue() session_state = SessionState() states = WidgetStates() _create_widget("trigger", states).trigger_value = True _create_widget("int", states).int_value = 123 queue.enqueue(ScriptRequest.RERUN, RerunData(widget_states=states)) states = WidgetStates() _create_widget("trigger", states).trigger_value = False _create_widget("int", states).int_value = 456 session_state.set_metadata( WidgetMetadata("trigger", lambda x, s: x, None, "trigger_value")) session_state.set_metadata( WidgetMetadata("int", lambda x, s: x, lambda x: x, "int_value")) queue.enqueue(ScriptRequest.RERUN, RerunData(widget_states=states)) event, data = queue.dequeue() self.assertEqual(event, ScriptRequest.RERUN) session_state.set_widgets_from_proto(data.widget_states) # Coalesced triggers should be True if either the old or # new value was True self.assertEqual(True, session_state.get("trigger")) # Other widgets should have their newest value self.assertEqual(456, session_state.get("int")) # We should have no more events self.assertEqual((None, None), queue.dequeue(), "Expected empty event queue") # Test that we can coalesce if previous widget state is None queue.enqueue(ScriptRequest.RERUN, RerunData(widget_states=None)) queue.enqueue(ScriptRequest.RERUN, RerunData(widget_states=None)) states = WidgetStates() _create_widget("int", states).int_value = 789 queue.enqueue(ScriptRequest.RERUN, RerunData(widget_states=states)) event, data = queue.dequeue() session_state.set_widgets_from_proto(data.widget_states) self.assertEqual(event, ScriptRequest.RERUN) self.assertEqual(789, session_state.get("int")) # We should have no more events self.assertEqual((None, None), queue.dequeue(), "Expected empty event queue") # Test that we can coalesce if our *new* widget state is None states = WidgetStates() _create_widget("int", states).int_value = 101112 queue.enqueue(ScriptRequest.RERUN, RerunData(widget_states=states)) queue.enqueue(ScriptRequest.RERUN, RerunData(widget_states=None)) event, data = queue.dequeue() session_state.set_widgets_from_proto(data.widget_states) self.assertEqual(event, ScriptRequest.RERUN) self.assertEqual(101112, session_state.get("int")) # We should have no more events self.assertEqual((None, None), queue.dequeue(), "Expected empty event queue")