• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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