1#!/usr/bin/python2 2"""Script adapter used by automation client for testing dejagnu. 3 4 This is not intended to be run on command line. 5 To kick off a single dejagnu run, use ./dejagnu/run_dejagnu.py 6""" 7 8from __future__ import print_function 9 10import argparse 11import sys 12import setup_chromeos 13 14from dejagnu import gdb_dejagnu 15from cros_utils import command_executer 16from cros_utils import email_sender 17 18 19class DejagnuAdapter(object): 20 """Dejagnu Adapter class.""" 21 22 def __init__(self, board, remote, gdb_dir, chromeos_root, cleanup): 23 self._board = board 24 self._remote = remote 25 self._gdb_dir = gdb_dir 26 self._chromeos_root = chromeos_root 27 self._cleanup = cleanup 28 self._cmd_exec = command_executer.GetCommandExecuter() 29 30 def SetupChromeOS(self): 31 cmd = [setup_chromeos.__file__, '--dir=' + self._chromeos_root, 32 '--minilayout', '--jobs=8'] 33 ret = setup_chromeos.Main(cmd) 34 if ret: 35 raise RuntimeError('Failed to checkout chromeos') 36 ## Do cros_sdk and setup_board, otherwise build_tc in next step will fail. 37 cmd = 'cd {0} && cros_sdk --download'.format(self._chromeos_root) 38 ret = self._cmd_exec.RunCommand(cmd, terminated_timeout=9000) 39 if ret: 40 raise RuntimeError('Failed to create chroot.') 41 42 def SetupBoard(self): 43 cmd = './setup_board --board=' + self._board 44 ret = self._cmd_exec.ChrootRunCommand(self._chromeos_root, 45 cmd, 46 terminated_timeout=4000) 47 if ret: 48 raise RuntimeError('Failed to setup board.') 49 50 def CheckGDB(self): 51 args = [gdb_dejagnu.__file__, '--board=' + self._board, 52 '--chromeos_root=' + self._chromeos_root, 53 '--mount=' + self._gdb_dir, '--remote=' + self._remote] 54 if self._cleanup: 55 args.append('--cleanup=' + self._cleanup) 56 return gdb_dejagnu.Main(args) 57 58 59# Parse the output log to determine how many failures we have. 60# Return -1 if parse output log failed. 61def GetNumNewFailures(result): 62 if not result: 63 return 0 64 return len(result) 65 66 67# Do not throw any exception in this function! 68def EmailResult(result): 69 email_to = ['yunlian@google.com'] 70 if len(result) == 4: 71 subject = 'Job failed: dejagnu test didn\'t finish' 72 email_text = ( 73 'Job failed prematurely, check exception below.\n' + result[3]) 74 elif result[0]: 75 subject = 'Job finished: dejagnu test failed' 76 num_new_failures = GetNumNewFailures(result[1]) 77 if num_new_failures >= 0: 78 summary = '{0} new fail(s), check log below.'.format(num_new_failures) 79 else: 80 summary = 'At least 1 new fail found, check log below.' 81 email_text = (summary + ('\nStdout ====\n' 82 '{0}\n' 83 '\nStderr ===\n' 84 '{1}\n').format(result[1], result[2])) 85 else: 86 subject = 'Job finished: dejagnu test passed' 87 email_text = ('Cool! No new fail found.\n' 88 '\nStdout ====\n' 89 '{0}\n' 90 '\nStderr ====\n' 91 '{1}\n').format(result[1], result[2]) 92 93 try: 94 email_sender.EmailSender().SendEmail(email_to, subject, email_text) 95 print('Email sent.') 96 except Exception as e: 97 # Do not propagate this email sending exception, you want to email an 98 # email exception? Just log it on console. 99 print('Sending email failed - {0}' 100 'Subject: {1}' 101 'Text: {2}').format( 102 str(e), subject, email_text) 103 104 105def ProcessArguments(argv): 106 """Processing script arguments.""" 107 parser = argparse.ArgumentParser( 108 description=('This script is used by nightly client to test gdb. ' 109 'DO NOT run it unless you know what you are doing.'), 110 usage='test_gdb_dejagnu.py options') 111 parser.add_argument('-b', 112 '--board', 113 dest='board', 114 help=('Required. Specify board type. For example ' 115 '\'lumpy\' and \'daisy\'')) 116 parser.add_argument('-r', 117 '--remote', 118 dest='remote', 119 help=('Required. Specify remote board address')) 120 parser.add_argument('-g', 121 '--gdb_dir', 122 dest='gdb_dir', 123 default='', 124 help=('Optional. Specify gdb checkout directory.')) 125 parser.add_argument('-c', 126 '--chromeos_root', 127 dest='chromeos_root', 128 default='chromeos.live', 129 help=('Optional. Specify chromeos checkout directory.')) 130 parser.add_argument('--cleanup', 131 dest='cleanup', 132 default=None, 133 help=('Optional. Do cleanup after the test.')) 134 135 options = parser.parse_args(argv) 136 137 if not options.board or not options.remote: 138 raise SyntaxError('--board and --remote are mandatory options.') 139 140 return options 141 142 143def Main(argv): 144 opt = ProcessArguments(argv) 145 print(opt) 146 adapter = DejagnuAdapter(opt.board, opt.remote, opt.gdb_dir, 147 opt.chromeos_root, opt.cleanup) 148 try: 149 adapter.SetupChromeOS() 150 adapter.SetupBoard() 151 ret = adapter.CheckGDB() 152 except Exception as e: 153 print(e) 154 ret = (1, '', '', str(e)) 155 finally: 156 EmailResult(ret) 157 158 return ret 159 160 161if __name__ == '__main__': 162 retval = Main(sys.argv[1:]) 163 sys.exit(retval[0]) 164