@@ -8,9 +8,11 @@
import unittest
import bb
+import bb.build
import os
import tempfile
import re
+import logging
class VerCmpString(unittest.TestCase):
@@ -693,6 +695,46 @@ class EnvironmentTests(unittest.TestCase):
self.assertEqual(os.environ["A"], "this is A")
self.assertNotIn("B", os.environ)
+class LogCatcherTests(unittest.TestCase):
+ def setUp(self):
+ self.logger = logging.getLogger("BitBake")
+ self.oldlevel = self.logger.level
+ self.logger.setLevel(logging.DEBUG)
+ self.catcher = bb.utils.LogCatcher()
+ self.logger.addHandler(self.catcher)
+
+ def tearDown(self):
+ self.logger.removeHandler(self.catcher)
+ self.logger.setLevel(self.oldlevel)
+
+ def test_records_capture_level_and_raw_message(self):
+ bb.warn("a warning")
+ bb.warnonce("a warn once")
+ bb.error("an error")
+ bb.erroronce("an error once")
+
+ self.assertEqual(self.catcher.records, [
+ (logging.WARNING, "a warning"),
+ (bb.msg.BBLogFormatter.WARNONCE, "a warn once"),
+ (logging.ERROR, "an error"),
+ (bb.msg.BBLogFormatter.ERRORONCE, "an error once"),
+ ])
+
+ def test_messages_are_formatted(self):
+ bb.warn("a warning")
+ self.assertEqual(self.catcher.messages, ["WARNING: a warning"])
+ self.assertTrue(self.catcher.contains("WARNING: a warning"))
+
+ def test_below_minimum_level_is_ignored(self):
+ bb.debug(1, "a debug")
+ bb.plain("a plain")
+ bb.note("a note")
+ bb.verbnote("a verb note")
+
+ self.assertEqual(self.catcher.records, [])
+ self.assertEqual(self.catcher.messages, [])
+
+
class FilemodeTests(unittest.TestCase):
def test_filemode_convert(self):
self.assertEqual(0o775, bb.utils.to_filemode("0o775"))
@@ -2154,9 +2154,11 @@ class LogCatcher(logging.Handler):
"""Logging handler for collecting logged messages so you can check them later"""
def __init__(self):
self.messages = []
- logging.Handler.__init__(self, logging.WARNING)
+ self.records = []
+ logging.Handler.__init__(self, bb.msg.BBLogFormatter.WARNONCE)
def emit(self, record):
self.messages.append(bb.build.logformatter.format(record))
+ self.records.append((record.levelno, record.getMessage()))
def contains(self, message):
return (message in self.messages)
LogCatcher stores only formatted messages, which strips the severity. Also record each log record's raw message and level, so callers can later replay them with their original severity. Lower the handler minimum level to WARNONCE so warnonce and erroronce messages are captured too. Add unit tests covering the captured levels and raw messages, the formatted output and the level filtering. AI-Generated: Uses opencode (DeepSeek V4 Flash) Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com> --- lib/bb/tests/utils.py | 42 ++++++++++++++++++++++++++++++++++++++++++ lib/bb/utils.py | 4 +++- 2 files changed, 45 insertions(+), 1 deletion(-)