Caroline Tice | f6ef439 | 2017-04-06 17:16:05 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python2 |
Caroline Tice | 88272d4 | 2016-01-13 09:48:29 -0800 | [diff] [blame] | 2 | """Script adapter used by automation client for testing dejagnu. |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 3 | |
Caroline Tice | 88272d4 | 2016-01-13 09:48:29 -0800 | [diff] [blame] | 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 | |
| 8 | from __future__ import print_function |
| 9 | |
| 10 | import argparse |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 11 | import sys |
| 12 | import setup_chromeos |
| 13 | |
| 14 | from dejagnu import gdb_dejagnu |
Caroline Tice | 88272d4 | 2016-01-13 09:48:29 -0800 | [diff] [blame] | 15 | from cros_utils import command_executer |
| 16 | from cros_utils import email_sender |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 17 | |
| 18 | |
| 19 | class DejagnuAdapter(object): |
Caroline Tice | 88272d4 | 2016-01-13 09:48:29 -0800 | [diff] [blame] | 20 | """Dejagnu Adapter class.""" |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 21 | |
Luis Lozano | f2a3ef4 | 2015-12-15 13:49:30 -0800 | [diff] [blame] | 22 | def __init__(self, board, remote, gdb_dir, chromeos_root, cleanup): |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 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): |
Caroline Tice | f6ef439 | 2017-04-06 17:16:05 -0700 | [diff] [blame] | 31 | cmd = [ |
| 32 | setup_chromeos.__file__, '--dir=' + self._chromeos_root, '--minilayout', |
| 33 | '--jobs=8' |
| 34 | ] |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 35 | ret = setup_chromeos.Main(cmd) |
| 36 | if ret: |
Caroline Tice | 9099a78 | 2016-07-22 16:28:12 -0700 | [diff] [blame] | 37 | raise RuntimeError('Failed to checkout chromeos') |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 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: |
Caroline Tice | 9099a78 | 2016-07-22 16:28:12 -0700 | [diff] [blame] | 42 | raise RuntimeError('Failed to create chroot.') |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 43 | |
| 44 | def SetupBoard(self): |
| 45 | cmd = './setup_board --board=' + self._board |
Caroline Tice | f6ef439 | 2017-04-06 17:16:05 -0700 | [diff] [blame] | 46 | ret = self._cmd_exec.ChrootRunCommand( |
| 47 | self._chromeos_root, cmd, terminated_timeout=4000) |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 48 | if ret: |
Caroline Tice | 9099a78 | 2016-07-22 16:28:12 -0700 | [diff] [blame] | 49 | raise RuntimeError('Failed to setup board.') |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 50 | |
| 51 | def CheckGDB(self): |
Caroline Tice | f6ef439 | 2017-04-06 17:16:05 -0700 | [diff] [blame] | 52 | args = [ |
| 53 | gdb_dejagnu.__file__, '--board=' + self._board, |
| 54 | '--chromeos_root=' + self._chromeos_root, '--mount=' + self._gdb_dir, |
| 55 | '--remote=' + self._remote |
| 56 | ] |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 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. |
Yunlian Jiang | a9c561a | 2014-01-02 13:51:15 -0800 | [diff] [blame] | 64 | def GetNumNewFailures(result): |
| 65 | if not result: |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 66 | return 0 |
Yunlian Jiang | a9c561a | 2014-01-02 13:51:15 -0800 | [diff] [blame] | 67 | return len(result) |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 68 | |
| 69 | |
| 70 | # Do not throw any exception in this function! |
| 71 | def EmailResult(result): |
| 72 | email_to = ['yunlian@google.com'] |
| 73 | if len(result) == 4: |
| 74 | subject = 'Job failed: dejagnu test didn\'t finish' |
Luis Lozano | f2a3ef4 | 2015-12-15 13:49:30 -0800 | [diff] [blame] | 75 | email_text = ( |
| 76 | 'Job failed prematurely, check exception below.\n' + result[3]) |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 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.' |
Luis Lozano | f2a3ef4 | 2015-12-15 13:49:30 -0800 | [diff] [blame] | 84 | email_text = (summary + ('\nStdout ====\n' |
| 85 | '{0}\n' |
| 86 | '\nStderr ===\n' |
| 87 | '{1}\n').format(result[1], result[2])) |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 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) |
Caroline Tice | 88272d4 | 2016-01-13 09:48:29 -0800 | [diff] [blame] | 98 | print('Email sent.') |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 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. |
Luis Lozano | f2a3ef4 | 2015-12-15 13:49:30 -0800 | [diff] [blame] | 102 | print('Sending email failed - {0}' |
| 103 | 'Subject: {1}' |
Caroline Tice | f6ef439 | 2017-04-06 17:16:05 -0700 | [diff] [blame] | 104 | 'Text: {2}').format(str(e), subject, email_text) |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 105 | |
| 106 | |
| 107 | def ProcessArguments(argv): |
| 108 | """Processing script arguments.""" |
Caroline Tice | 88272d4 | 2016-01-13 09:48:29 -0800 | [diff] [blame] | 109 | parser = argparse.ArgumentParser( |
Luis Lozano | f2a3ef4 | 2015-12-15 13:49:30 -0800 | [diff] [blame] | 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') |
Caroline Tice | f6ef439 | 2017-04-06 17:16:05 -0700 | [diff] [blame] | 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.')) |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 141 | |
Caroline Tice | 88272d4 | 2016-01-13 09:48:29 -0800 | [diff] [blame] | 142 | options = parser.parse_args(argv) |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 143 | |
| 144 | if not options.board or not options.remote: |
Caroline Tice | 9099a78 | 2016-07-22 16:28:12 -0700 | [diff] [blame] | 145 | raise SyntaxError('--board and --remote are mandatory options.') |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 146 | |
| 147 | return options |
| 148 | |
| 149 | |
| 150 | def Main(argv): |
| 151 | opt = ProcessArguments(argv) |
Caroline Tice | 88272d4 | 2016-01-13 09:48:29 -0800 | [diff] [blame] | 152 | print(opt) |
Luis Lozano | f2a3ef4 | 2015-12-15 13:49:30 -0800 | [diff] [blame] | 153 | adapter = DejagnuAdapter(opt.board, opt.remote, opt.gdb_dir, |
| 154 | opt.chromeos_root, opt.cleanup) |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 155 | try: |
| 156 | adapter.SetupChromeOS() |
| 157 | adapter.SetupBoard() |
| 158 | ret = adapter.CheckGDB() |
| 159 | except Exception as e: |
Caroline Tice | 88272d4 | 2016-01-13 09:48:29 -0800 | [diff] [blame] | 160 | print(e) |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 161 | ret = (1, '', '', str(e)) |
| 162 | finally: |
| 163 | EmailResult(ret) |
Caroline Tice | 88272d4 | 2016-01-13 09:48:29 -0800 | [diff] [blame] | 164 | |
| 165 | return ret |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 166 | |
Luis Lozano | f2a3ef4 | 2015-12-15 13:49:30 -0800 | [diff] [blame] | 167 | |
| 168 | if __name__ == '__main__': |
Caroline Tice | 88272d4 | 2016-01-13 09:48:29 -0800 | [diff] [blame] | 169 | retval = Main(sys.argv[1:]) |
Yunlian Jiang | dffb0a9 | 2013-12-20 14:10:16 -0800 | [diff] [blame] | 170 | sys.exit(retval[0]) |