diff --git a/fig/cli/log_printer.py b/fig/cli/log_printer.py index e302aecb7..0dc419e14 100644 --- a/fig/cli/log_printer.py +++ b/fig/cli/log_printer.py @@ -10,16 +10,17 @@ from .utils import split_buffer class LogPrinter(object): - def __init__(self, containers, attach_params=None): + def __init__(self, containers, attach_params=None, output=sys.stdout): self.containers = containers self.attach_params = attach_params or {} self.prefix_width = self._calculate_prefix_width(containers) self.generators = self._make_log_generators() + self.output = output def run(self): mux = Multiplexer(self.generators) for line in mux.loop(): - sys.stdout.write(line.encode(sys.__stdout__.encoding or 'utf-8')) + self.output.write(line) def _calculate_prefix_width(self, containers): """ @@ -45,12 +46,12 @@ class LogPrinter(object): return generators def _make_log_generator(self, container, color_fn): - prefix = color_fn(self._generate_prefix(container)) + prefix = color_fn(self._generate_prefix(container)).encode('utf-8') # Attach to container before log printer starts running line_generator = split_buffer(self._attach(container), '\n') for line in line_generator: - yield prefix + line.decode('utf-8') + yield prefix + line exit_code = container.wait() yield color_fn("%s exited with code %s\n" % (container.name, exit_code)) diff --git a/script/test b/script/test index 5f0f21f4a..c2cc315dd 100755 --- a/script/test +++ b/script/test @@ -1,2 +1,2 @@ #!/bin/sh -nosetests $@ +PYTHONIOENCODING=ascii nosetests $@ diff --git a/tests/unit/log_printer_test.py b/tests/unit/log_printer_test.py new file mode 100644 index 000000000..da2a83275 --- /dev/null +++ b/tests/unit/log_printer_test.py @@ -0,0 +1,57 @@ +from __future__ import unicode_literals +from __future__ import absolute_import +import os + +from fig.cli.log_printer import LogPrinter +from .. import unittest + + +class LogPrinterTest(unittest.TestCase): + def test_single_container(self): + def reader(*args, **kwargs): + yield "hello\nworld" + + container = MockContainer(reader) + output = run_log_printer([container]) + + self.assertIn('hello', output) + self.assertIn('world', output) + + def test_unicode(self): + glyph = u'\u2022'.encode('utf-8') + + def reader(*args, **kwargs): + yield glyph + b'\n' + + container = MockContainer(reader) + output = run_log_printer([container]) + + self.assertIn(glyph, output) + + +def run_log_printer(containers): + r, w = os.pipe() + reader, writer = os.fdopen(r, 'r'), os.fdopen(w, 'w') + printer = LogPrinter(containers, output=writer) + printer.run() + writer.close() + return reader.read() + + +class MockContainer(object): + def __init__(self, reader): + self._reader = reader + + @property + def name(self): + return 'myapp_web_1' + + @property + def name_without_project(self): + return 'web_1' + + def attach(self, *args, **kwargs): + return self._reader() + + def wait(self, *args, **kwargs): + return 0