Browse Source

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 <[email protected]>
Daniel Nephin 10 years ago
parent
commit
d32bb8efee
2 changed files with 42 additions and 41 deletions
  1. 1 0
      compose/cli/log_printer.py
  2. 41 41
      tests/unit/cli/log_printer_test.py

+ 1 - 0
compose/cli/log_printer.py

@@ -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):

+ 41 - 41
tests/unit/cli/log_printer_test.py

@@ -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)
-        return output
[email protected]
+def output_stream():
+    output = six.StringIO()
+    output.flush = mock.Mock()
+    return output
+
+
[email protected]
+def mock_container():
+    def reader(*args, **kwargs):
+        yield b"hello\nworld"
+    return build_mock_container(reader)
+
 
-    def test_single_container(self):
-        output = self.get_default_output()
+class TestLogPrinter(object):
 
-        self.assertIn('hello', output)
-        self.assertIn('world', output)
+    def test_single_container(self, output_stream, mock_container):
+        LogPrinter([mock_container], output=output_stream).run()
 
-    def test_monochrome(self):
-        output = self.get_default_output(monochrome=True)
-        self.assertNotIn('\033[', output)
+        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_polychrome(self):
-        output = self.get_default_output()
-        self.assertIn('\033[', output)
+    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_unicode(self):
+    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))
-
-    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))
-
-        output = run_log_printer([mock_container])
-        self.assertIn(
-            "WARNING: no logs are available with the 'none' log driver\n",
-            output
-        )
+        assert expected == wait_on_exit(mock_container)
 
+    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()
 
-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