diff --git a/ise/ise_logparser/pyproject.toml b/ise/ise_logparser/pyproject.toml index 07b89b6..3c2a0da 100644 --- a/ise/ise_logparser/pyproject.toml +++ b/ise/ise_logparser/pyproject.toml @@ -13,6 +13,7 @@ dependencies = [ "setuptools>=72.1.0", "colorama>=0.4.6", "types-colorama>=0.4.15.20240311", + "flameprof>=0.4", ] readme = "README.md" requires-python = ">= 3.8" diff --git a/ise/ise_logparser/requirements-dev.lock b/ise/ise_logparser/requirements-dev.lock index bd2a046..c703ee8 100644 --- a/ise/ise_logparser/requirements-dev.lock +++ b/ise/ise_logparser/requirements-dev.lock @@ -17,6 +17,8 @@ colorama==0.4.6 # via ise-logparser executing==2.0.1 # via icecream +flameprof==0.4 + # via ise-logparser icecream==2.1.3 # via ise-logparser mypy==1.11.1 diff --git a/ise/ise_logparser/requirements.lock b/ise/ise_logparser/requirements.lock index bd2a046..c703ee8 100644 --- a/ise/ise_logparser/requirements.lock +++ b/ise/ise_logparser/requirements.lock @@ -17,6 +17,8 @@ colorama==0.4.6 # via ise-logparser executing==2.0.1 # via icecream +flameprof==0.4 + # via ise-logparser icecream==2.1.3 # via ise-logparser mypy==1.11.1 diff --git a/ise/ise_logparser/src/main.py b/ise/ise_logparser/src/main.py index 5516d3f..5c494a8 100755 --- a/ise/ise_logparser/src/main.py +++ b/ise/ise_logparser/src/main.py @@ -1,17 +1,23 @@ #!/usr/bin/env python3 from __future__ import annotations - +import cProfile import argparse import logging import os +import profile import re from pathlib import Path from typing import cast +import time +from icecream import ic +import pstats import parsy as ps from colorama import Back, Fore, Style from parsy import Parser, generate, peek, regex, seq, string +ic.configureOutput(includeContext=True) + LEVEL_UNKNOWN = 255 NEWLINE = string("\n") SPACE = string(" ") @@ -141,6 +147,7 @@ class TestPrinterBuilder: print(res) return res + return "" def with_loglevel(self, loglevel: int) -> TestPrinterBuilder: self.loglevel = loglevel @@ -186,37 +193,36 @@ def test_output_line(): src = yield (string("[") >> regex(r"[A-Za-z_0-9]+") << string("] ")).optional() msg = yield message.map(lambda x: x.rstrip()) - return print_test_line(ts, get_debug_level_const(level), src, msg) + print_test_line(ts, get_debug_level_const(level), src, msg) + return ps.success('') # return {"ts": ts, "level": level, "src": src, "msg": msg} @generate def test_details(): - test_name = yield ( - ( - NEWLINE.optional() - << (SPACE * 4) - << (string("|--") | string("`--")) - << ps.whitespace - ) - >> ps.any_char.until(ps.whitespace).concat() + indent = yield ( + NEWLINE.optional() + << string("|").optional() + >> (SPACE.at_least(1)) + << (ps.char_from("|`") + string("--")) << ps.whitespace ) - test_results = yield (ps.letter.many().concat()) - print(f" | {colorize_status(test_results)}\t{test_name}") + test_name = yield (ps.any_char.until(ps.whitespace).concat() << ps.whitespace) + test_results = yield (ps.letter.many().concat() << NEWLINE) + print(f" {' ' * (len(indent)//2)} {colorize_status(test_results)}\t{test_name}") return {"test_results": test_results, "test_name": test_name} @generate def subtask_details(): subtask_name = ( - yield (string("`--") << ps.whitespace) + yield (string("|--") | string("`--")) + ps.whitespace >> ps.any_char.until(ps.whitespace).concat() << ps.whitespace ) - subtask_result = yield (ps.letter.many().concat()) - print(f" > {colorize_status(subtask_result)}\t{subtask_name}") + subtask_result = yield (ps.letter.many().concat() << NEWLINE) + print(f"  {colorize_status(subtask_result)}\t{subtask_name}") tests = yield test_details.many() return { "subtask_result": subtask_result, @@ -230,7 +236,7 @@ def task_details(): task_number = ( yield ps.any_char.until(string(":")).concat() << string(":") << ps.whitespace ) - task_name = yield (ps.any_char.until(ps.whitespace).concat() << ps.whitespace) + task_name = yield ps.any_char.until(ps.whitespace).concat() << ps.whitespace print(f"{task_number}\t {Style.BRIGHT + task_name + Style.RESET_ALL}") subtasks = yield (subtask_details.many()) @@ -247,15 +253,23 @@ def sections(): << NEWLINE ) + ic(elapsed()) test_output = yield test_output_line.until(end_block) << end_block << NEWLINE + ic(elapsed()) + # exit(1) post_test = yield (ps.any_char.until(report_block).concat() << report_block) + ic(elapsed()) # print(post_test) report = yield (ps.any_char.until(summary_block).concat() << summary_block) + ic(elapsed()) # print(report) summary = yield (ps.any_char.until(details_block).concat() << details_block) + ic(elapsed()) # print(summary) details = yield task_details.many() + ic(elapsed()) etc = yield (ps.any_char.until(ps.eof).concat()) + ic(elapsed()) return { "header": header, "test_output": test_output, @@ -267,17 +281,39 @@ def sections(): } +def elapsed(): + global current + global prev + current = time.time() + elapsed = current - prev + prev = current + return elapsed + + # TODO: make this work with streams -if __name__ == "__main__": +def main(): + global current + global prev + current = time.time() + prev = time.time() config = Config() with Path(config["LOGFILE"]).open() as f: log = f.read() - global output_test_line + global print_test_line print_test_line = TestPrinterBuilder() - if loglevel := config.get("LOGLEVEL"): + if loglevel := config["LOGLEVEL"]: print_test_line = print_test_line.with_loglevel(cast(int, loglevel)) if query := config.get("QUERY"): print_test_line = print_test_line.with_query(query) - from icecream import ic - parsed_sections = sections.parse(log) + sections.parse(log) +if __name__ == "__main__": + # import io + # pr = cProfile.Profile() + # pr.enable() + main() + # pr.disable() + # s = io.StringIO() + # ps = pstats.Stats(pr) + # ps.dump_stats("test.stats") + # print(s.getvalue())