• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import re
2from dataclasses import dataclass
3from datetime import timedelta
4from enum import Enum, auto
5from typing import Optional, Pattern, Union
6
7from lava.utils.gitlab_section import GitlabSection
8
9
10class LogSectionType(Enum):
11    UNKNOWN = auto()
12    LAVA_BOOT = auto()
13    TEST_SUITE = auto()
14    TEST_CASE = auto()
15    LAVA_POST_PROCESSING = auto()
16
17
18FALLBACK_GITLAB_SECTION_TIMEOUT = timedelta(minutes=10)
19DEFAULT_GITLAB_SECTION_TIMEOUTS = {
20    # Empirically, successful device boot in LAVA time takes less than 3
21    # minutes.
22    # LAVA itself is configured to attempt thrice to boot the device,
23    # summing up to 9 minutes.
24    # It is better to retry the boot than cancel the job and re-submit to avoid
25    # the enqueue delay.
26    LogSectionType.LAVA_BOOT: timedelta(minutes=9),
27    # Test suite phase is where the initialization happens.
28    LogSectionType.TEST_SUITE: timedelta(minutes=5),
29    # Test cases may take a long time, this script has no right to interrupt
30    # them. But if the test case takes almost 1h, it will never succeed due to
31    # Gitlab job timeout.
32    LogSectionType.TEST_CASE: timedelta(minutes=60),
33    # LAVA post processing may refer to a test suite teardown, or the
34    # adjustments to start the next test_case
35    LogSectionType.LAVA_POST_PROCESSING: timedelta(minutes=5),
36}
37
38
39@dataclass(frozen=True)
40class LogSection:
41    regex: Union[Pattern, str]
42    levels: tuple[str]
43    section_id: str
44    section_header: str
45    section_type: LogSectionType
46    collapsed: bool = False
47
48    def from_log_line_to_section(
49        self, lava_log_line: dict[str, str]
50    ) -> Optional[GitlabSection]:
51        if lava_log_line["lvl"] not in self.levels:
52            return
53
54        if match := re.search(self.regex, lava_log_line["msg"]):
55            section_id = self.section_id.format(*match.groups())
56            section_header = self.section_header.format(*match.groups())
57            return GitlabSection(
58                id=section_id,
59                header=section_header,
60                type=self.section_type,
61                start_collapsed=self.collapsed,
62            )
63
64
65LOG_SECTIONS = (
66    LogSection(
67        regex=re.compile(r"<?STARTTC>? ([^>]*)"),
68        levels=("target", "debug"),
69        section_id="{}",
70        section_header="test_case {}",
71        section_type=LogSectionType.TEST_CASE,
72    ),
73    LogSection(
74        regex=re.compile(r"<?STARTRUN>? ([^>]*)"),
75        levels=("target", "debug"),
76        section_id="{}",
77        section_header="test_suite {}",
78        section_type=LogSectionType.TEST_SUITE,
79    ),
80    LogSection(
81        regex=re.compile(r"ENDTC>? ([^>]+)"),
82        levels=("target", "debug"),
83        section_id="post-{}",
84        section_header="Post test_case {}",
85        collapsed=True,
86        section_type=LogSectionType.LAVA_POST_PROCESSING,
87    ),
88)
89