Home | History | Annotate | Download | only in bootperf-bin
      1 #!/bin/bash
      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 # Wrapper to run the platform_BootPerfServer autotest, and store the
      8 # results for later analysis by the 'showbootdata' script.
      9 #
     10 # NOTE: This script must be run from inside the chromeos build
     11 # chroot environment.
     12 #
     13 
     14 # --- BEGIN COMMON.SH BOILERPLATE ---
     15 # Load common CrOS utilities.  Inside the chroot this file is installed in
     16 # /usr/lib/crosutils.  Outside the chroot we find it relative to the script's
     17 # location.
     18 find_common_sh() {
     19   local common_paths=(/usr/lib/crosutils "$(dirname "$(readlink -f "$0")")/..")
     20   local path
     21 
     22   SCRIPT_ROOT=
     23   for path in "${common_paths[@]}"; do
     24     if [ -r "${path}/common.sh" ]; then
     25       SCRIPT_ROOT=${path}
     26       break
     27     fi
     28   done
     29 }
     30 
     31 find_common_sh
     32 . "${SCRIPT_ROOT}/common.sh" || (echo "Unable to load common.sh" && exit 1)
     33 # --- END COMMON.SH BOILERPLATE ---
     34 
     35 # TODO(jrbarnette) The log files produced in this script will be
     36 # stored inside the chroot.  So, from outside the chroot, this
     37 # script doesn't work.  I don't know if this is easy to fix, but
     38 # you're welcome to try.  Let me know how it goes.  :-)
     39 assert_inside_chroot
     40 
     41 DEFINE_string output_dir "" "output directory for results" o
     42 DEFINE_string board "" "name of board we are testing"
     43 DEFINE_boolean keep_logs "$FLAGS_FALSE" "keep autotest results" k
     44 
     45 RUN_TEST="test_that"
     46 TEST='platform_BootPerfServer.bootperf'
     47 TMP_RESULTS="$(mktemp -d /tmp/bootperf.XXXXXX)"
     48 RESULTS_ROOT="results-1-$TEST"
     49 RESULTS_DIR=platform_BootPerfServer/results
     50 RESULTS_KEYVAL=$RESULTS_DIR/keyval
     51 RESULTS_SUMMARY_FILES=(
     52   $RESULTS_DIR
     53   keyval
     54   platform_BootPerfServer/keyval
     55   platform_BootPerfServer/platform_BootPerf/keyval
     56   platform_BootPerfServer/platform_BootPerf/status
     57   platform_BootPerfServer/status
     58   platform_BootPerfServer/status.log
     59   platform_BootPerfServer/sysinfo/cmdline
     60   platform_BootPerfServer/sysinfo/cpuinfo
     61   platform_BootPerfServer/sysinfo/modules
     62   platform_BootPerfServer/sysinfo/uname
     63   platform_BootPerfServer/sysinfo/version
     64   status.log
     65 )
     66 
     67 # Structure of a results directory:
     68 #   $RUNDIR.$ITER/          - directory
     69 #       $RUNDIR_LOG             - file
     70 #       $RUNDIR_SUMMARY/        - directory
     71 #       $RUNDIR_ALL_RESULTS/    - optional directory
     72 #   $KEYVAL_SUMMARY/        - file
     73 # If you add any other content under the results directory, you'll
     74 # probably need to change extra_files(), below.
     75 RUNDIR=run
     76 RUNDIR_LOG=log.txt
     77 RUNDIR_SUMMARY=summary
     78 RUNDIR_ALL_RESULTS=logs
     79 KEYVAL_SUMMARY=results_keyval
     80 
     81 
     82 # Usage/help function.  This function is known to the shflags library,
     83 # and mustn't be renamed.
     84 flags_help() {
     85   cat <<END_USAGE >&2
     86 usage: $(basename $0) [ <options> ] <ip-address> [ <count> ]
     87 Options:
     88   --output_dir <directory>
     89   --o <directory>       Specify output directory for results
     90 
     91   --board <BOARDNAME>   name of board we are testing (e.g. daisy)
     92 
     93   --[no]keep_logs
     94   -k                    Keep [don't keep] autotest log files
     95 Summary:
     96   Run the platform_BootPerfServer autotest, and store results in the
     97   given destination directory.  The test target is specified by
     98   <ip-address>.
     99 
    100   By default, the test is run once; if <count> is given, the test is
    101   run that many times.  Note that the platform_BootPerfServer test
    102   reboots the target 10 times, so the total number of reboots will
    103   be 10*<count>.
    104 
    105   If the destination directory doesn't exist, it is created.  If the
    106   destination directory already holds test results, additional
    107   results are added in without overwriting earlier results.
    108 
    109   If no destination is specified, the current directory is used,
    110   provided that the directory is empty, or has been previously used
    111   as a destination directory for this command.
    112 
    113   By default, only a summary subset of the log files created by
    114   autotest is preserved; with --keep_logs the (potentially large)
    115   autotest logs are preserved with the test results.
    116 END_USAGE
    117   return $FLAGS_TRUE
    118 }
    119 
    120 usage() {
    121   if [ $# -gt 0 ]; then
    122     error "$(basename $0): $*"
    123     echo >&2
    124   fi
    125   flags_help
    126   exit 1
    127 }
    128 
    129 # List any files in the current directory not created as output
    130 # from running this script.
    131 extra_files() {
    132   ls | grep -v "^$RUNDIR[.]...\$" |
    133        grep -v $KEYVAL_SUMMARY
    134 }
    135 
    136 # Main function to run the boot performance test.  Run the boot
    137 # performance test for the given count, putting output into the
    138 # current directory.
    139 #
    140 # Arguments are <ip-address> and <count> arguments, as for the main
    141 # command.
    142 #
    143 # We terminate test runs if "test_that" ever fails to produce the
    144 # results keyval file; generally this is the result of a serious
    145 # error (e.g. disk full) that won't go away if we just plow on.
    146 run_boot_test() {
    147   local remote="$1"
    148   local count="${2:-1}"
    149 
    150   local iter=$(expr "$(echo $RUNDIR.???)" : '.*\(...\)')
    151   if [ "$iter" != "???" ]; then
    152       iter=$(echo $iter | awk '{printf "%03d\n", $1 + 1}')
    153   else
    154       iter=000
    155   fi
    156 
    157   i=0
    158   while [ $i -lt $count ]; do
    159     local iter_rundir=$RUNDIR.$iter
    160     local logfile=$(pwd)/$iter_rundir/$RUNDIR_LOG
    161     local summary_dir=$iter_rundir/$RUNDIR_SUMMARY
    162     local all_results_dir=$iter_rundir/$RUNDIR_ALL_RESULTS
    163 
    164     mkdir $iter_rundir
    165     echo "$(date '+%T') - $logfile"
    166 
    167     $RUN_TEST --results_dir="$TMP_RESULTS" --args "10" $BOARD \
    168               "$remote" $TEST >$logfile 2>&1
    169     if [ ! -e "$TMP_RESULTS/$RESULTS_ROOT/$RESULTS_KEYVAL" ]; then
    170       error "No results file; terminating test runs."
    171       error "Check $logfile for output from the test run,"
    172       error "and see $TMP_RESULTS for full test logs and output."
    173       return
    174     fi
    175     mkdir $summary_dir
    176     tar cf - -C $TMP_RESULTS/$RESULTS_ROOT "${RESULTS_SUMMARY_FILES[@]}" |
    177       tar xf - -C $summary_dir
    178     if [ $FLAGS_keep_logs -eq $FLAGS_TRUE ]; then
    179       mv $TMP_RESULTS $all_results_dir
    180       chmod 755 $all_results_dir
    181     else
    182       rm -rf $TMP_RESULTS
    183     fi
    184     i=$(expr $i + 1)
    185     iter=$(echo $iter | awk '{printf "%03d\n", $1 + 1}')
    186   done
    187   date '+%T'
    188   cat $RUNDIR.???/$RUNDIR_SUMMARY/$RESULTS_KEYVAL >$KEYVAL_SUMMARY
    189 }
    190 
    191 # Main routine - check validity of the (already parsed) command line
    192 # options.  'cd' to the results directory, if it was specified.  If
    193 # all the arguments checks pass, hand control to run_boot_test
    194 main() {
    195   if [ $# -lt 1 ]; then
    196       usage "Missing target host address"
    197   elif [ $# -gt 2 ]; then
    198       usage "Too many arguments"
    199   fi
    200 
    201   if [ -n "${FLAGS_board}" ]; then
    202     BOARD="--board=${FLAGS_board}"
    203   fi
    204 
    205   if [ -n "${FLAGS_output_dir}" ]; then
    206     if [ ! -d "${FLAGS_output_dir}" ]; then
    207       if ! mkdir "${FLAGS_output_dir}"; then
    208         usage "Unable to create ${FLAGS_output_dir}"
    209       fi
    210     fi
    211     cd "${FLAGS_output_dir}" ||
    212       usage "No permissions to chdir to ${FLAGS_output_dir}"
    213   elif [ -n "$(extra_files)" ]; then
    214     error "No results directory specified, and current directory"
    215     error "contains contents other than run results."
    216     error "You can override this error by using the --output_dir option"
    217     usage
    218   fi
    219 
    220   # Check the count argument.
    221   # N.B. the test [ "$2" -eq "$2" ] tests whether "$2" is valid as a
    222   # number; when it fails it will also report a syntax error (which
    223   # we suppress).
    224   if [ -n "$2" ]; then
    225     if ! [ "$2" -eq "$2" ] 2>/dev/null || [ "$2" -le 0 ]; then
    226       usage "<count> argument must be a positive number"
    227     fi
    228   fi
    229 
    230   run_boot_test "$@"
    231 }
    232 
    233 # shflags defines --help implicitly; if it's used on the command
    234 # line FLAGS will invoke flags_help, set FLAGS_help to TRUE, and
    235 # then return false.  To avoid printing help twice, we have to check
    236 # for that case here.
    237 if ! FLAGS "$@"; then
    238   if [ ${FLAGS_help} -eq ${FLAGS_TRUE} ]; then
    239     exit 0
    240   else
    241     usage
    242   fi
    243 fi
    244 
    245 eval main "${FLAGS_ARGV}"
    246