def test_text_column(): text_column = TextColumn("[b]foo", highlighter=NullHighlighter()) task = Task(1, "test", 100, 20, _get_time=lambda: 1.0) text = text_column.render(task) assert str(text) == "foo" text_column = TextColumn("[b]bar", markup=False) task = Task(1, "test", 100, 20, _get_time=lambda: 1.0) text = text_column.render(task) assert text == Text("[b]bar")
"xpass.textonly": "#F4C041", "xfail": "#ffffff on #695CC8", "xfail.textonly": "#695CC8", "muted": "dim", "info": "yellow italic", "info.border": "yellow", "dryrun": "#ffffff on #162740", "rule.line": "#189F4A", "fixture.name": "bold #1381E0", "fixture.scope.test": "bold #189F4A", "fixture.scope.module": "bold #F4C041", "fixture.scope.global": "bold #EA913C", "usedby": "#9285F6", } ) rich_console = Console(theme=theme, highlighter=NullHighlighter()) def format_test_id(test_result: TestResult) -> str: """ Format module name, line number, and test case number """ return f"{format_test_location(test_result.test)}{format_test_case_number(test_result.test)}" def format_test_location(test: Test) -> str: """ Returns the location of a test as a string of the form '{test.module_name}:{test.line_number}' """ return f"{test.module_name}:{test.line_number}"
def init_logging(level: int, location: pathlib.Path, cli_flags: argparse.Namespace) -> None: root_logger = logging.getLogger() base_logger = logging.getLogger("red") base_logger.setLevel(level) dpy_logger = logging.getLogger("discord") dpy_logger.setLevel(logging.WARNING) warnings_logger = logging.getLogger("py.warnings") warnings_logger.setLevel(logging.WARNING) rich_console = rich.get_console() rich.reconfigure(tab_size=4) rich_console.push_theme( Theme({ "log.time": Style(dim=True), "logging.level.warning": Style(color="yellow"), "logging.level.critical": Style(color="white", bgcolor="red"), "repr.number": Style(color="cyan"), "repr.url": Style(underline=True, italic=True, bold=False, color="cyan"), })) rich_console.file = sys.stdout # This is terrible solution, but it's the best we can do if we want the paths in tracebacks # to be visible. Rich uses `pygments.string` style which is fine, but it also uses # this highlighter which dims most of the path and therefore makes it unreadable on Mac. PathHighlighter.highlights = [] enable_rich_logging = False if isatty(0) and cli_flags.rich_logging is None: # Check if the bot thinks it has a active terminal. enable_rich_logging = True elif cli_flags.rich_logging is True: enable_rich_logging = True file_formatter = logging.Formatter( "[{asctime}] [{levelname}] {name}: {message}", datefmt="%Y-%m-%d %H:%M:%S", style="{") if enable_rich_logging is True: rich_formatter = logging.Formatter("{message}", datefmt="[%X]", style="{") stdout_handler = RedRichHandler( rich_tracebacks=True, show_path=False, highlighter=NullHighlighter(), tracebacks_extra_lines=cli_flags.rich_traceback_extra_lines, tracebacks_show_locals=cli_flags.rich_traceback_show_locals, tracebacks_theme=(PygmentsSyntaxTheme(FixedMonokaiStyle) if rich_console.color_system == "truecolor" else ANSISyntaxTheme(SYNTAX_THEME)), ) stdout_handler.setFormatter(rich_formatter) else: stdout_handler = logging.StreamHandler(sys.stdout) stdout_handler.setFormatter(file_formatter) root_logger.addHandler(stdout_handler) logging.captureWarnings(True) if not location.exists(): location.mkdir(parents=True, exist_ok=True) # Rotate latest logs to previous logs previous_logs: List[pathlib.Path] = [] latest_logs: List[Tuple[pathlib.Path, str]] = [] for path in location.iterdir(): match = re.match(r"latest(?P<part>-part\d+)?\.log", path.name) if match: part = match.groupdict(default="")["part"] latest_logs.append((path, part)) match = re.match(r"previous(?:-part\d+)?.log", path.name) if match: previous_logs.append(path) # Delete all previous.log files for path in previous_logs: path.unlink() # Rename latest.log files to previous.log for path, part in latest_logs: path.replace(location / f"previous{part}.log") latest_fhandler = RotatingFileHandler( stem="latest", directory=location, maxBytes=1_000_000, # About 1MB per logfile backupCount=MAX_OLD_LOGS, encoding="utf-8", ) all_fhandler = RotatingFileHandler( stem="red", directory=location, maxBytes=1_000_000, backupCount=MAX_OLD_LOGS, encoding="utf-8", ) for fhandler in (latest_fhandler, all_fhandler): fhandler.setFormatter(file_formatter) root_logger.addHandler(fhandler)
def test_wrong_type(): highlighter = NullHighlighter() with pytest.raises(TypeError): highlighter([])
def main() -> None: if os.environ.get('APPIMAGE', None): # if running as appimage, remove empty arguments if len(sys.argv) == 2 and sys.argv[-1] == '': sys.argv = sys.argv[:-1] parser = ModuleParser( description='SSH-MITM Tools', version=f"SSH-MITM {ssh_mitm_version}", modules_from_file=True, allow_abbrev=False ) parser.add_argument( '-d', '--debug', dest='debug', default=False, action='store_true', help='More verbose output of status information' ) parser.add_argument( '--paramiko-log-level', dest='paramiko_log_level', default='warning', choices=['warning', 'info', 'debug'], help='set paramikos log level' ) parser.add_argument( '--disable-workarounds', dest='disable_workarounds', action='store_true', help='disable paramiko workarounds' ) subparsers = parser.add_subparsers(title='Available commands', dest="subparser_name", metavar='subcommand') subparsers.required = True parser_mitm_server: ModuleParser = cast( ModuleParser, subparsers.add_parser( 'server', allow_abbrev=False, help='start the ssh-mitm server' ) ) init_server_parser(parser_mitm_server) parser_audit: ModuleParser = cast( ModuleParser, subparsers.add_parser( 'audit', allow_abbrev=False, help='audit tools for ssh servers' ) ) init_audit_parser(parser_audit) args = parser.parse_args() root_logger = logging.getLogger() root_logger.setLevel(logging.DEBUG if args.debug else logging.INFO) root_logger.handlers.clear() root_logger.addHandler(RichHandler( highlighter=NullHighlighter(), markup=False, rich_tracebacks=True, enable_link_path=args.debug, show_path=args.debug )) if not args.disable_workarounds: Transport.run = dropbear.transport_run # type: ignore if args.paramiko_log_level == 'debug': logging.getLogger("paramiko").setLevel(logging.DEBUG) elif args.paramiko_log_level == 'info': logging.getLogger("paramiko").setLevel(logging.INFO) else: logging.getLogger("paramiko").setLevel(logging.WARNING) if args.subparser_name == 'server': run_server(args=args) elif args.subparser_name == 'audit': run_audit(args=args)