From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- testing/mozbase/mozlog/mozlog/__init__.py | 34 + testing/mozbase/mozlog/mozlog/capture.py | 96 ++ testing/mozbase/mozlog/mozlog/commandline.py | 344 ++++++ .../mozbase/mozlog/mozlog/formatters/__init__.py | 32 + testing/mozbase/mozlog/mozlog/formatters/base.py | 25 + .../mozlog/mozlog/formatters/errorsummary.py | 163 +++ .../mozbase/mozlog/mozlog/formatters/grouping.py | 391 +++++++ .../mozlog/mozlog/formatters/html/__init__.py | 7 + .../mozbase/mozlog/mozlog/formatters/html/html.py | 343 ++++++ .../mozbase/mozlog/mozlog/formatters/html/main.js | 166 +++ .../mozlog/mozlog/formatters/html/style.css | 155 +++ .../mozlog/mozlog/formatters/html/xmlgen.py | 312 ++++++ .../mozlog/mozlog/formatters/machformatter.py | 651 ++++++++++++ .../mozbase/mozlog/mozlog/formatters/process.py | 60 ++ .../mozlog/mozlog/formatters/tbplformatter.py | 446 ++++++++ .../mozbase/mozlog/mozlog/formatters/unittest.py | 83 ++ testing/mozbase/mozlog/mozlog/formatters/xunit.py | 115 ++ testing/mozbase/mozlog/mozlog/handlers/__init__.py | 19 + testing/mozbase/mozlog/mozlog/handlers/base.py | 124 +++ .../mozlog/mozlog/handlers/bufferhandler.py | 86 ++ .../mozlog/mozlog/handlers/messagehandler.py | 39 + .../mozlog/mozlog/handlers/statushandler.py | 87 ++ .../mozlog/mozlog/handlers/summaryhandler.py | 193 ++++ .../mozlog/mozlog/handlers/valgrindhandler.py | 138 +++ testing/mozbase/mozlog/mozlog/logtypes.py | 302 ++++++ testing/mozbase/mozlog/mozlog/proxy.py | 81 ++ .../mozlog/mozlog/pytest_mozlog/__init__.py | 0 .../mozbase/mozlog/mozlog/pytest_mozlog/plugin.py | 127 +++ testing/mozbase/mozlog/mozlog/reader.py | 78 ++ testing/mozbase/mozlog/mozlog/scripts/__init__.py | 41 + testing/mozbase/mozlog/mozlog/scripts/format.py | 55 + testing/mozbase/mozlog/mozlog/scripts/logmerge.py | 90 ++ testing/mozbase/mozlog/mozlog/scripts/unstable.py | 148 +++ testing/mozbase/mozlog/mozlog/stdadapter.py | 50 + testing/mozbase/mozlog/mozlog/structuredlog.py | 769 ++++++++++++++ .../mozbase/mozlog/mozlog/unstructured/__init__.py | 8 + .../mozbase/mozlog/mozlog/unstructured/logger.py | 191 ++++ .../mozlog/mozlog/unstructured/loggingmixin.py | 42 + .../mozlog/mozlog/unstructured/loglistener.py | 50 + testing/mozbase/mozlog/setup.cfg | 2 + testing/mozbase/mozlog/setup.py | 43 + testing/mozbase/mozlog/tests/conftest.py | 24 + testing/mozbase/mozlog/tests/manifest.ini | 9 + testing/mozbase/mozlog/tests/test_capture.py | 37 + testing/mozbase/mozlog/tests/test_errorsummary.py | 125 +++ testing/mozbase/mozlog/tests/test_formatters.py | 767 ++++++++++++++ testing/mozbase/mozlog/tests/test_logger.py | 303 ++++++ testing/mozbase/mozlog/tests/test_logtypes.py | 106 ++ testing/mozbase/mozlog/tests/test_structured.py | 1098 ++++++++++++++++++++ .../mozbase/mozlog/tests/test_terminal_colors.py | 62 ++ 50 files changed, 8717 insertions(+) create mode 100644 testing/mozbase/mozlog/mozlog/__init__.py create mode 100644 testing/mozbase/mozlog/mozlog/capture.py create mode 100644 testing/mozbase/mozlog/mozlog/commandline.py create mode 100644 testing/mozbase/mozlog/mozlog/formatters/__init__.py create mode 100644 testing/mozbase/mozlog/mozlog/formatters/base.py create mode 100644 testing/mozbase/mozlog/mozlog/formatters/errorsummary.py create mode 100644 testing/mozbase/mozlog/mozlog/formatters/grouping.py create mode 100644 testing/mozbase/mozlog/mozlog/formatters/html/__init__.py create mode 100755 testing/mozbase/mozlog/mozlog/formatters/html/html.py create mode 100644 testing/mozbase/mozlog/mozlog/formatters/html/main.js create mode 100644 testing/mozbase/mozlog/mozlog/formatters/html/style.css create mode 100644 testing/mozbase/mozlog/mozlog/formatters/html/xmlgen.py create mode 100644 testing/mozbase/mozlog/mozlog/formatters/machformatter.py create mode 100644 testing/mozbase/mozlog/mozlog/formatters/process.py create mode 100644 testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py create mode 100755 testing/mozbase/mozlog/mozlog/formatters/unittest.py create mode 100644 testing/mozbase/mozlog/mozlog/formatters/xunit.py create mode 100644 testing/mozbase/mozlog/mozlog/handlers/__init__.py create mode 100644 testing/mozbase/mozlog/mozlog/handlers/base.py create mode 100644 testing/mozbase/mozlog/mozlog/handlers/bufferhandler.py create mode 100644 testing/mozbase/mozlog/mozlog/handlers/messagehandler.py create mode 100644 testing/mozbase/mozlog/mozlog/handlers/statushandler.py create mode 100644 testing/mozbase/mozlog/mozlog/handlers/summaryhandler.py create mode 100644 testing/mozbase/mozlog/mozlog/handlers/valgrindhandler.py create mode 100644 testing/mozbase/mozlog/mozlog/logtypes.py create mode 100644 testing/mozbase/mozlog/mozlog/proxy.py create mode 100644 testing/mozbase/mozlog/mozlog/pytest_mozlog/__init__.py create mode 100644 testing/mozbase/mozlog/mozlog/pytest_mozlog/plugin.py create mode 100644 testing/mozbase/mozlog/mozlog/reader.py create mode 100644 testing/mozbase/mozlog/mozlog/scripts/__init__.py create mode 100644 testing/mozbase/mozlog/mozlog/scripts/format.py create mode 100644 testing/mozbase/mozlog/mozlog/scripts/logmerge.py create mode 100644 testing/mozbase/mozlog/mozlog/scripts/unstable.py create mode 100644 testing/mozbase/mozlog/mozlog/stdadapter.py create mode 100644 testing/mozbase/mozlog/mozlog/structuredlog.py create mode 100644 testing/mozbase/mozlog/mozlog/unstructured/__init__.py create mode 100644 testing/mozbase/mozlog/mozlog/unstructured/logger.py create mode 100644 testing/mozbase/mozlog/mozlog/unstructured/loggingmixin.py create mode 100644 testing/mozbase/mozlog/mozlog/unstructured/loglistener.py create mode 100644 testing/mozbase/mozlog/setup.cfg create mode 100644 testing/mozbase/mozlog/setup.py create mode 100644 testing/mozbase/mozlog/tests/conftest.py create mode 100644 testing/mozbase/mozlog/tests/manifest.ini create mode 100644 testing/mozbase/mozlog/tests/test_capture.py create mode 100644 testing/mozbase/mozlog/tests/test_errorsummary.py create mode 100644 testing/mozbase/mozlog/tests/test_formatters.py create mode 100644 testing/mozbase/mozlog/tests/test_logger.py create mode 100644 testing/mozbase/mozlog/tests/test_logtypes.py create mode 100644 testing/mozbase/mozlog/tests/test_structured.py create mode 100644 testing/mozbase/mozlog/tests/test_terminal_colors.py (limited to 'testing/mozbase/mozlog') diff --git a/testing/mozbase/mozlog/mozlog/__init__.py b/testing/mozbase/mozlog/mozlog/__init__.py new file mode 100644 index 0000000000..82d40b5c55 --- /dev/null +++ b/testing/mozbase/mozlog/mozlog/__init__.py @@ -0,0 +1,34 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +""" +Mozlog aims to standardize log handling and formatting within Mozilla. + +It implements a JSON-based structured logging protocol with convenience +facilities for recording test results. + +The old unstructured module is deprecated. It simply wraps Python's +logging_ module and adds a few convenience methods for logging test +results and events. +""" + +import sys + +from . import commandline, structuredlog, unstructured +from .proxy import get_proxy_logger +from .structuredlog import get_default_logger, set_default_logger + +# Backwards compatibility shim for consumers that use mozlog.structured +structured = sys.modules[__name__] +sys.modules["{}.structured".format(__name__)] = structured + +__all__ = [ + "commandline", + "structuredlog", + "unstructured", + "get_default_logger", + "set_default_logger", + "get_proxy_logger", + "structured", +] diff --git a/testing/mozbase/mozlog/mozlog/capture.py b/testing/mozbase/mozlog/mozlog/capture.py new file mode 100644 index 0000000000..75717d62c8 --- /dev/null +++ b/testing/mozbase/mozlog/mozlog/capture.py @@ -0,0 +1,96 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import sys +import threading +from io import BytesIO + + +class LogThread(threading.Thread): + def __init__(self, queue, logger, level): + self.queue = queue + self.log_func = getattr(logger, level) + threading.Thread.__init__(self, name="Thread-Log") + self.daemon = True + + def run(self): + while True: + try: + msg = self.queue.get() + except (EOFError, IOError): + break + if msg is None: + break + else: + self.log_func(msg) + + +class LoggingWrapper(BytesIO): + """Wrapper for file like objects to redirect output to logger + instead""" + + def __init__(self, queue, prefix=None): + BytesIO.__init__(self) + self.queue = queue + self.prefix = prefix + self.buffer = self + + def write(self, data): + if isinstance(data, bytes): + try: + data = data.decode("utf8") + except UnicodeDecodeError: + data = data.decode("unicode_escape") + + if data.endswith("\n"): + data = data[:-1] + if data.endswith("\r"): + data = data[:-1] + if not data: + return + if self.prefix is not None: + data = "%s: %s" % (self.prefix, data) + self.queue.put(data) + + def flush(self): + pass + + +class CaptureIO(object): + def __init__(self, logger, do_capture, mp_context=None): + if mp_context is None: + import multiprocessing as mp_context + self.logger = logger + self.do_capture = do_capture + self.logging_queue = None + self.logging_thread = None + self.original_stdio = None + self.mp_context = mp_context + + def __enter__(self): + if self.do_capture: + self.original_stdio = (sys.stdout, sys.stderr) + self.logging_queue = self.mp_context.Queue() + self.logging_thread = LogThread(self.logging_queue, self.logger, "info") + sys.stdout = LoggingWrapper(self.logging_queue, prefix="STDOUT") + sys.stderr = LoggingWrapper(self.logging_queue, prefix="STDERR") + self.logging_thread.start() + + def __exit__(self, *args, **kwargs): + if self.do_capture: + sys.stdout, sys.stderr = self.original_stdio + if self.logging_queue is not None: + self.logger.info("Closing logging queue") + self.logging_queue.put(None) + if self.logging_thread is not None: + self.logging_thread.join(10) + while not self.logging_queue.empty(): + try: + self.logger.warning( + "Dropping log message: %r", self.logging_queue.get() + ) + except Exception: + pass + self.logging_queue.close() + self.logger.info("queue closed") diff --git a/testing/mozbase/mozlog/mozlog/commandline.py b/testing/mozbase/mozlog/mozlog/commandline.py new file mode 100644 index 0000000000..51e9ea6929 --- /dev/null +++ b/testing/mozbase/mozlog/mozlog/commandline.py @@ -0,0 +1,344 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import argparse +import optparse +import os +import sys +from collections import defaultdict + +import six + +from . import formatters, handlers +from .structuredlog import StructuredLogger, set_default_logger + +log_formatters = { + "raw": ( + formatters.JSONFormatter, + "Raw structured log messages " "(provided by mozlog)", + ), + "unittest": ( + formatters.UnittestFormatter, + "Unittest style output " "(provided by mozlog)", + ), + "xunit": ( + formatters.XUnitFormatter, + "xUnit compatible XML " "(provided by mozlog)", + ), + "html": (formatters.HTMLFormatter, "HTML report " "(provided by mozlog)"), + "mach": (formatters.MachFormatter, "Human-readable output " "(provided by mozlog)"), + "tbpl": (formatters.TbplFormatter, "TBPL style log format " "(provided by mozlog)"), + "grouped": ( + formatters.GroupingFormatter, + "Grouped summary of test results " "(provided by mozlog)", + ), + "errorsummary": (formatters.ErrorSummaryFormatter, argparse.SUPPRESS), +} + +TEXT_FORMATTERS = ("raw", "mach") +"""a subset of formatters for non test harnesses related applications""" + + +DOCS_URL = "https://firefox-source-docs.mozilla.org/mozbase/mozlog.html" + + +def level_filter_wrapper(formatter, level): + return handlers.LogLevelFilter(formatter, level) + + +def verbose_wrapper(formatter, verbose): + formatter.verbose = verbose + return formatter + + +def compact_wrapper(formatter, compact): + formatter.compact = compact + return formatter + + +def buffer_handler_wrapper(handler, buffer_limit): + if buffer_limit == "UNLIMITED": + buffer_limit = None + else: + buffer_limit = int(buffer_limit) + return handlers.BufferHandler(handler, buffer_limit) + + +def screenshot_wrapper(formatter, enable_screenshot): + formatter.enable_screenshot = enable_screenshot + return formatter + + +def valgrind_handler_wrapper(handler): + return handlers.ValgrindHandler(handler) + + +def default_formatter_options(log_type, overrides): + formatter_option_defaults = {"raw": {"level": "debug"}} + rv = {"verbose": False, "level": "info"} + rv.update(formatter_option_defaults.get(log_type, {})) + + if overrides is not None: + rv.update(overrides) + + return rv + + +fmt_options = { + #