1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
# SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net>
# SPDX-License-Identifier: BSD-2-Clause
"""Helper functions for the `remrun` testing tools."""
from __future__ import annotations
import contextlib
import functools
import logging
import os
import subprocess # noqa: S404
import sys
import typing
try:
import utf8_locale
_HAVE_UTF8_LOCALE = True
except ImportError:
_HAVE_UTF8_LOCALE = False
if typing.TYPE_CHECKING:
from typing import Final
@functools.lru_cache
def build_logger(
*,
name: str = "run_sshd_test",
quiet: bool = False,
verbose: bool = False,
) -> logging.Logger:
"""Build a logger that outputs to the standard output and error streams.
Messages of level `WARNING` and higher go to the standard error stream.
If `quiet` is false, messages of level `INFO` also go to the standard error stream.
If `verbose` is true, messages of level `DEBUG` also go to the standard error stream.
"""
logger: Final = logging.getLogger(name)
logger.setLevel(logging.DEBUG if verbose else logging.WARNING if quiet else logging.INFO)
logger.propagate = False
diag_handler: Final = logging.StreamHandler(sys.stderr)
diag_handler.setLevel(logging.DEBUG if verbose else logging.WARNING)
if not quiet:
diag_handler.addFilter(lambda rec: rec.levelno != logging.INFO)
logger.addHandler(diag_handler)
if not quiet:
info_handler: Final = logging.StreamHandler(sys.stderr)
info_handler.setLevel(logging.INFO)
info_handler.addFilter(lambda rec: rec.levelno == logging.INFO)
logger.addHandler(info_handler)
return logger
@functools.lru_cache
def get_utf8_env() -> dict[str, str]:
"""Prepare a UTF-8-capable environment to run child processes in."""
if _HAVE_UTF8_LOCALE:
return utf8_locale.get_utf8_env()
env: Final = dict(os.environ)
with contextlib.suppress(KeyError):
env.pop("LANGUAGE")
try:
lines = subprocess.check_output( # noqa: S603
["u8loc", "-q", "LC_ALL"], # noqa: S607
encoding="ISO-8859-1",
).splitlines()
except (OSError, subprocess.CalledProcessError):
pass
else:
if len(lines) == 1:
env["LC_ALL"] = lines[0]
return env
try:
lines = subprocess.check_output( # noqa: S603
["locale", "-a"], # noqa: S607
encoding="ISO-8859-1",
).splitlines()
except (OSError, subprocess.CalledProcessError):
sys.exit("Could not run `u8loc` or `locale` and no `utf8-locale` installed")
for name in ("C.UTF-8", "C.utf8"):
if name in lines:
env["LC_ALL"] = name
return env
sys.exit("No C.UTF-8 or C.utf8 locale and no `utf8-locale` installed")
|