| #!/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 |