log_printer_test.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. from __future__ import absolute_import
  2. from __future__ import unicode_literals
  3. import pytest
  4. import six
  5. from compose.cli.log_printer import LogPrinter
  6. from compose.cli.log_printer import wait_on_exit
  7. from compose.container import Container
  8. from tests import mock
  9. def build_mock_container(reader):
  10. return mock.Mock(
  11. spec=Container,
  12. name='myapp_web_1',
  13. name_without_project='web_1',
  14. has_api_logs=True,
  15. log_stream=None,
  16. logs=reader,
  17. wait=mock.Mock(return_value=0),
  18. )
  19. @pytest.fixture
  20. def output_stream():
  21. output = six.StringIO()
  22. output.flush = mock.Mock()
  23. return output
  24. @pytest.fixture
  25. def mock_container():
  26. def reader(*args, **kwargs):
  27. yield b"hello\nworld"
  28. return build_mock_container(reader)
  29. class TestLogPrinter(object):
  30. def test_single_container(self, output_stream, mock_container):
  31. LogPrinter([mock_container], output=output_stream, log_args={'follow': True}).run()
  32. output = output_stream.getvalue()
  33. assert 'hello' in output
  34. assert 'world' in output
  35. # Call count is 2 lines + "container exited line"
  36. assert output_stream.flush.call_count == 3
  37. def test_single_container_without_stream(self, output_stream, mock_container):
  38. LogPrinter([mock_container], output=output_stream).run()
  39. output = output_stream.getvalue()
  40. assert 'hello' in output
  41. assert 'world' in output
  42. # Call count is 2 lines
  43. assert output_stream.flush.call_count == 2
  44. def test_monochrome(self, output_stream, mock_container):
  45. LogPrinter([mock_container], output=output_stream, monochrome=True).run()
  46. assert '\033[' not in output_stream.getvalue()
  47. def test_polychrome(self, output_stream, mock_container):
  48. LogPrinter([mock_container], output=output_stream).run()
  49. assert '\033[' in output_stream.getvalue()
  50. def test_unicode(self, output_stream):
  51. glyph = u'\u2022'
  52. def reader(*args, **kwargs):
  53. yield glyph.encode('utf-8') + b'\n'
  54. container = build_mock_container(reader)
  55. LogPrinter([container], output=output_stream).run()
  56. output = output_stream.getvalue()
  57. if six.PY2:
  58. output = output.decode('utf-8')
  59. assert glyph in output
  60. def test_wait_on_exit(self):
  61. exit_status = 3
  62. mock_container = mock.Mock(
  63. spec=Container,
  64. name='cname',
  65. wait=mock.Mock(return_value=exit_status))
  66. expected = '{} exited with code {}\n'.format(mock_container.name, exit_status)
  67. assert expected == wait_on_exit(mock_container)
  68. def test_generator_with_no_logs(self, mock_container, output_stream):
  69. mock_container.has_api_logs = False
  70. mock_container.log_driver = 'none'
  71. LogPrinter([mock_container], output=output_stream).run()
  72. output = output_stream.getvalue()
  73. assert "WARNING: no logs are available with the 'none' log driver\n" in output
  74. assert "exited with code" not in output