Pass byte strings straight through LogPrinter

This commit is contained in:
Aanand Prasad 2014-06-18 14:50:57 +01:00
parent 262248d8a6
commit d0b5bcf26a
3 changed files with 63 additions and 5 deletions

View File

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

View File

@ -1,2 +1,2 @@
#!/bin/sh
nosetests $@
PYTHONIOENCODING=ascii nosetests $@

View File

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