Fixed issue with device / skin for android version < 5.0

This commit is contained in:
butomo1989 2017-03-07 16:24:14 +01:00
parent 032552a5e9
commit fdf936a3f3
4 changed files with 60 additions and 27 deletions

View file

@ -89,6 +89,9 @@ pass environment variable **CONNECT\_TO\_GRID=True** to connect docker-appium to
List of Devices List of Devices
--------------- ---------------
For **EMULATOR_TYPE=x86** and android version < 5.0 this feature will be not available.
Type | Device Name Type | Device Name
--- | --- --- | ---
Phone | Galaxy Nexus Phone | Galaxy Nexus

View file

@ -6,6 +6,13 @@ import subprocess
logging.basicConfig() logging.basicConfig()
logger = logging.getLogger('android') logger = logging.getLogger('android')
# not using enum because need to install pip that will make docker image size bigger
TYPE_ARMEABI = 'armeabi'
TYPE_X86 = 'x86'
TYPE_X86_64 = 'x86_64'
API_LEVEL_ANDROID_5 = 21
def get_api_level(android_version): def get_api_level(android_version):
""" """
@ -65,7 +72,7 @@ def install_package(android_path, emulator_file, api_level, sys_img):
titel=titel, cmd=cmd), shell=True) titel=titel, cmd=cmd), shell=True)
def create_avd(android_path, device, skin, avd_name, api_level): def create_avd(android_path, device, skin, avd_name, sys_img, api_level):
""" """
Create android virtual device. Create android virtual device.
@ -77,9 +84,15 @@ def create_avd(android_path, device, skin, avd_name, api_level):
:type skin: str :type skin: str
:param avd_name: desire name :param avd_name: desire name
:type avd_name: str :type avd_name: str
:param sys_img: system image
:type sys_img: str
:param api_level: api level :param api_level: api level
:type api_level: str :type api_level: str
""" """
# Bug: cannot use skin for system image x86 with android version < 5.0
if sys_img == TYPE_X86:
cmd = 'echo no | android create avd -f -n {name} -t android-{api}'.format(name=avd_name, api=api_level)
else:
# Link emulator skins # Link emulator skins
skins_rsc = os.path.join(android_path, 'skins') skins_rsc = os.path.join(android_path, 'skins')
skins_dst = os.path.join(android_path, 'platforms', 'android-{api}'.format(api=api_level), 'skins') skins_dst = os.path.join(android_path, 'platforms', 'android-{api}'.format(api=api_level), 'skins')
@ -90,6 +103,7 @@ def create_avd(android_path, device, skin, avd_name, api_level):
cmd = 'echo no | android create avd -f -n {name} -t android-{api}'.format(name=avd_name, api=api_level) cmd = 'echo no | android create avd -f -n {name} -t android-{api}'.format(name=avd_name, api=api_level)
if device and skin: if device and skin:
cmd += ' -d {device} -s {skin}'.format(device=device.replace(' ', '\ '), skin=skin) cmd += ' -d {device} -s {skin}'.format(device=device.replace(' ', '\ '), skin=skin)
logger.info('AVD creation command: {cmd}'.format(cmd=cmd)) logger.info('AVD creation command: {cmd}'.format(cmd=cmd))
titel = 'AVD creation process' titel = 'AVD creation process'
subprocess.check_call('xterm -T "{titel}" -n "{titel}" -e \"{cmd}\"'.format( subprocess.check_call('xterm -T "{titel}" -n "{titel}" -e \"{cmd}\"'.format(

View file

@ -5,10 +5,6 @@ from src import android, appium, log
logger = logging.getLogger('service') logger = logging.getLogger('service')
# not using enum because need to install pip that will make docker image size bigger
TYPE_ARMEABI = 'armeabi'
TYPE_X86 = 'x86'
def start(): def start():
""" """
@ -18,7 +14,7 @@ def start():
# Get all needed environment variables # Get all needed environment variables
android_path = os.getenv('ANDROID_HOME', '/root') android_path = os.getenv('ANDROID_HOME', '/root')
logger.info('Android path: {path}'.format(path=android_path)) logger.info('Android path: {path}'.format(path=android_path))
emulator_type = os.getenv('EMULATOR_TYPE', TYPE_ARMEABI).lower() emulator_type = os.getenv('EMULATOR_TYPE', android.TYPE_ARMEABI).lower()
logger.info('Emulator type: {type}'.format(type=emulator_type)) logger.info('Emulator type: {type}'.format(type=emulator_type))
android_version = os.getenv('ANDROID_VERSION', '4.2.2') android_version = os.getenv('ANDROID_VERSION', '4.2.2')
logger.info('Android version: {version}'.format(version=android_version)) logger.info('Android version: {version}'.format(version=android_version))
@ -26,22 +22,31 @@ def start():
logger.info('Connect to selenium grid? {input}'.format(input=connect_to_grid)) logger.info('Connect to selenium grid? {input}'.format(input=connect_to_grid))
# Install needed sdk packages # Install needed sdk packages
emulator_type = TYPE_ARMEABI if emulator_type not in [TYPE_ARMEABI, TYPE_X86] else emulator_type emulator_type = android.TYPE_ARMEABI if emulator_type not in [android.TYPE_ARMEABI, android.TYPE_X86] else \
emulator_file = 'emulator64-x86' if emulator_type == TYPE_X86 else 'emulator64-arm' emulator_type
emulator_file = 'emulator64-x86' if emulator_type == android.TYPE_X86 else 'emulator64-arm'
logger.info('Emulator file: {file}'.format(file=emulator_file)) logger.info('Emulator file: {file}'.format(file=emulator_file))
api_level = android.get_api_level(android_version) api_level = android.get_api_level(android_version)
sys_img = 'x86_64' if emulator_type == TYPE_X86 else 'armeabi-v7a'
logger.info('System image: {sys_img}'.format(sys_img=sys_img))
android.install_package(android_path, emulator_file, api_level, sys_img)
# Create android virtual device
device_name = os.getenv('DEVICE', 'Nexus 5') device_name = os.getenv('DEVICE', 'Nexus 5')
logger.info('Device: {device}'.format(device=device_name)) logger.info('Device: {device}'.format(device=device_name))
skin_name = device_name.replace(' ', '_').lower() skin_name = device_name.replace(' ', '_').lower()
logger.info('Skin: {skin}'.format(skin=skin_name)) logger.info('Skin: {skin}'.format(skin=skin_name))
if emulator_type == android.TYPE_X86:
if int(api_level) < android.API_LEVEL_ANDROID_5:
sys_img = android.TYPE_X86
skin_name = 'emulator'
else:
sys_img = android.TYPE_X86_64
else:
sys_img = '{type}-v7a'.format(type=android.TYPE_ARMEABI)
logger.info('System image: {sys_img}'.format(sys_img=sys_img))
android.install_package(android_path, emulator_file, api_level, sys_img)
# Create android virtual device
avd_name = '{device}_{version}'.format(device=skin_name, version=android_version) avd_name = '{device}_{version}'.format(device=skin_name, version=android_version)
logger.info('AVD name: {avd}'.format(avd=avd_name)) logger.info('AVD name: {avd}'.format(avd=avd_name))
android.create_avd(android_path, device_name, skin_name, avd_name, api_level) android.create_avd(android_path, device_name, skin_name, avd_name, sys_img, api_level)
# Run appium server # Run appium server
appium.run(connect_to_grid, avd_name, android_version) appium.run(connect_to_grid, avd_name, android_version)

View file

@ -6,6 +6,8 @@ import mock
from src import android from src import android
@mock.patch('os.symlink')
@mock.patch('subprocess.check_call')
class TestAvd(TestCase): class TestAvd(TestCase):
"""Unit test class to test method create_avd.""" """Unit test class to test method create_avd."""
@ -16,15 +18,24 @@ class TestAvd(TestCase):
self.avd_name = 'nexus_5_5.0' self.avd_name = 'nexus_5_5.0'
self.api_level = 21 self.api_level = 21
@mock.patch('os.symlink') def test_avd_creation_x86_64(self, mocked_sys_link, mocked_suprocess):
@mock.patch('subprocess.check_call')
def test_avd_creation(self, mocked_sys_link, mocked_suprocess):
with mock.patch('os.listdir') as mocked_list_dir: with mock.patch('os.listdir') as mocked_list_dir:
mocked_list_dir.return_value = ['file1', 'file2'] mocked_list_dir.return_value = ['file1', 'file2']
self.assertFalse(mocked_list_dir.called) self.assertFalse(mocked_list_dir.called)
self.assertFalse(mocked_sys_link.called) self.assertFalse(mocked_sys_link.called)
self.assertFalse(mocked_suprocess.called) self.assertFalse(mocked_suprocess.called)
android.create_avd(self.android_path, self.device, self.skin, self.avd_name, self.api_level) android.create_avd(self.android_path, self.device, self.skin, self.avd_name, android.TYPE_X86_64,
self.api_level)
self.assertTrue(mocked_list_dir.called) self.assertTrue(mocked_list_dir.called)
self.assertTrue(mocked_sys_link.called) self.assertTrue(mocked_sys_link.called)
self.assertTrue(mocked_suprocess.called) self.assertTrue(mocked_suprocess.called)
def test_avd_creation_x86(self, mocked_sys_link, mocked_suprocess):
with mock.patch('os.listdir') as mocked_list_dir:
mocked_list_dir.return_value = ['file1', 'file2']
self.assertFalse(mocked_list_dir.called)
self.assertFalse(mocked_sys_link.called)
self.assertFalse(mocked_suprocess.called)
android.create_avd(self.android_path, self.device, self.skin, self.avd_name, android.TYPE_X86,
self.api_level)
self.assertFalse(mocked_list_dir.called)