aboutsummaryrefslogtreecommitdiff
path: root/deprecated/crb/crb_driver.py
diff options
context:
space:
mode:
Diffstat (limited to 'deprecated/crb/crb_driver.py')
-rwxr-xr-xdeprecated/crb/crb_driver.py370
1 files changed, 370 insertions, 0 deletions
diff --git a/deprecated/crb/crb_driver.py b/deprecated/crb/crb_driver.py
new file mode 100755
index 00000000..c6403462
--- /dev/null
+++ b/deprecated/crb/crb_driver.py
@@ -0,0 +1,370 @@
+#!/usr/bin/python2
+#
+# Copyright 2010 Google Inc. All Rights Reserved.
+
+import datetime
+import optparse
+import os
+import smtplib
+import sys
+import time
+from email.mime.text import MIMEText
+
+from autotest_gatherer import AutotestGatherer as AutotestGatherer
+from autotest_run import AutotestRun as AutotestRun
+from machine_manager_singleton import MachineManagerSingleton as MachineManagerSingleton
+from cros_utils import logger
+from cros_utils.file_utils import FileUtils
+
+
+def CanonicalizeChromeOSRoot(chromeos_root):
+ chromeos_root = os.path.expanduser(chromeos_root)
+ if os.path.isfile(os.path.join(chromeos_root, 'src/scripts/enter_chroot.sh')):
+ return chromeos_root
+ else:
+ return None
+
+
+class Autotest(object):
+
+ def __init__(self, autotest_string):
+ self.name = None
+ self.iterations = None
+ self.args = None
+ fields = autotest_string.split(',', 1)
+ self.name = fields[0]
+ if len(fields) > 1:
+ autotest_string = fields[1]
+ fields = autotest_string.split(',', 1)
+ else:
+ return
+ self.iterations = int(fields[0])
+ if len(fields) > 1:
+ self.args = fields[1]
+ else:
+ return
+
+ def __str__(self):
+ return '\n'.join([self.name, self.iterations, self.args])
+
+
+def CreateAutotestListFromString(autotest_strings, default_iterations=None):
+ autotest_list = []
+ for autotest_string in autotest_strings.split(':'):
+ autotest = Autotest(autotest_string)
+ if default_iterations and not autotest.iterations:
+ autotest.iterations = default_iterations
+
+ autotest_list.append(autotest)
+ return autotest_list
+
+
+def CreateAutotestRuns(images,
+ autotests,
+ remote,
+ board,
+ exact_remote,
+ rerun,
+ rerun_if_failed,
+ main_chromeos_root=None):
+ autotest_runs = []
+ for image in images:
+ logger.GetLogger().LogOutput('Computing md5sum of: %s' % image)
+ image_checksum = FileUtils().Md5File(image)
+ logger.GetLogger().LogOutput('md5sum %s: %s' % (image, image_checksum))
+ ### image_checksum = "abcdefghi"
+
+ chromeos_root = main_chromeos_root
+ if not main_chromeos_root:
+ image_chromeos_root = os.path.join(
+ os.path.dirname(image), '../../../../..')
+ chromeos_root = CanonicalizeChromeOSRoot(image_chromeos_root)
+ assert chromeos_root, 'chromeos_root: %s invalid' % image_chromeos_root
+ else:
+ chromeos_root = CanonicalizeChromeOSRoot(main_chromeos_root)
+ assert chromeos_root, 'chromeos_root: %s invalid' % main_chromeos_root
+
+ # We just need a single ChromeOS root in the MachineManagerSingleton. It is
+ # needed because we can save re-image time by checking the image checksum at
+ # the beginning and assigning autotests to machines appropriately.
+ if not MachineManagerSingleton().chromeos_root:
+ MachineManagerSingleton().chromeos_root = chromeos_root
+
+ for autotest in autotests:
+ for iteration in range(autotest.iterations):
+ autotest_run = AutotestRun(autotest,
+ chromeos_root=chromeos_root,
+ chromeos_image=image,
+ board=board,
+ remote=remote,
+ iteration=iteration,
+ image_checksum=image_checksum,
+ exact_remote=exact_remote,
+ rerun=rerun,
+ rerun_if_failed=rerun_if_failed)
+ autotest_runs.append(autotest_run)
+ return autotest_runs
+
+
+def GetNamesAndIterations(autotest_runs):
+ strings = []
+ for autotest_run in autotest_runs:
+ strings.append('%s:%s' % (autotest_run.autotest.name,
+ autotest_run.iteration))
+ return ' %s (%s)' % (len(strings), ' '.join(strings))
+
+
+def GetStatusString(autotest_runs):
+ status_bins = {}
+ for autotest_run in autotest_runs:
+ if autotest_run.status not in status_bins:
+ status_bins[autotest_run.status] = []
+ status_bins[autotest_run.status].append(autotest_run)
+
+ status_strings = []
+ for key, val in status_bins.items():
+ status_strings.append('%s: %s' % (key, GetNamesAndIterations(val)))
+ return 'Thread Status:\n%s' % '\n'.join(status_strings)
+
+
+def GetProgressBar(num_done, num_total):
+ ret = 'Done: %s%%' % int(100.0 * num_done / num_total)
+ bar_length = 50
+ done_char = '>'
+ undone_char = ' '
+ num_done_chars = bar_length * num_done / num_total
+ num_undone_chars = bar_length - num_done_chars
+ ret += ' [%s%s]' % (num_done_chars * done_char,
+ num_undone_chars * undone_char)
+ return ret
+
+
+def GetProgressString(start_time, num_remain, num_total):
+ current_time = time.time()
+ elapsed_time = current_time - start_time
+ try:
+ eta_seconds = float(num_remain) * elapsed_time / (num_total - num_remain)
+ eta_seconds = int(eta_seconds)
+ eta = datetime.timedelta(seconds=eta_seconds)
+ except ZeroDivisionError:
+ eta = 'Unknown'
+ strings = []
+ strings.append('Current time: %s Elapsed: %s ETA: %s' %
+ (datetime.datetime.now(),
+ datetime.timedelta(seconds=int(elapsed_time)), eta))
+ strings.append(GetProgressBar(num_total - num_remain, num_total))
+ return '\n'.join(strings)
+
+
+def RunAutotestRunsInParallel(autotest_runs):
+ start_time = time.time()
+ active_threads = []
+ for autotest_run in autotest_runs:
+ # Set threads to daemon so program exits when ctrl-c is pressed.
+ autotest_run.daemon = True
+ autotest_run.start()
+ active_threads.append(autotest_run)
+
+ print_interval = 30
+ last_printed_time = time.time()
+ while active_threads:
+ try:
+ active_threads = [t for t in active_threads
+ if t is not None and t.isAlive()]
+ for t in active_threads:
+ t.join(1)
+ if time.time() - last_printed_time > print_interval:
+ border = '=============================='
+ logger.GetLogger().LogOutput(border)
+ logger.GetLogger().LogOutput(GetProgressString(start_time, len(
+ [t for t in autotest_runs if t.status not in ['SUCCEEDED', 'FAILED']
+ ]), len(autotest_runs)))
+ logger.GetLogger().LogOutput(GetStatusString(autotest_runs))
+ logger.GetLogger().LogOutput('%s\n' %
+ MachineManagerSingleton().AsString())
+ logger.GetLogger().LogOutput(border)
+ last_printed_time = time.time()
+ except KeyboardInterrupt:
+ print 'C-c received... cleaning up threads.'
+ for t in active_threads:
+ t.terminate = True
+ return 1
+ return 0
+
+
+def RunAutotestRunsSerially(autotest_runs):
+ for autotest_run in autotest_runs:
+ retval = autotest_run.Run()
+ if retval:
+ return retval
+
+
+def ProduceTables(autotest_runs, full_table, fit_string):
+ l = logger.GetLogger()
+ ags_dict = {}
+ for autotest_run in autotest_runs:
+ name = autotest_run.full_name
+ if name not in ags_dict:
+ ags_dict[name] = AutotestGatherer()
+ ags_dict[name].runs.append(autotest_run)
+ output = ''
+ for b, ag in ags_dict.items():
+ output += 'Benchmark: %s\n' % b
+ output += ag.GetFormattedMainTable(percents_only=not full_table,
+ fit_string=fit_string)
+ output += '\n'
+
+ summary = ''
+ for b, ag in ags_dict.items():
+ summary += 'Benchmark Summary Table: %s\n' % b
+ summary += ag.GetFormattedSummaryTable(percents_only=not full_table,
+ fit_string=fit_string)
+ summary += '\n'
+
+ output += summary
+ output += ('Number of re-images performed: %s' %
+ MachineManagerSingleton().num_reimages)
+ l.LogOutput(output)
+
+ if autotest_runs:
+ board = autotest_runs[0].board
+ else:
+ board = ''
+
+ subject = '%s: %s' % (board, ', '.join(ags_dict.keys()))
+
+ if any(autotest_run.run_completed for autotest_run in autotest_runs):
+ SendEmailToUser(subject, summary)
+
+
+def SendEmailToUser(subject, text_to_send):
+ # Email summary to the current user.
+ msg = MIMEText(text_to_send)
+
+ # me == the sender's email address
+ # you == the recipient's email address
+ me = os.path.basename(__file__)
+ you = os.getlogin()
+ msg['Subject'] = '[%s] %s' % (os.path.basename(__file__), subject)
+ msg['From'] = me
+ msg['To'] = you
+
+ # Send the message via our own SMTP server, but don't include the
+ # envelope header.
+ s = smtplib.SMTP('localhost')
+ s.sendmail(me, [you], msg.as_string())
+ s.quit()
+
+
+def Main(argv):
+ """The main function."""
+ # Common initializations
+ ### command_executer.InitCommandExecuter(True)
+ l = logger.GetLogger()
+
+ parser = optparse.OptionParser()
+ parser.add_option('-t',
+ '--tests',
+ dest='tests',
+ help=('Tests to compare.'
+ 'Optionally specify per-test iterations by:'
+ '<test>,<iter>:<args>'))
+ parser.add_option('-c',
+ '--chromeos_root',
+ dest='chromeos_root',
+ help='A *single* chromeos_root where scripts can be found.')
+ parser.add_option('-n',
+ '--iterations',
+ dest='iterations',
+ help='Iterations to run per benchmark.',
+ default=1)
+ parser.add_option('-r',
+ '--remote',
+ dest='remote',
+ help='The remote chromeos machine.')
+ parser.add_option('-b', '--board', dest='board', help='The remote board.')
+ parser.add_option('--full_table',
+ dest='full_table',
+ help='Print full tables.',
+ action='store_true',
+ default=True)
+ parser.add_option('--exact_remote',
+ dest='exact_remote',
+ help='Run tests on the exact remote.',
+ action='store_true',
+ default=False)
+ parser.add_option('--fit_string',
+ dest='fit_string',
+ help='Fit strings to fixed sizes.',
+ action='store_true',
+ default=False)
+ parser.add_option('--rerun',
+ dest='rerun',
+ help='Re-run regardless of cache hit.',
+ action='store_true',
+ default=False)
+ parser.add_option('--rerun_if_failed',
+ dest='rerun_if_failed',
+ help='Re-run if previous run was a failure.',
+ action='store_true',
+ default=False)
+ parser.add_option('--no_lock',
+ dest='no_lock',
+ help='Do not lock the machine before running the tests.',
+ action='store_true',
+ default=False)
+ l.LogOutput(' '.join(argv))
+ [options, args] = parser.parse_args(argv)
+
+ if options.remote is None:
+ l.LogError('No remote machine specified.')
+ parser.print_help()
+ return 1
+
+ if not options.board:
+ l.LogError('No board specified.')
+ parser.print_help()
+ return 1
+
+ remote = options.remote
+ tests = options.tests
+ board = options.board
+ exact_remote = options.exact_remote
+ iterations = int(options.iterations)
+
+ autotests = CreateAutotestListFromString(tests, iterations)
+
+ main_chromeos_root = options.chromeos_root
+ images = args[1:]
+ fit_string = options.fit_string
+ full_table = options.full_table
+ rerun = options.rerun
+ rerun_if_failed = options.rerun_if_failed
+
+ MachineManagerSingleton().no_lock = options.no_lock
+
+ # Now try creating all the Autotests
+ autotest_runs = CreateAutotestRuns(images, autotests, remote, board,
+ exact_remote, rerun, rerun_if_failed,
+ main_chromeos_root)
+
+ try:
+ # At this point we have all the autotest runs.
+ for machine in remote.split(','):
+ MachineManagerSingleton().AddMachine(machine)
+
+ retval = RunAutotestRunsInParallel(autotest_runs)
+ if retval:
+ return retval
+
+ # Now print tables
+ ProduceTables(autotest_runs, full_table, fit_string)
+ finally:
+ # not sure why this isn't called at the end normally...
+ MachineManagerSingleton().__del__()
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(Main(sys.argv))