test_gcc_dejagnu.py revision f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbe
1#!/usr/bin/python 2# 3# Copyright 2010 Google Inc. All Rights Reserved. 4"""Script adapter used by automation client for testing dejagnu. 5 This is not intended to be run on command line. 6 To kick off a single dejagnu run, use chromeos/v14/dejagnu/run_dejagnu.py 7""" 8 9__author__ = 'shenhan@google.com (Han Shen)' 10 11import optparse 12import os 13from os import path 14import sys 15import setup_chromeos 16import build_tc 17 18from dejagnu import run_dejagnu 19from utils import command_executer 20from utils import email_sender 21 22 23class DejagnuAdapter(object): 24 25 # TODO(shenhan): move these to constants.py. 26 _CHROMIUM_GCC_GIT = ('https://chromium.googlesource.com/' 27 'chromiumos/third_party/gcc.git') 28 _CHROMIUM_GCC_BRANCH = 'gcc.gnu.org/branches/google/gcc-4_7-mobile' 29 30 _cmd_exec = command_executer.GetCommandExecuter() 31 32 def __init__(self, board, remote, gcc_dir, chromeos_root, runtestflags, 33 cleanup): 34 self._board = board 35 self._remote = remote 36 self._gcc_dir = gcc_dir 37 self._chromeos_root = chromeos_root 38 self._runtestflags = runtestflags 39 self._cleanup = cleanup 40 41 def SetupChromeOS(self): 42 cmd = [setup_chromeos.__file__, '--dir=' + self._chromeos_root, 43 '--minilayout', '--jobs=8'] 44 ret = setup_chromeos.Main(cmd) 45 if ret: 46 raise Exception('Failed to checkout chromeos') 47 ## Do cros_sdk and setup_board, otherwise build_tc in next step will fail. 48 cmd = 'cd {0} && cros_sdk --download'.format(self._chromeos_root) 49 ret = self._cmd_exec.RunCommand(cmd, terminated_timeout=9000) 50 if ret: 51 raise Exception('Failed to create chroot.') 52 53 def SetupBoard(self): 54 cmd = './setup_board --board=' + self._board 55 ret = self._cmd_exec.ChrootRunCommand(self._chromeos_root, 56 cmd, 57 terminated_timeout=4000) 58 if ret: 59 raise Exception('Failed to setup board.') 60 61 def CheckoutGCC(self): 62 cmd = 'git clone {0} {1} && cd {1} && git checkout {2}'.format( 63 self._CHROMIUM_GCC_GIT, self._gcc_dir, self._CHROMIUM_GCC_BRANCH) 64 65 ret = self._cmd_exec.RunCommand(cmd, terminated_timeout=300) 66 if ret: 67 raise Exception('Failed to checkout gcc.') 68 ## Handle build_tc bug. 69 cmd = ('touch {0}/gcc/config/arm/arm-tune.md ' + \ 70 '{0}/gcc/config/arm/arm-tables.opt').format(self._gcc_dir) 71 ret = self._cmd_exec.RunCommand(cmd) 72 73 def BuildGCC(self): 74 build_gcc_args = [build_tc.__file__, '--board=' + self._board, 75 '--chromeos_root=' + self._chromeos_root, 76 '--gcc_dir=' + self._gcc_dir] 77 ret = build_tc.Main(build_gcc_args) 78 if ret: 79 raise Exception('Building gcc failed.') 80 81 def CheckGCC(self): 82 args = [run_dejagnu.__file__, '--board=' + self._board, 83 '--chromeos_root=' + self._chromeos_root, 84 '--mount=' + self._gcc_dir, '--remote=' + self._remote] 85 if self._cleanup: 86 args.append('--cleanup=' + self._cleanup) 87 if self._runtestflags: 88 args.append('--flags=' + self._runtestflags) 89 return run_dejagnu.Main(args) 90 91 92# Parse the output log to determine how many failures we have. 93# Return -1 if parse output log failed. 94def GetNumNewFailures(str): 95 if not str: 96 return 0 97 start_counting = False 98 n_failures = 0 99 for l in str.splitlines(): 100 print l 101 if not start_counting and 'Build results not in the manifest' in l: 102 start_counting = True 103 elif start_counting and l and ( 104 l.find('UNRESOLVED:') == 0 or l.find('FAIL:') == 0 or \ 105 l.find('XFAIL:') == 0 or l.find('XPASS:') == 0): 106 n_failures = n_failures + 1 107 if not start_counting: 108 return -1 109 return n_failures 110 111 112# Do not throw any exception in this function! 113def EmailResult(result): 114 email_to = ['c-compiler-chrome@google.com'] 115 email_from = ['dejagnu-job@google.com'] 116 if len(result) == 4: 117 subject = 'Job failed: dejagnu test didn\'t finish' 118 email_text = 'Job failed prematurely, check exception below.\n' + \ 119 result[3] 120 elif result[0]: 121 subject = 'Job finished: dejagnu test failed' 122 num_new_failures = GetNumNewFailures(result[1]) 123 if num_new_failures >= 0: 124 summary = '{0} new fail(s), check log below.'.format(num_new_failures) 125 else: 126 summary = 'At least 1 new fail found, check log below.' 127 email_text = summary + \ 128 ('\nStdout ====\n' 129 '{0}\n' 130 '\nStderr ===\n' 131 '{1}\n').format(result[1], result[2]) 132 else: 133 subject = 'Job finished: dejagnu test passed' 134 email_text = ('Cool! No new fail found.\n' 135 '\nStdout ====\n' 136 '{0}\n' 137 '\nStderr ====\n' 138 '{1}\n').format(result[1], result[2]) 139 140 try: 141 email_sender.EmailSender().SendEmail(email_to, subject, email_text) 142 print 'Email sent.' 143 except Exception as e: 144 # Do not propagate this email sending exception, you want to email an 145 # email exception? Just log it on console. 146 print('Sending email failed - {0}' 147 'Subject: {1}' 148 'Text: {2}').format( 149 str(e), subject, email_text) 150 151 152def ProcessArguments(argv): 153 """Processing script arguments.""" 154 parser = optparse.OptionParser( 155 description=('This script is used by nightly client to test gcc. ' 156 'DO NOT run it unless you know what you are doing.'), 157 usage='test_gcc_dejagnu.py options') 158 parser.add_option('-b', 159 '--board', 160 dest='board', 161 help=('Required. Specify board type. For example ' 162 '\'lumpy\' and \'daisy\'')) 163 parser.add_option('-r', 164 '--remote', 165 dest='remote', 166 help=('Required. Specify remote board address')) 167 parser.add_option('-g', 168 '--gcc_dir', 169 dest='gcc_dir', 170 default='gcc.live', 171 help=('Optional. Specify gcc checkout directory.')) 172 parser.add_option('-c', 173 '--chromeos_root', 174 dest='chromeos_root', 175 default='chromeos.live', 176 help=('Optional. Specify chromeos checkout directory.')) 177 parser.add_option('--cleanup', 178 dest='cleanup', 179 default=None, 180 help=('Optional. Do cleanup after the test.')) 181 parser.add_option('--runtestflags', 182 dest='runtestflags', 183 default=None, 184 help=('Optional. Options to RUNTESTFLAGS env var ' 185 'while invoking make check. ' 186 '(Mainly used for testing purpose.)')) 187 188 options, args = parser.parse_args(argv) 189 190 if not options.board or not options.remote: 191 raise Exception('--board and --remote are mandatory options.') 192 193 return options 194 195 196def Main(argv): 197 opt = ProcessArguments(argv) 198 adapter = DejagnuAdapter(opt.board, opt.remote, opt.gcc_dir, 199 opt.chromeos_root, opt.runtestflags, opt.cleanup) 200 try: 201 adapter.SetupChromeOS() 202 adapter.SetupBoard() 203 adapter.CheckoutGCC() 204 adapter.BuildGCC() 205 ret = adapter.CheckGCC() 206 except Exception as e: 207 print e 208 ret = (1, '', '', str(e)) 209 finally: 210 EmailResult(ret) 211 return ret 212 213 214if __name__ == '__main__': 215 retval = Main(sys.argv) 216 sys.exit(retval[0]) 217