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