blob: 37b628733cc231fb9fe5aafabc10fbc61859e3c0 [file] [log] [blame]
# Copyright 2021 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Tests for pw_console.log_store"""
import logging
import unittest
from unittest.mock import MagicMock
from pw_console.log_store import LogStore
from pw_console.console_prefs import ConsolePrefs
def _create_log_store():
log_store = LogStore(prefs=ConsolePrefs(
project_file=False, project_user_file=False, user_file=False))
assert not log_store.table.prefs.show_python_file
viewer = MagicMock()
viewer.new_logs_arrived = MagicMock()
log_store.register_viewer(viewer)
return log_store, viewer
class TestLogStore(unittest.TestCase):
"""Tests for LogStore."""
def setUp(self):
self.maxDiff = None # pylint: disable=invalid-name
def test_get_total_count(self) -> None:
log_store, viewer = _create_log_store()
test_log = logging.getLogger('log_store.test')
# Must use the assertLogs context manager and the addHandler call.
with self.assertLogs(test_log, level='DEBUG') as log_context:
test_log.addHandler(log_store)
for i in range(5):
test_log.debug('Test log %s', i)
# Expected log message content
self.assertEqual(
['DEBUG:log_store.test:Test log {}'.format(i) for i in range(5)],
log_context.output,
)
# LogStore state checks
viewer.new_logs_arrived.assert_called()
self.assertEqual(5, log_store.get_total_count())
self.assertEqual(4, log_store.get_last_log_index())
log_store.clear_logs()
self.assertEqual(0, log_store.get_total_count())
def test_channel_counts_and_prefix_width(self) -> None:
"""Test logger names and prefix width calculations."""
log_store, _viewer = _create_log_store()
# Log some messagse on 3 separate logger instances
for i, logger_name in enumerate([
'log_store.test',
'log_store.dev',
'log_store.production',
]):
test_log = logging.getLogger(logger_name)
with self.assertLogs(test_log, level='DEBUG') as _log_context:
test_log.addHandler(log_store)
test_log.debug('Test log message')
for j in range(i):
test_log.debug('%s', j)
self.assertEqual(
{
'log_store.test': 1,
'log_store.dev': 2,
'log_store.production': 3,
},
log_store.channel_counts,
)
self.assertEqual(
'log_store.test: 1, log_store.dev: 2, log_store.production: 3',
log_store.get_channel_counts(),
)
self.assertRegex(
log_store.logs[0].ansi_stripped_log,
r'[0-9]{8} [0-9]{2}:[0-9]{2}:[0-9]{2} DEBUG Test log message',
)
self.assertEqual(
{
'log_store.test': 0,
'log_store.dev': 0,
'log_store.production': 0,
},
log_store.channel_formatted_prefix_widths,
)
def test_render_table_header_with_metadata(self) -> None:
log_store, _viewer = _create_log_store()
test_log = logging.getLogger('log_store.test')
# Log table with extra columns
with self.assertLogs(test_log, level='DEBUG') as _log_context:
test_log.addHandler(log_store)
test_log.debug('Test log %s',
extra=dict(extra_metadata_fields={
'planet': 'Jupiter',
'galaxy': 'Milky Way'
}))
self.assertEqual(
[
('bold', 'Time '),
('', ' '),
('bold', 'Level'),
('', ' '),
('bold', 'Planet '),
('', ' '),
('bold', 'Galaxy '),
('', ' '),
('bold', 'Message'),
],
log_store.render_table_header(),
)
if __name__ == '__main__':
unittest.main()