Fix #1549 - flush after each line of logs.

Includes some refactoring of log_printer_test to support checking for flush(), and so that each test calls the unit-under-test directly, instead of through a helper function.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Daniel Nephin 2015-11-05 15:33:42 -05:00
parent de08da278d
commit 36176befb0
2 changed files with 42 additions and 41 deletions

View File

@ -26,6 +26,7 @@ class LogPrinter(object):
generators = list(self._make_log_generators(self.monochrome, prefix_width))
for line in Multiplexer(generators).loop():
self.output.write(line)
self.output.flush()
def _make_log_generators(self, monochrome, prefix_width):
def no_color(text):

View File

@ -1,13 +1,13 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import mock
import pytest
import six
from compose.cli.log_printer import LogPrinter
from compose.cli.log_printer import wait_on_exit
from compose.container import Container
from tests import unittest
from tests import mock
def build_mock_container(reader):
@ -22,40 +22,52 @@ def build_mock_container(reader):
)
class LogPrinterTest(unittest.TestCase):
def get_default_output(self, monochrome=False):
def reader(*args, **kwargs):
yield b"hello\nworld"
container = build_mock_container(reader)
output = run_log_printer([container], monochrome=monochrome)
@pytest.fixture
def output_stream():
output = six.StringIO()
output.flush = mock.Mock()
return output
def test_single_container(self):
output = self.get_default_output()
self.assertIn('hello', output)
self.assertIn('world', output)
@pytest.fixture
def mock_container():
def reader(*args, **kwargs):
yield b"hello\nworld"
return build_mock_container(reader)
def test_monochrome(self):
output = self.get_default_output(monochrome=True)
self.assertNotIn('\033[', output)
def test_polychrome(self):
output = self.get_default_output()
self.assertIn('\033[', output)
class TestLogPrinter(object):
def test_unicode(self):
def test_single_container(self, output_stream, mock_container):
LogPrinter([mock_container], output=output_stream).run()
output = output_stream.getvalue()
assert 'hello' in output
assert 'world' in output
# Call count is 2 lines + "container exited line"
assert output_stream.flush.call_count == 3
def test_monochrome(self, output_stream, mock_container):
LogPrinter([mock_container], output=output_stream, monochrome=True).run()
assert '\033[' not in output_stream.getvalue()
def test_polychrome(self, output_stream, mock_container):
LogPrinter([mock_container], output=output_stream).run()
assert '\033[' in output_stream.getvalue()
def test_unicode(self, output_stream):
glyph = u'\u2022'
def reader(*args, **kwargs):
yield glyph.encode('utf-8') + b'\n'
container = build_mock_container(reader)
output = run_log_printer([container])
LogPrinter([container], output=output_stream).run()
output = output_stream.getvalue()
if six.PY2:
output = output.decode('utf-8')
self.assertIn(glyph, output)
assert glyph in output
def test_wait_on_exit(self):
exit_status = 3
@ -65,24 +77,12 @@ class LogPrinterTest(unittest.TestCase):
wait=mock.Mock(return_value=exit_status))
expected = '{} exited with code {}\n'.format(mock_container.name, exit_status)
self.assertEqual(expected, wait_on_exit(mock_container))
assert expected == wait_on_exit(mock_container)
def test_generator_with_no_logs(self):
mock_container = mock.Mock(
spec=Container,
has_api_logs=False,
log_driver='none',
name_without_project='web_1',
wait=mock.Mock(return_value=0))
def test_generator_with_no_logs(self, mock_container, output_stream):
mock_container.has_api_logs = False
mock_container.log_driver = 'none'
LogPrinter([mock_container], output=output_stream).run()
output = run_log_printer([mock_container])
self.assertIn(
"WARNING: no logs are available with the 'none' log driver\n",
output
)
def run_log_printer(containers, monochrome=False):
output = six.StringIO()
LogPrinter(containers, output=output, monochrome=monochrome).run()
return output.getvalue()
output = output_stream.getvalue()
assert "WARNING: no logs are available with the 'none' log driver\n" in output