#!/bin/bash # # Copyright 2010 Google Inc. All Rights Reserved. # Author: bgay@google.com (Bruce Gay) # # The labpretest.sh script is designed to emulate a typical automated test lab # session. It puts a device into bootloader mode, reboots into bootloader mode, # determines device type, erases user cache, flashes a generic userdata image, # updates the bootloader image, updates the radio image, updates the system # image and reboots, sets up for a monkey run and finally runs a random monkey # test. It will repeat this based on an optional parameter(-i) or default to 100 # times. It will detect if it is in a low battery situation and wait for it to # charge again. COUNT=100 ROOT=$(cd `dirname $0` && pwd) ADB="$ROOT/tools/adb" FASTBOOT="$ROOT/tools/fastboot" MEVENTS=200 NOMONKEY=0 buildfile='' device='' product='' bootpart='' bootfile='' while getopts "d:i::m:xh" optionName; do case "$optionName" in d) device="$OPTARG";; i) COUNT=$OPTARG;; m) MEVENTS=$OPTARG;; x) NOMONKEY=1;; h) echo "options: [-d <device ID>, -i <loop count>, -m <monkey events> -x (skips monkey)]"; exit;; *) echo "invalid parameter -$optionName"; exit -1;; esac done declare -r COUNT declare -r MEVENTS declare -r NOMONKEY ################################################ # Prints output to console with time stamp # Arguments: # None # Returns: # None ################################################ log_print() { if [ -z "$1" ]; then echo "# $(date +'%D %T')" else echo "# $(date +'%D %T'): $1" fi } ################################################ # Blocks until battery level is at least # above TARGET if below LIMIT # Globals: # ADB # device # Arguments: # None # Returns: # None ################################################ wait_for_battery() { TARGET=80 LIMIT=20 local battery local tick log_print "checking battery level" while [ "$battery" = "" ]; do battery=`$ADB -s $device shell dumpsys battery | tr -d '\r' | awk '/level:/ {print $2}'` sleep 2 done if [ $battery -lt $LIMIT ]; then log_print "Battery is low, waiting for charge" while true; do battery=`$ADB -s $device shell dumpsys battery | tr -d '\r' | awk '/level:/ {print $2}'` if (( $battery >= $TARGET )); then break; fi tick=$[$TARGET - $battery] echo "battery charge level is $battery, sleeping for $tick seconds" sleep $[$TARGET - $battery * 10] done log_print "resuming test run with battery level at $battery%" else log_print "resuming test run with battery level at $battery%" fi } ################################################ # Blocks until device is in fastboot mode or # time out is reached # Globals: # loop # device # Arguments: # None # Returns: # None ################################################ fastboot_wait_for_device() { local fdevice="" local n=0 while [ "$device" != "$fdevice" -a $n -le 30 ]; do sleep 6 fdevice=`$FASTBOOT devices | sed -n "s/\($device\).*/\1/ p"` let n+=1 done if [ $n -gt 30 ]; then log_print "device time out after $loop iterations" exit else log_print "device returned and available" fi } ################################################ # reboots device into fastboot mode or # time out is reached # Globals: # device # ADB # Arguments: # None # Returns: # None ################################################ reboot_into_fastboot_from_adb() { log_print "rebooting into bootloader and waiting for availability via fastboot" $ADB -s $device reboot bootloader fastboot_wait_for_device } ################################################ # reboots device into fastboot mode or # times out # Globals: # device # FASTBOOT # Arguments: # None # Returns: # None ################################################ reboot_into_fastboot_from_fastboot() { log_print "rebooting into bootloader and waiting for availability via fastboot" $FASTBOOT -s $device reboot-bootloader fastboot_wait_for_device } ################################################ # reboots device from fastboot to adb or # times out # Globals: # device # FASTBOOT # ADB # Arguments: # None # Returns: # None ################################################ reboot_into_adb_from_fastboot() { log_print "rebooting and waiting for availability via adb" $FASTBOOT -s $device reboot $ADB -s $device wait-for-device } ################################################ # reboots device from fastboot to adb or # times out # Globals: # device # ADB # Arguments: # None # Returns: # None ################################################ wait_for_boot_complete() { log_print "waiting for device to finish booting" local result=$($ADB -s $device shell getprop dev.bootcomplete) local result_test=${result:1:1} echo -n "." while [ -z $result_test ]; do sleep 1 echo -n "." result=$($ADB -s $device shell getprop dev.bootcomplete) result_test=${result:0:1} done log_print "finished booting" } ################################################ # fastboot flashes partition # # Globals: # device # FASTBOOT # Arguments: # command_name # command_parameters # Returns: # None ################################################ fastboot_command() { $FASTBOOT -s $device $1 $2 $3 sleep 5 } ################################################ # fastboot command wrapper # # Globals: # device # FASTBOOT # Arguments: # partition_name # file_name # Returns: # None ################################################ flash_partition() { $FASTBOOT -s $device flash $1 $2 sleep 5 } ################################################ # adb command wrapper # # Globals: # device # ADB # Arguments: # command_name # command_parameters # Returns: # None ################################################ adb_command() { $ADB -s $device $1 $2 $3 $4 $5 sleep 5 } ################################################ # sets the name of the boot partition and # bootfile, then flashes device # # Globals: # product # ROOT # bootloaderfile # bootpart # device # Arguments: # None # Returns: # None ################################################ flash_bootloader_image() { if [ "$bootpart" == '' ]; then log_print "bootpart not defined" exit fi if [ "$bootloaderfile" == '' ]; then log_print "getting bootloader file for $product" bootloaderfile=`ls -1 $ROOT/$product | sed -n 's/\(.*boot[0-9._]\+img\)/\1/ p'` if [ "$bootloaderfile" == '' ]; then log_print "bootloader file empty: $bootloaderfile" exit fi if [ ! -e "$ROOT/$product/$bootloaderfile" ]; then log_print "bootloader file not found: ./$product/$bootloaderfile" exit fi log_print "using $ROOT/$product/$bootloaderfile as the bootloader image file" fi log_print "downloading bootloader image to $device" flash_partition $bootpart $ROOT/$product/$bootloaderfile reboot_into_fastboot_from_fastboot } ################################################ # sets the name of the radio partition and # radiofile and flashes device # # Globals: # product # ROOT # radiofile # radiopart # device # Arguments: # None # Returns: # None ################################################ flash_radio_image() { if [ "$radiopart" == '' ]; then log_print "setting radio partion to 'radio'" radiopart='radio' fi if [ "$radiofile" == "" ]; then log_print "getting radio file for $product" radiofile=`ls -1 $ROOT/$product | sed -n 's/\(radio[0-9._A-Za-z]\+img\)/\1/ p'` if [ "$radiofile" == "" ]; then log_print "radio file empty: $radiofile" exit fi if [ ! -e "$ROOT/$product/$radiofile" ]; then log_print "radio file not found: ./$product/$radiofile" exit fi log_print "using $ROOT/$product/$radiofile as the radio image file" fi log_print "downloading radio image to $device" flash_partition $radiopart $ROOT/$product/$radiofile reboot_into_fastboot_from_fastboot } ################################################ # sets the name of the boot partition and # bootfile # # Globals: # product # ROOT # buildfile # device # Arguments: # None # Returns: # None ################################################ flash_system_image() { if [ "$buildfile" == "" ]; then log_print "getting build file for $product" buildfile=`\ls -1 $ROOT/$product 2>&1 | sed -n 's/\([a-z]\+-img-[0-9]\+.zip\)/\1/ p'` if [ "$buildfile" == "" ]; then log_print "build file empty: $buildfile" exit fi if [ ! -e "$ROOT/$product/$buildfile" ]; then log_print "build file not found: ./$product/$buildfile" exit fi log_print "using $ROOT/$product/$buildfile as the system image file" fi log_print "downloading system image to $device" fastboot_command update $ROOT/$product/$buildfile } ################################################ # flashes the userdata partition # # Globals: # product # ROOT # Arguments: # None # Returns: # None ################################################ flash_userdata_image() { log_print "flashing userdata..." if [ -e $ROOT/$product/userdata.img ];then flash_partition userdata $ROOT/$product/userdata.img else log_print "userdata.img file not found: $ROOT/$product/userdata.img" exit fi } ################################################ # flashes the device # # Globals: # product # ROOT # FASTBOOT # bootfile # bootpart # radiofile # Arguments: # None # Returns: # None ################################################ flash_device() { log_print "erasing cache..." fastboot_command erase cache flash_userdata_image flash_bootloader_image flash_radio_image flash_system_image #device has been rebooted adb_command wait-for-device } ################################################ # gets the device product type and sets product # # Globals: # product # ROOT # FASTBOOT # device # Arguments: # None # Returns: # None ################################################ set_product_type() { if [ "$product" == "" ]; then log_print "getting device product type" product=`$FASTBOOT -s $device getvar product 2>&1 | sed -n 's/product: \([a-z]*\)\n*/\1/ p'` if [ ! -e "$ROOT/$product" ]; then log_print "device product id not supported: $product" exit fi fi log_print "using $product as device product id" } #start of script #test for dependencies if [ ! -e $ADB ]; then echo "Error: adb not in path! Please correct this." exit fi if [ ! -e $FASTBOOT ]; then echo "Error: fastboot not in path! Please correct this." exit fi #checks to see if the called device is available if [ "$device" != "" ]; then tmpdevice=`$ADB devices | sed -n "s/\($device\).*/\1/ p"` if [ "$device" != "$tmpdevice" ]; then tmpdevice=`$FASTBOOT devices | sed -n "s/\($device\).*/\1/ p"` if [ "$device" != "$tmpdevice" ]; then echo "Warning: device not found... $device" exit else echo "'Device '$device' found!'" reboot_into_adb_from_fastboot wait_for_boot_complete fi fi else device=`$ADB devices | sed -n 's/.*\(^[0-9A-Z]\{2\}[0-9A-Z]*\).*/\1/ p'` if [ `echo $device | wc -w` -ne 1 ]; then echo 'There is more than one device found,' echo 'please pass the correct device ID in as a parameter.' exit fi fi if [ "$device" == "" ]; then echo 'Device not found via adb' device=`$FASTBOOT devices | sed -n 's/.*\(^[0-9A-Z]\{2\}[0-9A-Z]*\).*/\1/ p'` if [ `echo $device | wc -w` -ne 1 ]; then echo "There is more than one device available," echo "please pass the correct device ID in as a parameter." exit fi if [ "$device" == "" ]; then echo 'Device not found via fastboot, please investigate' exit else echo 'Device '$device' found!' reboot_into_adb_from_fastboot wait_for_boot_complete echo 'Hammering on '$device fi else echo 'Hammering on '$device fi reboot_into_fastboot_from_adb set_product_type reboot_into_adb_from_fastboot wait_for_boot_complete #check for availability of a custom flash info file and retreive it if [ -e "$ROOT/$product/custom_flash.sh" ]; then . $ROOT/$product/custom_flash.sh fi echo $'\n\n' #start of looping for ((loop=1 ; loop <= $COUNT ; loop++ )) ; do echo "" echo "" echo ________________ $(date +'%D %T') - $loop - $device ______________________ log_print "setting adb root and sleeping for 7 seconds" adb_command root wait_for_battery log_print "rebooting into bootloader and waiting for availability via fastboot" reboot_into_fastboot_from_adb # not necessary, but useful in testing log_print "using fastboot to reboot to bootloader for test purposes" reboot_into_fastboot_from_fastboot #flashing the device flash_device #preping device for monkey run log_print "setting adb root" adb_command root log_print "setting ro.test_harness property" adb_command shell setprop ro.test_harness 1 log_print "waiting for device to finish booting" result=$($ADB -s $device shell getprop dev.bootcomplete) result_test=${result:1:1} echo -n "." while [ -z $result_test ]; do sleep 1 echo -n "." result=$($ADB -s $device shell getprop dev.bootcomplete) result_test=${result:0:1} done log_print "finished booting" log_print "waiting for the Package Manager" result=$($ADB -s $device shell pm path android) result_test=${result:0:7} echo -n "." while [ $result_test != "package" ]; do sleep 1 echo -n "." result=$($ADB -s $device shell pm path android) result_test=${result:0:7} done echo "Package Manager available" #lets you see what's going on log_print "setting shell svc power stayon true" adb_command shell svc power stayon true #calls the monkey run if not skipped if [ $NOMONKEY == 0 ]; then seed=$(($(date +%s) % 99)) log_print "running short monkey run..." $ADB -s $device shell monkey -p com.android.alarmclock -p com.android.browser -p com.android.calculator2 -p com.android.calendar -p com.android.camera -p com.android.contacts -p com.google.android.gm -p com.android.im -p com.android.launcher -p com.google.android.apps.maps -p com.android.mms -p com.android.music -p com.android.phone -p com.android.settings -p com.google.android.street -p com.android.vending -p com.google.android.youtube -p com.android.email -p com.google.android.voicesearch -c android.intent.category.LAUNCHER --ignore-security-exceptions -s $seed $MEVENTS log_print "finished running monkey, rinse, repeat..." else log_print "-x parameter used, skipping the monkey run" fi if [ $loop -eq $COUNT ]; then log_print "device $device has returned, testing completed, count = $loop" echo `echo "Device $device has returned, testing completed, count = $loop." > $ROOT/$device.log` else log_print "device $device has returned, rinse and repeat count = $loop" echo `echo "Device $device has returned, rinse and repeat count = $loop." > $ROOT/$device.log` fi done