From fdf936a3f3642cdf37a7b62dfedb623085745754 Mon Sep 17 00:00:00 2001 From: butomo1989 Date: Tue, 7 Mar 2017 16:24:14 +0100 Subject: [PATCH] Fixed issue with device / skin for android version < 5.0 --- README.md | 3 +++ src/android.py | 34 ++++++++++++++++++++-------- src/service.py | 31 ++++++++++++++----------- src/tests/android/test_create_avd.py | 19 ++++++++++++---- 4 files changed, 60 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 015e8f4..3754c9a 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,9 @@ pass environment variable **CONNECT\_TO\_GRID=True** to connect docker-appium to List of Devices --------------- + +For **EMULATOR_TYPE=x86** and android version < 5.0 this feature will be not available. + Type | Device Name --- | --- Phone | Galaxy Nexus diff --git a/src/android.py b/src/android.py index 0d9af31..6f1ef0f 100644 --- a/src/android.py +++ b/src/android.py @@ -6,6 +6,13 @@ import subprocess logging.basicConfig() 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): """ @@ -65,7 +72,7 @@ def install_package(android_path, emulator_file, api_level, sys_img): 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. @@ -77,19 +84,26 @@ def create_avd(android_path, device, skin, avd_name, api_level): :type skin: str :param avd_name: desire name :type avd_name: str + :param sys_img: system image + :type sys_img: str :param api_level: api level :type api_level: str """ - # Link emulator skins - skins_rsc = os.path.join(android_path, 'skins') - skins_dst = os.path.join(android_path, 'platforms', 'android-{api}'.format(api=api_level), 'skins') - for skin_file in os.listdir(skins_rsc): - os.symlink(os.path.join(skins_rsc, skin_file), os.path.join(skins_dst, skin_file)) + # 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 + skins_rsc = os.path.join(android_path, 'skins') + skins_dst = os.path.join(android_path, 'platforms', 'android-{api}'.format(api=api_level), 'skins') + for skin_file in os.listdir(skins_rsc): + os.symlink(os.path.join(skins_rsc, skin_file), os.path.join(skins_dst, skin_file)) + + # Create android emulator + cmd = 'echo no | android create avd -f -n {name} -t android-{api}'.format(name=avd_name, api=api_level) + if device and skin: + cmd += ' -d {device} -s {skin}'.format(device=device.replace(' ', '\ '), skin=skin) - # Create android emulator - cmd = 'echo no | android create avd -f -n {name} -t android-{api}'.format(name=avd_name, api=api_level) - if device and skin: - cmd += ' -d {device} -s {skin}'.format(device=device.replace(' ', '\ '), skin=skin) logger.info('AVD creation command: {cmd}'.format(cmd=cmd)) titel = 'AVD creation process' subprocess.check_call('xterm -T "{titel}" -n "{titel}" -e \"{cmd}\"'.format( diff --git a/src/service.py b/src/service.py index 578036b..5f6413d 100644 --- a/src/service.py +++ b/src/service.py @@ -5,10 +5,6 @@ from src import android, appium, log 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(): """ @@ -18,7 +14,7 @@ def start(): # Get all needed environment variables android_path = os.getenv('ANDROID_HOME', '/root') 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)) android_version = os.getenv('ANDROID_VERSION', '4.2.2') 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)) # Install needed sdk packages - emulator_type = TYPE_ARMEABI if emulator_type not in [TYPE_ARMEABI, TYPE_X86] else emulator_type - emulator_file = 'emulator64-x86' if emulator_type == TYPE_X86 else 'emulator64-arm' + emulator_type = android.TYPE_ARMEABI if emulator_type not in [android.TYPE_ARMEABI, android.TYPE_X86] else \ + emulator_type + emulator_file = 'emulator64-x86' if emulator_type == android.TYPE_X86 else 'emulator64-arm' logger.info('Emulator file: {file}'.format(file=emulator_file)) 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') logger.info('Device: {device}'.format(device=device_name)) skin_name = device_name.replace(' ', '_').lower() 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) 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 appium.run(connect_to_grid, avd_name, android_version) diff --git a/src/tests/android/test_create_avd.py b/src/tests/android/test_create_avd.py index 7678b0c..0e13422 100644 --- a/src/tests/android/test_create_avd.py +++ b/src/tests/android/test_create_avd.py @@ -6,6 +6,8 @@ import mock from src import android +@mock.patch('os.symlink') +@mock.patch('subprocess.check_call') class TestAvd(TestCase): """Unit test class to test method create_avd.""" @@ -16,15 +18,24 @@ class TestAvd(TestCase): self.avd_name = 'nexus_5_5.0' self.api_level = 21 - @mock.patch('os.symlink') - @mock.patch('subprocess.check_call') - def test_avd_creation(self, mocked_sys_link, mocked_suprocess): + def test_avd_creation_x86_64(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, 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_sys_link.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)