log_parser.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import gzip
  2. import re
  3. from typing import TextIO
  4. def log_reader(fn, decompress, errors="backslashreplace"):
  5. if decompress:
  6. return gzip.open(fn, "rt", errors=errors)
  7. return open(fn, "rt", errors=errors)
  8. GTEST_MARK = "[==========]"
  9. YUNIT_MARK = "<-----"
  10. def parse_gtest_fails(log):
  11. ilog = iter(log)
  12. while 1:
  13. try:
  14. line = next(ilog)
  15. except StopIteration:
  16. break
  17. if line.startswith("[ RUN ]"):
  18. buf = []
  19. while 1:
  20. try:
  21. line = next(ilog)
  22. except StopIteration:
  23. break
  24. if line.startswith("[ FAILED ]"):
  25. plen = len("[ FAILED ] ")
  26. classname, method = line[plen:].split(" ")[0].split(".", maxsplit=1)
  27. yield classname, method, buf
  28. break
  29. elif line.startswith("[ OK ]"):
  30. break
  31. else:
  32. buf.append(line)
  33. def parse_yunit_fails(log):
  34. i = 0
  35. class_method = found_fail = found_exec = buf_start = None
  36. while i < len(log):
  37. line = log[i]
  38. if found_fail:
  39. if line.startswith(("[exec] ", "-----> ")):
  40. cls, method = class_method.split("::")
  41. yield cls, method, log[buf_start:i]
  42. class_method = found_fail = found_exec = buf_start = None
  43. elif found_exec:
  44. if line.startswith("[FAIL] "):
  45. found_fail = True
  46. elif line.startswith("[good] "):
  47. found_exec = class_method = buf_start = None
  48. if not found_exec and line.startswith("[exec] "):
  49. class_method = line[7:].rstrip("...")
  50. found_exec = True
  51. buf_start = i
  52. i += 1
  53. if buf_start is not None:
  54. cls, method = class_method.split("::")
  55. yield cls, method, log[buf_start:]
  56. def ctest_log_parser(fp: TextIO):
  57. start_re = re.compile(r"^\s+Start\s+\d+: ")
  58. status_re = re.compile(r"^\s*\d+/\d+ Test\s+#\d+: ([^ ]+) [.]+(\D+)")
  59. finish_re = re.compile(r"\d+% tests passed")
  60. buf = []
  61. target = reason = None
  62. while 1:
  63. line = fp.readline()
  64. if not line:
  65. break
  66. if target:
  67. if not (start_re.match(line) or status_re.match(line) or finish_re.match(line)):
  68. buf.append(line.rstrip())
  69. else:
  70. yield target, reason, buf
  71. target = reason = None
  72. buf = []
  73. if target is None:
  74. if "***" not in line:
  75. continue
  76. m = status_re.match(line)
  77. if not m:
  78. continue
  79. target = m.group(1)
  80. reason = m.group(2).replace("*", "").strip()
  81. if buf:
  82. yield target, reason, buf