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