1bf215546Sopenharmony_ci#!/usr/bin/env python3 2bf215546Sopenharmony_ci# 3bf215546Sopenharmony_ci# Copyright © 2020 Igalia, S.L. 4bf215546Sopenharmony_ci# 5bf215546Sopenharmony_ci# Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci# copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci# to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci# the rights to use, copy, modify, merge, publish, distribute, sublicense, 9bf215546Sopenharmony_ci# and/or sell copies of the Software, and to permit persons to whom the 10bf215546Sopenharmony_ci# Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci# 12bf215546Sopenharmony_ci# The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci# paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci# Software. 15bf215546Sopenharmony_ci# 16bf215546Sopenharmony_ci# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21bf215546Sopenharmony_ci# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22bf215546Sopenharmony_ci# IN THE SOFTWARE. 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ciimport argparse 25bf215546Sopenharmony_ciimport os 26bf215546Sopenharmony_ciimport re 27bf215546Sopenharmony_cifrom serial_buffer import SerialBuffer 28bf215546Sopenharmony_ciimport sys 29bf215546Sopenharmony_ciimport threading 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ciclass PoERun: 33bf215546Sopenharmony_ci def __init__(self, args, test_timeout): 34bf215546Sopenharmony_ci self.powerup = args.powerup 35bf215546Sopenharmony_ci self.powerdown = args.powerdown 36bf215546Sopenharmony_ci self.ser = SerialBuffer( 37bf215546Sopenharmony_ci args.dev, "results/serial-output.txt", "") 38bf215546Sopenharmony_ci self.test_timeout = test_timeout 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci def print_error(self, message): 41bf215546Sopenharmony_ci RED = '\033[0;31m' 42bf215546Sopenharmony_ci NO_COLOR = '\033[0m' 43bf215546Sopenharmony_ci print(RED + message + NO_COLOR) 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci def logged_system(self, cmd): 46bf215546Sopenharmony_ci print("Running '{}'".format(cmd)) 47bf215546Sopenharmony_ci return os.system(cmd) 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci def run(self): 50bf215546Sopenharmony_ci if self.logged_system(self.powerup) != 0: 51bf215546Sopenharmony_ci return 1 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci boot_detected = False 54bf215546Sopenharmony_ci for line in self.ser.lines(timeout=5 * 60, phase="bootloader"): 55bf215546Sopenharmony_ci if re.search("Booting Linux", line): 56bf215546Sopenharmony_ci boot_detected = True 57bf215546Sopenharmony_ci break 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci if not boot_detected: 60bf215546Sopenharmony_ci self.print_error( 61bf215546Sopenharmony_ci "Something wrong; couldn't detect the boot start up sequence") 62bf215546Sopenharmony_ci return 2 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci for line in self.ser.lines(timeout=self.test_timeout, phase="test"): 65bf215546Sopenharmony_ci if re.search("---. end Kernel panic", line): 66bf215546Sopenharmony_ci return 1 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci # Binning memory problems 69bf215546Sopenharmony_ci if re.search("binner overflow mem", line): 70bf215546Sopenharmony_ci self.print_error("Memory overflow in the binner; GPU hang") 71bf215546Sopenharmony_ci return 1 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci if re.search("nouveau 57000000.gpu: bus: MMIO read of 00000000 FAULT at 137000", line): 74bf215546Sopenharmony_ci self.print_error("nouveau jetson boot bug, retrying.") 75bf215546Sopenharmony_ci return 2 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci result = re.search("hwci: mesa: (\S*)", line) 78bf215546Sopenharmony_ci if result: 79bf215546Sopenharmony_ci if result.group(1) == "pass": 80bf215546Sopenharmony_ci return 0 81bf215546Sopenharmony_ci else: 82bf215546Sopenharmony_ci return 1 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci self.print_error( 85bf215546Sopenharmony_ci "Reached the end of the CPU serial log without finding a result") 86bf215546Sopenharmony_ci return 2 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_cidef main(): 90bf215546Sopenharmony_ci parser = argparse.ArgumentParser() 91bf215546Sopenharmony_ci parser.add_argument('--dev', type=str, 92bf215546Sopenharmony_ci help='Serial device to monitor', required=True) 93bf215546Sopenharmony_ci parser.add_argument('--powerup', type=str, 94bf215546Sopenharmony_ci help='shell command for rebooting', required=True) 95bf215546Sopenharmony_ci parser.add_argument('--powerdown', type=str, 96bf215546Sopenharmony_ci help='shell command for powering off', required=True) 97bf215546Sopenharmony_ci parser.add_argument( 98bf215546Sopenharmony_ci '--test-timeout', type=int, help='Test phase timeout (minutes)', required=True) 99bf215546Sopenharmony_ci args = parser.parse_args() 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci poe = PoERun(args, args.test_timeout * 60) 102bf215546Sopenharmony_ci retval = poe.run() 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci poe.logged_system(args.powerdown) 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci sys.exit(retval) 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ciif __name__ == '__main__': 110bf215546Sopenharmony_ci main() 111