1#!/usr/bin/python 2 3# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7"""A command to display summary statistics from runs of 'bootperf'. 8 9Command line options allow selecting from one of four sets of 10performance statistics: 11 1. boot time statistics (selected by --keyset boot) measure time 12 spent since kernel startup; 13 2. disk statistics (selected by --keyset disk) measure total bytes 14 read from the boot device since kernel startup; 15 3. firmware time statistics (selected by --keyset firmware) measure 16 time spent since CPU power on. 17 4. reboot time statistics (selected by --keyset reboot) measure 18 time spent since the shutdown request immediately preceding 19 the request. 20 21The various statistics are recorded as cumulative time (or disk read) 22since kernel startup (or CPU power on), sampled when specific events 23occur during boot. Events include such things as 'startup', (the 24moment when the upstart 'startup' job begins running), and 'login', 25(when the Chrome OS login screen is displayed). By default, all 26recorded events are included in the output; command line options 27allow restricting the view to a selected subset of events. 28 29Separate command line options allow selecting from one of two 30different display modes. When --averages is selected, the display 31shows the average value and sample standard deviation (as a percent 32of the average) for all selected events. The --averages display 33also calculates the difference (in time or bytes) between adjacent 34events, and shows the average and sample standard deviation of the 35differences. 36 37The --rawdata display shows the raw data value associated with each 38event for each boot: Each line of output represents the event values 39for one boot iteration. 40 41""" 42 43import sys 44import optparse 45 46import perfprinter 47import resultsdir 48import resultset 49 50 51_USAGE = "%prog [options] [results-directory ...]" 52_DESCRIPTION = """\ 53Summarize boot time performance results. The result directory 54arguments are directories previously specified as output for the 55'bootperf' script. 56""" 57 58 59def _SetupOptions(): 60 """Create an OptionParser for the command line.""" 61 optparser = optparse.OptionParser(usage=_USAGE, description=_DESCRIPTION) 62 63 optgroup = optparse.OptionGroup( 64 optparser, "Statistics selection") 65 66 keyset_help = ("Selects the set of statistics to display; " 67 "choose one of ") 68 keyset_help += "'" + resultset.TestResultSet.AVAILABLE_KEYSETS[0] + "'" 69 for keyset in resultset.TestResultSet.AVAILABLE_KEYSETS[1:-1]: 70 keyset_help += ", '" + keyset + "'" 71 keyset_help += (", or '" + 72 resultset.TestResultSet.AVAILABLE_KEYSETS[-1] + "'.") 73 keyset_default = resultset.TestResultSet.BOOTTIME_KEYSET 74 keyset_help += " (Default is '" + keyset_default + "'.)" 75 optgroup.add_option( 76 "-k", "--keyset", action="store", dest="keyset", type="choice", 77 choices=resultset.TestResultSet.AVAILABLE_KEYSETS, 78 help=keyset_help) 79 optparser.add_option_group(optgroup) 80 optparser.set_defaults(keyset=keyset_default) 81 82 optgroup = optparse.OptionGroup(optparser, "Event selection") 83 optgroup.add_option( 84 "-e", "--event", action="append", 85 dest="eventnames", 86 help="Restrict statistics to the comma-separated list of events.") 87 optparser.add_option_group(optgroup) 88 89 optgroup = optparse.OptionGroup( 90 optparser, "Display mode selection (choose one)") 91 optgroup.add_option( 92 "-a", "--averages", action="store_true", 93 dest="print_averages", 94 help="Display a summary of the averages of chosen statistics (default).") 95 optgroup.add_option( 96 "-r", "--rawdata", action="store_true", 97 dest="print_raw", 98 help="Display raw data from all boot iterations.") 99 optparser.add_option_group(optgroup) 100 optparser.set_defaults(print_averages=False) 101 optparser.set_defaults(print_raw=False) 102 return optparser 103 104 105def _ProcessDisplayOptions(options): 106 """Determine options controlling the display format. 107 108 Command options allow choosing either raw data format, or summary 109 statistics format. The default option is the summary format. 110 It's not allowed to select both formats. 111 112 @param options Parsed command line options data. 113 114 """ 115 display_count = 0 116 if options.print_averages: 117 display_count += 1 118 printfunc = perfprinter.PrintStatisticsSummary 119 if options.print_raw: 120 display_count += 1 121 printfunc = perfprinter.PrintRawData 122 if display_count == 0: 123 printfunc = perfprinter.PrintStatisticsSummary 124 elif display_count > 1: 125 print >>sys.stderr, "Can't use -a and -r together.\n" 126 return None 127 return printfunc 128 129 130def _ProcessEventlistOptions(options): 131 """Determine whether we'll display all events, or a subset. 132 133 Command options allow restricting a chosen key set to a 134 list of specific events. If the option is present, return 135 the list of events. Otherwise, return `None`. 136 137 @param options Parsed command line options data. 138 139 """ 140 if not options.eventnames: 141 return None 142 eventlist = [] 143 for kl in options.eventnames: 144 eventlist.extend(kl.split(',')) 145 return eventlist 146 147 148def main(argv): 149 """Canonical main routine.""" 150 optparser = _SetupOptions() 151 (options, args) = optparser.parse_args(argv) 152 printfunc = _ProcessDisplayOptions(options) 153 keyset_type = options.keyset 154 eventlist = _ProcessEventlistOptions(options) 155 if printfunc is None or keyset_type is None: 156 optparser.print_help() 157 sys.exit(1) 158 if not args: 159 args = ["."] 160 printfunc(resultsdir.ReadResultsDirectory, 161 args, keyset_type, eventlist) 162 163 164if __name__ == "__main__": 165 main(sys.argv[1:]) 166