-
-
Save DominikDary/3226892 to your computer and use it in GitHub Desktop.
Script for starting up multiple android emulators per box
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
##### | |
# | |
# This script creates android emulators on the fly. | |
# | |
# Please refer to the README for usage instructions. | |
# | |
#### | |
# Set-up ANDROID_SDK_HOME | |
# this creates all the AVD's and the emulator will look for them in the same location | |
if [ "x${avd_dir}" != "x" ]; then | |
export ANDROID_SDK_HOME="${avd_dir}" | |
else | |
export ANDROID_SDK_HOME="/var/yandroid_sdk/avd_dir" | |
fi | |
# set the directory to find the current webdriver apk | |
## I downlaod the apk separately and keep it somewhere special | |
if [ "x${selenium_grid_android_server__apk_dir}" != "x" ]; then | |
APK_DIR="${apk_dir}" | |
else | |
APK_DIR="/usr/lib/selenium_grid_android_server" | |
fi | |
# grab some variables | |
## emulator_count | |
if [ "x${emulator_count}" != "x" ]; then | |
EMULATOR_COUNT="${emulator_count}" | |
else | |
EMULATOR_COUNT="1" | |
fi | |
## android_target | |
if [ "x${android_target}" != "x" ]; then | |
ANDROID_TARGET="${android_target}" | |
else | |
ANDROID_TARGET="anrdoid-15" | |
fi | |
## android_target | |
if [ "x${android_abi}" != "x" ]; then | |
ANDROID_ABI="${android_abi}" | |
else | |
ANDROID_ABI="x86" | |
fi | |
## sdcard_size | |
if [ "x${sdcard_size}" != "x" ]; then | |
SDCARD="${sdcard_size}" | |
else | |
SDCARD="60M" | |
fi | |
## port number to start searching for free ports for the console | |
if [ "x${console_port_start}" != "x" ]; then | |
console_port="${console_port_start}" | |
else | |
console_port="5554" | |
fi | |
## port number to start searching for free ports for the listener | |
if [ "x${listener_port_start}" != "x" ]; then | |
listener_port="${listener_port_start}" | |
else | |
listener_port="8000" | |
fi | |
## port number to start searching for free ports for socat | |
if [ "x${socat_port_start}" != "x" ]; then | |
socat_port="${socat_port_start}" | |
else | |
socat_port="9000" | |
fi | |
## set the hub_host | |
if [ "x${hub_host}" != "x" ]; then | |
HUB_HOST="${hub_host}" | |
else | |
HUB_HOST="localhost" | |
fi | |
## set the hub_port | |
if [ "x${hub_port}" != "x" ]; then | |
HUB_PORT="${hub_port}" | |
else | |
HUB_PORT="4444" | |
fi | |
## set the local ip | |
LOCAL_IP=`hostname -i` | |
# Funtions | |
# Create an array of free port numbers to use for the emulators | |
# Yes, this looks unnecessarily complex, but CONSOLE_PORT needs to | |
# be an even integer and can only be within a range of 5554-5584. | |
function findFreePorts { | |
k=0 | |
for (( i=0 ; i < $EMULATOR_COUNT; i++ )) | |
{ | |
while netstat -atwn | grep "^.*{console_port}.*:\*\s*LISTEN\s*$" | |
do | |
#Console Port should and can only be an even number | |
#Android allows only even numbers | |
console_port=$(( ${console_port} + 2 )) | |
echo PORT1 ${console_port} | |
done | |
ports[k]=${console_port} | |
k=$(( $k + 1 )) | |
while netstat -atwn | grep "^.*{listener_port}.*:\*\s*LISTEN\s*$" | |
do | |
listener_port=$(( ${listener_port} + 1 )) | |
echo PORT2 ${listener_port} | |
done | |
ports[k]=${listener_port} | |
k=$(( $k + 1 )) | |
while netstat -atwn | grep "^.*{socat_port}.*:\*\s*LISTEN\s*$" | |
do | |
socat_port=$(( ${socat_port} + 1 )) | |
echo PORT3 ${socat_port} | |
done | |
ports[k]=${socat_port} | |
k=$(( $k + 1 )) | |
#Console Port should and can only be an even number | |
#Android allows only even numbers | |
console_port=$(( ${console_port} + 2 )) | |
listener_port=$(( ${listener_port} + 1 )) | |
socat_port=$(( ${socat_port} + 1 )) | |
} | |
} | |
# create the AVD | |
function createAVD { | |
local CONSOLE_PORT=$1 | |
echo no | android -s create avd -n avd_$CONSOLE_PORT -t "$ANDROID_TARGET" -c $SDCARD -f -b $ANDROID_ABI | |
} | |
# start the AVD | |
# This starts the emulator | |
function startEmulator { | |
local CONSOLE_PORT=$1 | |
echo "[emulator-$CONSOLE_PORT] Starting emulator with avd avd_$CONSOLE_PORT and console port $CONSOLE_PORT" | |
emulator -avd avd_$CONSOLE_PORT -port $CONSOLE_PORT -no-boot-anim -noaudio -no-window & | |
# This waits for emulator to start up | |
echo "[emulator-$CONSOLE_PORT] Waiting for emulator to boot completely" | |
wait_for_boot_complete "getprop dev.bootcomplete" 1 | |
wait_for_boot_complete "getprop sys.boot_completed" 1 | |
wait_for_boot_complete "pm path android" package | |
} | |
# function to really, really check things are booted up | |
function wait_for_boot_complete { | |
local boot_property=$1 | |
local boot_property_test=$2 | |
echo "[emulator-$CONSOLE_PORT] Checking $boot_property..." | |
local result=`adb -s emulator-$CONSOLE_PORT shell $boot_property 2>/dev/null | grep "$boot_property_test"` | |
while [ -z $result ]; do | |
sleep 1 | |
result=`adb -s emulator-$CONSOLE_PORT shell $boot_property 2>/dev/null | grep "$boot_property_test"` | |
done | |
echo "[emulator-$CONSOLE_PORT] All boot properties succesful" | |
} | |
# Copy the APK in and start webdriver | |
function installWebdriverAPK { | |
local CONSOLE_PORT=$1 | |
echo "[emulator-$CONSOLE_PORT] Installing WebDriver apk" | |
adb -s emulator-$CONSOLE_PORT install $APK_DIR/android-server.apk | |
} | |
# Activating Webdriver | |
function activateWebdriver { | |
local CONSOLE_PORT=$1 | |
echo "[emulator-$CONSOLE_PORT] Getting out of home screen" | |
adb -s emulator-$CONSOLE_PORT shell input keyevent 82 | |
adb -s emulator-$CONSOLE_PORT shell input keyevent 4 | |
echo "[emulator-$CONSOLE_PORT] Activating WebDriver app" | |
adb -s emulator-$CONSOLE_PORT shell am start -a android.intent.action.MAIN -n org.openqa.selenium.android.app/.MainActivity | |
} | |
# set up port forwarding | |
function portForward { | |
local CONSOLE_PORT=$1 | |
local LISTENER_PORT=$2 | |
echo "[emulator-$CONSOLE_PORT] Setting up port forwarding" | |
adb -s emulator-$CONSOLE_PORT forward tcp:$LISTENER_PORT tcp:8080 | |
} | |
# start up socat | |
function start_socat { | |
local CONSOLE_PORT=$1 | |
local LISTENER_PORT=$2 | |
local SOCAT_PORT=$3 | |
echo "[emulator-$CONSOLE_PORT] Starting up socat on port $SOCAT_PORT" | |
socat TCP-LISTEN:$SOCAT_PORT,fork TCP:localhost:$LISTENER_PORT & | |
} | |
# register the node on the grid | |
function register_node { | |
local CONSOLE_PORT=$1 | |
local SOCAT_PORT=$2 | |
JSON="{'configuration': {'registerCycle': 5000, 'hub': 'http://<HUB_HOST>:<HUB_PORT>/grid/register', 'host': '<LOCAL_IP>', 'proxy': 'org.openqa.grid.selenium.proxy.DefaultRemoteProxy', 'maxSession': 1, 'port': <SOCAT_PORT>, 'hubPort': <HUB_PORT>, 'hubHost': '<HUB_HOST>', 'url': 'http://<LOCAL_IP>:<SOCAT_PORT>', 'remoteHost': 'http://<LOCAL_IP>:<SOCAT_PORT>', 'register': true, 'role': 'node'}, 'class': 'org.openqa.grid.common.RegistrationRequest', 'capabilities': [{'seleniumProtocol': 'WebDriver', 'platform': 'ANDROID', 'browserName': 'android', 'version': null, 'maxInstances': 1}]}" | |
JSON=${JSON//<HUB_HOST>/$HUB_HOST} | |
JSON=${JSON//<HUB_PORT>/$HUB_PORT} | |
JSON=${JSON//<LOCAL_IP>/$LOCAL_IP} | |
JSON=${JSON//<SOCAT_PORT>/$SOCAT_PORT} | |
echo "[emulator-$CONSOLE_PORT] json is: ${JSON}" | |
curl -X POST -d "${JSON}" http://$HUB_HOST:$HUB_PORT/grid/register | |
} | |
# create one emulator instance | |
function createOneEmulatorInstance { | |
local CONSOLE_PORT=$1 | |
local LISTENER_PORT=$2 | |
local SOCAT_PORT=$3 | |
createAVD $CONSOLE_PORT | |
startEmulator $CONSOLE_PORT | |
installWebdriverAPK $CONSOLE_PORT | |
activateWebdriver $CONSOLE_PORT | |
portForward $CONSOLE_PORT $LISTENER_PORT | |
start_socat $CONSOLE_PORT $LISTENER_PORT $SOCAT_PORT | |
register_node $CONSOLE_PORT $SOCAT_PORT | |
} | |
## The main function :) | |
function main { | |
# Get an array of free port numbers to use | |
findFreePorts | |
# Based on the port number found, create an instance of an emulator up to the EMULATOR_COUNT specified | |
for (( l=0, i=0 ; l < ${#ports[@]}, i < $EMULATOR_COUNT; i++, l=l+3 )) | |
{ | |
echo "ports for emulator $((i+1)): console=${ports[$l]}, listener=${ports[$l+1]}, socat=${ports[$l+2]}" | |
createOneEmulatorInstance ${ports[$l]} ${ports[$l+1]} ${ports[$l+2]} & | |
} | |
# Wait until those emulators are registered on the grid | |
# TODO: make this check an all-in-one comparison, not sequentially checking each IP as it does now. | |
# However, this won't really block anything more than a millisecond more than reality | |
for (( l=0, i=0 ; l < ${#ports[@]}, i < $EMULATOR_COUNT; i++, l=l+3 )) | |
{ | |
echo "[emulator-${ports[$l]}] testing for $LOCAL_IP:${ports[$l+2]} on grid $HUB_HOST:$HUB_PORT ..." | |
while [[ `curl -s http://$HUB_HOST:$HUB_PORT/grid/console` != *$LOCAL_IP:${ports[$l+2]}* ]] | |
do | |
sleep 1 | |
done | |
echo "" | |
echo "[emulator-${ports[$l]}] testing for $LOCAL_IP:${ports[$l+2]} on grid $HUB_HOST:$HUB_PORT successful!" | |
} | |
echo Emulator startup complete! | |
} | |
## Execute the script | |
main | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment