def test_logs_on_fatal_error(self): # Set up a logger whose output we'll be able to inspect. logs = StringIO() logger = logging.getLogger('TestLoggingThread') logger.addHandler(logging.StreamHandler(logs)) kobo_logger = LoggingBase(logger) # Set up hub to raise some exception other than an XML-RPC fault. mock_hub = Mock() mock_hub.upload_task_log.side_effect = RuntimeError("Simulated error") thread = LoggingThread(mock_hub, 9999, logger=kobo_logger) thread.daemon = True thread.start() thread.write('This is a log message!') # Since we set up a fatal error, we expect the thread to die soon # despite not calling stop(). thread.join(10.0) self.assertFalse(thread.is_alive()) # Before dying, it should have written something useful to the logs. captured = logs.getvalue() assert 'Fatal error in LoggingThread' in captured assert 'RuntimeError: Simulated error' in captured
def test_upload_task_log_on_stop(self): mock_hub = Mock() thread = LoggingThread(mock_hub, 9999) thread.daemon = True thread.start() self.assertTrue(thread.is_alive()) self.assertTrue(thread._running) thread.write('This is a log message!') mock_hub.upload_task_log.assert_not_called() thread.stop() self.assertFalse(thread.is_alive()) self.assertFalse(thread._running) mock_hub.upload_task_log.assert_called_once_with(ArgumentIsInstanceOf(BytesIO), 9999, 'stdout.log', append=True)
def test_upload_task_log_after_some_time(self): mock_hub = Mock() thread = LoggingThread(mock_hub, 9999) thread.daemon = True thread.start() self.assertTrue(thread.is_alive()) self.assertTrue(thread._running) for i in range(5): thread.write('%d - This is a very long message to be written in the log\n' % (i + 1)) mock_hub.upload_task_log.assert_not_called() # let the thread running for a while time.sleep(.1) mock_hub.upload_task_log.assert_called_once_with(ArgumentIsInstanceOf(BytesIO), 9999, 'stdout.log', append=True) thread.stop() self.assertFalse(thread.is_alive()) self.assertFalse(thread._running)
def test_upload_task_log_after_some_time(self): mock_hub = Mock() thread = LoggingThread(mock_hub, 9999) thread.daemon = True thread.start() self.assertTrue(thread.is_alive()) self.assertTrue(thread._running) for i in range(5): thread.write( '%d - This is a very long message to be written in the log\n' % (i + 1)) mock_hub.upload_task_log.assert_not_called() # let the thread running for a while time.sleep(.1) mock_hub.upload_task_log.assert_called_once_with( ArgumentIsInstanceOf(StringIO), 9999, 'stdout.log', append=True) thread.stop() self.assertFalse(thread.is_alive()) self.assertFalse(thread._running)
def test_upload_task_log_on_stop(self): mock_hub = Mock() thread = LoggingThread(mock_hub, 9999) thread.daemon = True thread.start() self.assertTrue(thread.is_alive()) self.assertTrue(thread._running) thread.write('This is a log message!') mock_hub.upload_task_log.assert_not_called() thread.stop() self.assertFalse(thread.is_alive()) self.assertFalse(thread._running) mock_hub.upload_task_log.assert_called_once_with( ArgumentIsInstanceOf(StringIO), 9999, 'stdout.log', append=True)
def test_mixed_writes(self): uploaded = [] # Used as a side-effect to keep whatever's uploaded def mock_upload(io, *args, **kwargs): uploaded.append(io.read()) mock_hub = Mock() mock_hub.upload_task_log.side_effect = mock_upload thread = LoggingThread(mock_hub, 9999) thread.daemon = True thread.start() # Mixing text, ascii-safe bytes, ascii-unsafe bytes here # as is possible with sys.stdout at least on py2. thread.write('Some text!') thread.write(b'Some bytes!') thread.write(u'Some 文!') thread.write(b'Some \xe2 wacky bytes!') # It should be able to stop normally thread.stop() self.assertFalse(thread.is_alive()) # It should have uploaded exactly the expected bytes. assert b''.join(uploaded) == ( b'Some text!Some bytes!' b'Some \xe6\x96\x87!Some \xe2 wacky bytes!')