aboutsummaryrefslogtreecommitdiffstats
path: root/.github/scripts/tests/log_parser.py
blob: 2a7f744f93da5d0c0371b1b54bf3230a3df62414 (plain) (blame)
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
95
96
97
98
99
100
101
102
103
104
105
106
import gzip
import re
from typing import TextIO


def log_reader(fn, decompress, errors="backslashreplace"):
    if decompress:
        return gzip.open(fn, "rt", errors=errors)

    return open(fn, "rt", errors=errors)


GTEST_MARK = "[==========]"
YUNIT_MARK = "<-----"


def parse_gtest_fails(log):
    ilog = iter(log)
    while 1:
        try:
            line = next(ilog)
        except StopIteration:
            break

        if line.startswith("[ RUN      ]"):
            buf = []
            while 1:
                try:
                    line = next(ilog)
                except StopIteration:
                    break

                if line.startswith("[  FAILED  ]"):
                    plen = len("[  FAILED  ] ")
                    classname, method = line[plen:].split(" ")[0].split(".", maxsplit=1)
                    yield classname, method, buf
                    break
                elif line.startswith("[       OK ]"):
                    break
                else:
                    buf.append(line)


def parse_yunit_fails(log):
    i = 0
    class_method = found_fail = found_exec = buf_start = None
    while i < len(log):
        line = log[i]

        if found_fail:
            if line.startswith(("[exec] ", "-----> ")):
                cls, method = class_method.split("::")
                yield cls, method, log[buf_start:i]
                class_method = found_fail = found_exec = buf_start = None
        elif found_exec:
            if line.startswith("[FAIL] "):
                found_fail = True
            elif line.startswith("[good] "):
                found_exec = class_method = buf_start = None

        if not found_exec and line.startswith("[exec] "):
            class_method = line[7:].rstrip("...")
            found_exec = True
            buf_start = i
        i += 1

    if buf_start is not None:
        cls, method = class_method.split("::")
        yield cls, method, log[buf_start:]


def ctest_log_parser(fp: TextIO):
    start_re = re.compile(r"^\s+Start\s+\d+: ")
    status_re = re.compile(r"^\s*\d+/\d+ Test\s+#\d+: ([^ ]+) [.]+(\D+)")
    finish_re = re.compile(r"\d+% tests passed")

    buf = []
    target = reason = None

    while 1:
        line = fp.readline()
        if not line:
            break

        if target:
            if not (start_re.match(line) or status_re.match(line) or finish_re.match(line)):
                buf.append(line.rstrip())
            else:
                yield target, reason, buf
                target = reason = None
                buf = []

        if target is None:
            if "***" not in line:
                continue

            m = status_re.match(line)

            if not m:
                continue

            target = m.group(1)
            reason = m.group(2).replace("*", "").strip()

    if buf:
        yield target, reason, buf