162 lines
5.4 KiB
Python
162 lines
5.4 KiB
Python
import logging
|
|
import os
|
|
import re
|
|
import subprocess
|
|
|
|
import appium
|
|
|
|
from service import CONFIG_FILE
|
|
|
|
logging.basicConfig()
|
|
logger = logging.getLogger('main')
|
|
|
|
# not using enum because need to install pip that will make docker image size bigger
|
|
TYPE_ARMEABI = 'armeabi'
|
|
TYPE_X86 = 'x86'
|
|
|
|
|
|
def run():
|
|
"""
|
|
Start noVNC, installation of needed android SDK packages and Appium server.
|
|
|
|
"""
|
|
# Get android version package
|
|
android_version = os.getenv('ANDROID_VERSION', '4.2.2')
|
|
emulator_name = 'emulator_{version}'.format(version=android_version)
|
|
os.environ['EMULATOR_NAME'] = emulator_name
|
|
|
|
# Get emulator type
|
|
types = [TYPE_ARMEABI, TYPE_X86]
|
|
emulator_type = os.getenv('EMULATOR_TYPE', TYPE_ARMEABI).lower()
|
|
emulator_type = TYPE_ARMEABI if emulator_type not in types else emulator_type
|
|
|
|
# Link emulator shortcut
|
|
subprocess.check_call('ln -s $ANDROID_HOME/tools/{shortcut_file} $ANDROID_HOME/tools/emulator'.format(
|
|
shortcut_file='emulator64-x86' if emulator_type == TYPE_X86 else 'emulator64-arm'), shell=True)
|
|
|
|
# Option to connect with selenium server
|
|
connect_to_grid = str_to_bool(str(os.getenv('CONNECT_TO_GRID', False)))
|
|
logger.info('Connect with selenium grid? {input}'.format(input=connect_to_grid))
|
|
appium_cmd = 'appium'
|
|
if connect_to_grid:
|
|
try:
|
|
appium_host = os.getenv('APPIUM_HOST', '127.0.0.1')
|
|
appium_port = int(os.getenv('APPIUM_PORT', 4723))
|
|
selenium_host = os.getenv('SELENIUM_HOST', '172.17.0.1')
|
|
selenium_port = int(os.getenv('SELENIUM_PORT', 4444))
|
|
appium.create_node_config(CONFIG_FILE, emulator_name, android_version,
|
|
appium_host, appium_port, selenium_host, selenium_port)
|
|
appium_cmd += ' --nodeconfig {file}'.format(file=CONFIG_FILE)
|
|
except ValueError as v_err:
|
|
logger.error(v_err)
|
|
|
|
# Start installation of android packages, emulator creation and appium in a terminal
|
|
android_cmd = get_android_bash_commands(android_version, emulator_type)
|
|
if android_cmd:
|
|
cmd = 'xterm -T "Android-Appium" -n "Android-Appium" -e \"{android} && ' \
|
|
'/bin/echo $EMULATOR_NAME && {appium}\"'.format(android=android_cmd, appium=appium_cmd)
|
|
else:
|
|
logger.warning('There is no android packages installed!')
|
|
cmd = 'xterm -e \"{appium}\"'.format(appium=appium_cmd)
|
|
subprocess.check_call(cmd, shell=True)
|
|
|
|
|
|
def get_available_sdk_packages():
|
|
"""
|
|
Get list of available sdk packages.
|
|
|
|
:return: List of available packages.
|
|
:rtype: bytearray
|
|
"""
|
|
cmd = ['android', 'list', 'sdk']
|
|
output_str = subprocess.check_output(cmd)
|
|
logger.info('List of Android SDK: ')
|
|
logger.info(output_str)
|
|
return [output.strip() for output in output_str.split('\n')] if output_str else None
|
|
|
|
|
|
def get_item_position(keyword, items):
|
|
"""
|
|
Get position of item in array by given keyword.
|
|
|
|
:return: item position
|
|
:rtype: int
|
|
"""
|
|
pos = 0
|
|
for p, v in enumerate(items):
|
|
if keyword in v:
|
|
pos = p
|
|
break # Get the first item that match with keyword
|
|
return pos
|
|
|
|
|
|
def get_android_bash_commands(android_version, emulator_type):
|
|
"""
|
|
Get bash commands to install given android version and to create android emulator based on given type.
|
|
|
|
To see list of available targets: android list targets
|
|
To see list to avd: android list avd
|
|
|
|
:param android_version: android version
|
|
:type android_version: str
|
|
:param emulator_type: emulator type
|
|
:type emulator_type: str
|
|
:return: bash commands
|
|
:rtype: bytearray
|
|
"""
|
|
bash_command = None
|
|
|
|
try:
|
|
packages = get_available_sdk_packages()
|
|
|
|
if packages:
|
|
item_pos = get_item_position(android_version, packages)
|
|
logger.info('item position: {pos}'.format(pos=item_pos))
|
|
item = packages[item_pos]
|
|
|
|
item_info = item.split('-')
|
|
package_number = item_info[0]
|
|
api_version = re.search('%s(.*)%s' % ('API', ','), item_info[1]).group(1).strip()
|
|
logger.info(
|
|
'Package number: {number}, API version: {version}'.format(number=package_number, version=api_version))
|
|
|
|
commands = []
|
|
|
|
# Command to install SDK package
|
|
commands.append('echo y | android update sdk --no-ui --filter {number}'.format(number=package_number))
|
|
|
|
# Command to install system image and create android emulator
|
|
sys_img = 'x86' if emulator_type == TYPE_X86 else 'armeabi-v7a'
|
|
commands.append('echo y | android update sdk --no-ui -a --filter sys-img-{sys_img}-android-{api}'.format(
|
|
sys_img=sys_img, api=api_version))
|
|
commands.append(
|
|
'echo no | android create avd -f -n emulator_{version} -t android-{api} --abi {sys_img}'.format(
|
|
version=android_version, api=api_version, sys_img=sys_img))
|
|
|
|
# Join all commands in one str for xterm
|
|
bash_command = ' && '.join(commands)
|
|
else:
|
|
raise RuntimeError('Packages is empty!')
|
|
|
|
except IndexError as i_err:
|
|
logger.error(i_err)
|
|
|
|
return bash_command
|
|
|
|
|
|
def str_to_bool(str):
|
|
"""
|
|
Convert string to boolean.
|
|
|
|
:param str: given string
|
|
:type str: str
|
|
:return: converted string
|
|
:rtype: bool
|
|
"""
|
|
return str.lower() in ('yes', 'true', 't', '1')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
logger.setLevel(logging.INFO)
|
|
run()
|