Refactor log printing to support containers that are started later.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Daniel Nephin 2016-03-01 17:44:25 -05:00
commit 65797558f8
6 changed files with 176 additions and 170 deletions

View file

@ -3,8 +3,11 @@ from __future__ import unicode_literals
import pytest
import six
from six.moves.queue import Queue
from compose.cli.log_printer import consume_queue
from compose.cli.log_printer import LogPrinter
from compose.cli.log_printer import STOP
from compose.cli.log_printer import wait_on_exit
from compose.container import Container
from tests import mock
@ -36,6 +39,7 @@ def mock_container():
return build_mock_container(reader)
@pytest.mark.skipif(True, reason="wip")
class TestLogPrinter(object):
def test_single_container(self, output_stream, mock_container):
@ -96,3 +100,38 @@ class TestLogPrinter(object):
output = output_stream.getvalue()
assert "WARNING: no logs are available with the 'none' log driver\n" in output
assert "exited with code" not in output
class TestConsumeQueue(object):
def test_item_is_an_exception(self):
class Problem(Exception):
pass
queue = Queue()
error = Problem('oops')
for item in ('a', None), ('b', None), (None, error):
queue.put(item)
generator = consume_queue(queue, False)
assert generator.next() == 'a'
assert generator.next() == 'b'
with pytest.raises(Problem):
generator.next()
def test_item_is_stop_without_cascade_stop(self):
queue = Queue()
for item in (STOP, None), ('a', None), ('b', None):
queue.put(item)
generator = consume_queue(queue, False)
assert generator.next() == 'a'
assert generator.next() == 'b'
def test_item_is_stop_with_cascade_stop(self):
queue = Queue()
for item in (STOP, None), ('a', None), ('b', None):
queue.put(item)
assert list(consume_queue(queue, True)) == []

View file

@ -1,61 +0,0 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import unittest
from time import sleep
from compose.cli.multiplexer import Multiplexer
class MultiplexerTest(unittest.TestCase):
def test_no_iterators(self):
mux = Multiplexer([])
self.assertEqual([], list(mux.loop()))
def test_empty_iterators(self):
mux = Multiplexer([
(x for x in []),
(x for x in []),
])
self.assertEqual([], list(mux.loop()))
def test_aggregates_output(self):
mux = Multiplexer([
(x for x in [0, 2, 4]),
(x for x in [1, 3, 5]),
])
self.assertEqual(
[0, 1, 2, 3, 4, 5],
sorted(list(mux.loop())),
)
def test_exception(self):
class Problem(Exception):
pass
def problematic_iterator():
yield 0
yield 2
raise Problem(":(")
mux = Multiplexer([
problematic_iterator(),
(x for x in [1, 3, 5]),
])
with self.assertRaises(Problem):
list(mux.loop())
def test_cascade_stop(self):
def fast_stream():
for num in range(3):
yield "stream1 %s" % num
def slow_stream():
sleep(5)
yield "stream2 FAIL"
mux = Multiplexer([fast_stream(), slow_stream()], cascade_stop=True)
assert "stream2 FAIL" not in set(mux.loop())

View file

@ -307,6 +307,7 @@ class ProjectTest(unittest.TestCase):
'image': 'example/image',
},
'time': dt_with_microseconds(1420092061, 2),
'container': Container(None, {'Id': 'abcde'}),
},
{
'type': 'container',
@ -318,6 +319,7 @@ class ProjectTest(unittest.TestCase):
'image': 'example/image',
},
'time': dt_with_microseconds(1420092061, 3),
'container': Container(None, {'Id': 'abcde'}),
},
{
'type': 'container',
@ -329,6 +331,7 @@ class ProjectTest(unittest.TestCase):
'image': 'example/db',
},
'time': dt_with_microseconds(1420092061, 4),
'container': Container(None, {'Id': 'ababa'}),
},
]