1#!/usr/bin/env python3 2# 3# Copyright © 2020 Igalia, S.L. 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 31 32class PoERun: 33 def __init__(self, args, test_timeout): 34 self.powerup = args.powerup 35 self.powerdown = args.powerdown 36 self.ser = SerialBuffer( 37 args.dev, "results/serial-output.txt", "") 38 self.test_timeout = test_timeout 39 40 def print_error(self, message): 41 RED = '\033[0;31m' 42 NO_COLOR = '\033[0m' 43 print(RED + message + NO_COLOR) 44 45 def logged_system(self, cmd): 46 print("Running '{}'".format(cmd)) 47 return os.system(cmd) 48 49 def run(self): 50 if self.logged_system(self.powerup) != 0: 51 return 1 52 53 boot_detected = False 54 for line in self.ser.lines(timeout=5 * 60, phase="bootloader"): 55 if re.search("Booting Linux", line): 56 boot_detected = True 57 break 58 59 if not boot_detected: 60 self.print_error( 61 "Something wrong; couldn't detect the boot start up sequence") 62 return 2 63 64 for line in self.ser.lines(timeout=self.test_timeout, phase="test"): 65 if re.search("---. end Kernel panic", line): 66 return 1 67 68 # Binning memory problems 69 if re.search("binner overflow mem", line): 70 self.print_error("Memory overflow in the binner; GPU hang") 71 return 1 72 73 if re.search("nouveau 57000000.gpu: bus: MMIO read of 00000000 FAULT at 137000", line): 74 self.print_error("nouveau jetson boot bug, retrying.") 75 return 2 76 77 result = re.search("hwci: mesa: (\S*)", line) 78 if result: 79 if result.group(1) == "pass": 80 return 0 81 else: 82 return 1 83 84 self.print_error( 85 "Reached the end of the CPU serial log without finding a result") 86 return 2 87 88 89def main(): 90 parser = argparse.ArgumentParser() 91 parser.add_argument('--dev', type=str, 92 help='Serial device to monitor', required=True) 93 parser.add_argument('--powerup', type=str, 94 help='shell command for rebooting', required=True) 95 parser.add_argument('--powerdown', type=str, 96 help='shell command for powering off', required=True) 97 parser.add_argument( 98 '--test-timeout', type=int, help='Test phase timeout (minutes)', required=True) 99 args = parser.parse_args() 100 101 poe = PoERun(args, args.test_timeout * 60) 102 retval = poe.run() 103 104 poe.logged_system(args.powerdown) 105 106 sys.exit(retval) 107 108 109if __name__ == '__main__': 110 main() 111