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