• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#
3# Copyright © 2020 Google LLC
4#
5# Permission is hereby granted, free of charge, to any person obtaining a
6# copy of this software and associated documentation files (the "Software"),
7# to deal in the Software without restriction, including without limitation
8# the rights to use, copy, modify, merge, publish, distribute, sublicense,
9# and/or sell copies of the Software, and to permit persons to whom the
10# Software is furnished to do so, subject to the following conditions:
11#
12# The above copyright notice and this permission notice (including the next
13# paragraph) shall be included in all copies or substantial portions of the
14# Software.
15#
16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22# IN THE SOFTWARE.
23
24import argparse
25import os
26import re
27from serial_buffer import SerialBuffer
28import sys
29import threading
30
31class FastbootRun:
32    def __init__(self, args):
33        self.powerup = args.powerup
34        # We would like something like a 1 minute timeout, but the piglit traces
35        # jobs stall out for long periods of time.
36        self.ser = SerialBuffer(args.dev, "results/serial-output.txt", "R SERIAL> ", timeout=600)
37        self.fastboot="fastboot boot -s {ser} artifacts/fastboot.img".format(ser=args.fbserial)
38
39    def print_error(self, message):
40        RED = '\033[0;31m'
41        NO_COLOR = '\033[0m'
42        print(RED + message + NO_COLOR)
43
44    def logged_system(self, cmd):
45        print("Running '{}'".format(cmd))
46        return os.system(cmd)
47
48    def run(self):
49        if self.logged_system(self.powerup) != 0:
50            return 1
51
52        fastboot_ready = False
53        for line in self.ser.lines():
54            if re.search("fastboot: processing commands", line) or \
55                re.search("Listening for fastboot command on", line):
56                fastboot_ready = True
57                break
58
59            if re.search("data abort", line):
60                self.print_error("Detected crash during boot, restarting run...")
61                return 2
62
63        if not fastboot_ready:
64            self.print_error("Failed to get to fastboot prompt, restarting run...")
65            return 2
66
67        if self.logged_system(self.fastboot) != 0:
68            return 1
69
70        for line in self.ser.lines():
71            if re.search("---. end Kernel panic", line):
72                return 1
73
74            # The db820c boards intermittently reboot.  Just restart the run
75            # when if we see a reboot after we got past fastboot.
76            if re.search("PON REASON", line):
77                self.print_error("Detected spontaneous reboot, restarting run...")
78                return 2
79
80            # db820c sometimes wedges around iommu fault recovery
81            if re.search("watchdog: BUG: soft lockup - CPU.* stuck", line):
82                self.print_error(
83                    "Detected kernel soft lockup, restarting run...")
84                return 2
85
86            # If the network device dies, it's probably not graphics's fault, just try again.
87            if re.search("NETDEV WATCHDOG", line):
88                self.print_error(
89                    "Detected network device failure, restarting run...")
90                return 2
91
92            result = re.search("hwci: mesa: (\S*)", line)
93            if result:
94                if result.group(1) == "pass":
95                    return 0
96                else:
97                    return 1
98
99        self.print_error("Reached the end of the CPU serial log without finding a result, restarting run...")
100        return 2
101
102def main():
103    parser = argparse.ArgumentParser()
104    parser.add_argument('--dev', type=str, help='Serial device (otherwise reading from serial-output.txt)')
105    parser.add_argument('--powerup', type=str, help='shell command for rebooting', required=True)
106    parser.add_argument('--powerdown', type=str, help='shell command for powering off', required=True)
107    parser.add_argument('--fbserial', type=str, help='fastboot serial number of the board', required=True)
108    args = parser.parse_args()
109
110    fastboot = FastbootRun(args)
111
112    while True:
113        retval = fastboot.run()
114        if retval != 2:
115            break
116
117        fastboot = FastbootRun(args)
118
119    fastboot.logged_system(args.powerdown)
120
121    sys.exit(retval)
122
123if __name__ == '__main__':
124    main()
125