• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import re
2from dataclasses import dataclass
3from datetime import timedelta
4from enum import Enum, auto
5from os import getenv
6from typing import Optional, Pattern, Union
7
8from lava.utils.gitlab_section import GitlabSection
9
10
11class LogSectionType(Enum):
12    UNKNOWN = auto()
13    LAVA_BOOT = auto()
14    TEST_DUT_SUITE = auto()
15    TEST_SUITE = auto()
16    TEST_CASE = auto()
17    LAVA_POST_PROCESSING = auto()
18
19
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.
26LAVA_BOOT_TIMEOUT = int(getenv("LAVA_BOOT_TIMEOUT", 9))
27
28# Test DUT suite phase is where the initialization happens in DUT, not on docker.
29# The device will be listening to SSH session until the end of the job.
30LAVA_TEST_DUT_SUITE_TIMEOUT = int(getenv("JOB_TIMEOUT", 60))
31
32# Test suite phase is where the initialization happens on docker.
33LAVA_TEST_SUITE_TIMEOUT = int(getenv("LAVA_TEST_SUITE_TIMEOUT", 5))
34
35# Test cases may take a long time, this script has no right to interrupt
36# them. But if the test case takes almost 1h, it will never succeed due to
37# Gitlab job timeout.
38LAVA_TEST_CASE_TIMEOUT = int(getenv("JOB_TIMEOUT", 60))
39
40# LAVA post processing may refer to a test suite teardown, or the
41# adjustments to start the next test_case
42LAVA_POST_PROCESSING_TIMEOUT = int(getenv("LAVA_POST_PROCESSING_TIMEOUT", 5))
43
44FALLBACK_GITLAB_SECTION_TIMEOUT = timedelta(minutes=10)
45DEFAULT_GITLAB_SECTION_TIMEOUTS = {
46    LogSectionType.LAVA_BOOT: timedelta(minutes=LAVA_BOOT_TIMEOUT),
47    LogSectionType.TEST_DUT_SUITE: timedelta(minutes=LAVA_TEST_DUT_SUITE_TIMEOUT),
48    LogSectionType.TEST_SUITE: timedelta(minutes=LAVA_TEST_SUITE_TIMEOUT),
49    LogSectionType.TEST_CASE: timedelta(minutes=LAVA_TEST_CASE_TIMEOUT),
50    LogSectionType.LAVA_POST_PROCESSING: timedelta(
51        minutes=LAVA_POST_PROCESSING_TIMEOUT
52    ),
53}
54
55
56@dataclass(frozen=True)
57class LogSection:
58    regex: Union[Pattern, str]
59    levels: tuple[str]
60    section_id: str
61    section_header: str
62    section_type: LogSectionType
63    collapsed: bool = False
64
65    def from_log_line_to_section(
66        self, lava_log_line: dict[str, str]
67    ) -> Optional[GitlabSection]:
68        if lava_log_line["lvl"] not in self.levels:
69            return
70
71        if match := re.search(self.regex, lava_log_line["msg"]):
72            section_id = self.section_id.format(*match.groups())
73            section_header = self.section_header.format(*match.groups())
74            timeout = DEFAULT_GITLAB_SECTION_TIMEOUTS[self.section_type]
75            return GitlabSection(
76                id=section_id,
77                header=f"{section_header} - Timeout: {timeout}",
78                type=self.section_type,
79                start_collapsed=self.collapsed,
80            )
81
82
83LOG_SECTIONS = (
84    LogSection(
85        regex=re.compile(r"<?STARTTC>? ([^>]*)"),
86        levels=("target", "debug"),
87        section_id="{}",
88        section_header="test_case {}",
89        section_type=LogSectionType.TEST_CASE,
90    ),
91    LogSection(
92        regex=re.compile(r"<?STARTRUN>? ([^>]*ssh.*server.*)"),
93        levels=("debug"),
94        section_id="{}",
95        section_header="[dut] test_suite {}",
96        section_type=LogSectionType.TEST_DUT_SUITE,
97    ),
98    LogSection(
99        regex=re.compile(r"<?STARTRUN>? ([^>]*)"),
100        levels=("debug"),
101        section_id="{}",
102        section_header="[docker] test_suite {}",
103        section_type=LogSectionType.TEST_SUITE,
104    ),
105    LogSection(
106        regex=re.compile(r"ENDTC>? ([^>]+)"),
107        levels=("target", "debug"),
108        section_id="post-{}",
109        section_header="Post test_case {}",
110        collapsed=True,
111        section_type=LogSectionType.LAVA_POST_PROCESSING,
112    ),
113)
114