Refactored
This commit is contained in:
parent
26b99bd32b
commit
f4e16a3cf2
|
@ -46,8 +46,8 @@ ENV PATH="${PATH}:${JAVA_HOME}/bin"
|
|||
#=====================
|
||||
RUN apt-get install wget unzip libqt5webkit5 -y
|
||||
|
||||
RUN wget https://dl.google.com/android/repository/tools_r25.2.3-linux.zip
|
||||
RUN unzip tools_r25.2.3-linux.zip && rm tools_r25.2.3-linux.zip
|
||||
RUN wget https://dl.google.com/android/repository/tools_r25.2.3-linux.zip && \
|
||||
unzip tools_r25.2.3-linux.zip && rm tools_r25.2.3-linux.zip
|
||||
ENV ANDROID_HOME="/root"
|
||||
ENV PATH="${PATH}:${ANDROID_HOME}/tools"
|
||||
|
||||
|
@ -55,9 +55,8 @@ ENV PATH="${PATH}:${ANDROID_HOME}/tools"
|
|||
# Install Platform-tools, Build-tools
|
||||
# To see list of available packages: android list sdk
|
||||
#=====================================================
|
||||
RUN echo y | android update sdk --no-ui --filter 2,3
|
||||
ENV PATH="${PATH}:${ANDROID_HOME}/platform-tools"
|
||||
ENV PATH="${PATH}:${ANDROID_HOME}/build-tools"
|
||||
RUN echo y | android update sdk --no-ui --filter platform-tools,build-tools-25.0.2
|
||||
ENV PATH="${PATH}:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/build-tools"
|
||||
RUN mv ${ANDROID_HOME}/tools/emulator ${ANDROID_HOME}/tools/emulator.backup
|
||||
|
||||
#====================================
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import os
|
||||
|
||||
ROOT = '/root'
|
||||
ANDROID_PATH = os.getenv('ANDROID_HOME', '/root')
|
||||
WORKDIR = os.path.dirname(__file__)
|
||||
CONFIG_FILE = os.path.join(WORKDIR, 'nodeconfig.json')
|
||||
LOGGING_FILE = os.path.join(WORKDIR, 'logging.conf')
|
||||
|
|
106
src/android.py
106
src/android.py
|
@ -1,44 +1,37 @@
|
|||
import logging
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
logging.basicConfig()
|
||||
from src import ANDROID_PATH
|
||||
|
||||
logger = logging.getLogger('android')
|
||||
|
||||
# not using enum because need to install pip that will make docker image size bigger
|
||||
EMULATOR = 'emulator'
|
||||
TYPE_ARMEABI = 'armeabi'
|
||||
TYPE_X86 = 'x86'
|
||||
TYPE_X86_64 = 'x86_64'
|
||||
|
||||
API_LEVEL_ANDROID_5 = 21
|
||||
|
||||
|
||||
def get_available_sdk_packages():
|
||||
"""
|
||||
Get list of available sdk packages.
|
||||
|
||||
:return: List of available packages.
|
||||
:rtype: bytearray
|
||||
"""
|
||||
logger.info('List of Android SDK: ')
|
||||
output_str = subprocess.check_output('android list sdk'.split())
|
||||
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 # Get the last item that match with keyword
|
||||
return pos
|
||||
API_LEVELS = {
|
||||
'2.1': 7,
|
||||
'2.2': 8,
|
||||
'2.3.1': 9,
|
||||
'2.3.3': 1,
|
||||
'3.0': 11,
|
||||
'3.1': 12,
|
||||
'3.2': 13,
|
||||
'4.0': 14,
|
||||
'4.0.3': 15,
|
||||
'4.1.2': 16,
|
||||
'4.2.2': 17,
|
||||
'4.3.1': 18,
|
||||
'4.4.2': 19,
|
||||
'4.4W.2': 20,
|
||||
'5.0.1': 21,
|
||||
'5.1.1': 22,
|
||||
'6.0': 23,
|
||||
'7.0': 24,
|
||||
'7.1.1': 25
|
||||
}
|
||||
|
||||
|
||||
def get_api_level(android_version):
|
||||
|
@ -47,38 +40,25 @@ def get_api_level(android_version):
|
|||
|
||||
:param android_version: android version
|
||||
:type android_version: str
|
||||
:return: api version
|
||||
:rtype: str
|
||||
:return: api level
|
||||
:rtype: int
|
||||
"""
|
||||
api_version = None
|
||||
api_level = None
|
||||
|
||||
try:
|
||||
packages = get_available_sdk_packages()
|
||||
for key in sorted(API_LEVELS):
|
||||
if android_version in key:
|
||||
api_level = API_LEVELS.get(key)
|
||||
except TypeError as t_err:
|
||||
logger.error(t_err)
|
||||
|
||||
if packages:
|
||||
item_pos = get_item_position(android_version, packages)
|
||||
logger.info('Package in position: {pos}'.format(pos=item_pos))
|
||||
item = packages[item_pos]
|
||||
logger.info('Item: {item}'.format(item=item))
|
||||
|
||||
item_info = item.split('-')
|
||||
api_version = re.search('%s(.*)%s' % ('API', ','), item_info[1]).group(1).strip()
|
||||
logger.info('API level: {api}'.format(api=api_version))
|
||||
else:
|
||||
raise RuntimeError('List of packages is empty!')
|
||||
|
||||
except IndexError as i_err:
|
||||
logger.error(i_err)
|
||||
|
||||
return api_version
|
||||
return api_level
|
||||
|
||||
|
||||
def install_package(android_path, emulator_file, api_level, sys_img):
|
||||
def install_package(emulator_file, api_level, sys_img):
|
||||
"""
|
||||
Install sdk package.
|
||||
|
||||
:param android_path: location where android SDK is installed
|
||||
:type android_path: str
|
||||
:param emulator_file: emulator file that need to be link
|
||||
:type emulator_file: str
|
||||
:param api_level: api level
|
||||
|
@ -87,8 +67,8 @@ def install_package(android_path, emulator_file, api_level, sys_img):
|
|||
:type sys_img: str
|
||||
"""
|
||||
# Link emulator shortcut
|
||||
emu_file = os.path.join(android_path, 'tools', emulator_file)
|
||||
emu_target = os.path.join(android_path, 'tools', 'emulator')
|
||||
emu_file = os.path.join(ANDROID_PATH, 'tools', emulator_file)
|
||||
emu_target = os.path.join(ANDROID_PATH, 'tools', 'emulator')
|
||||
os.symlink(emu_file, emu_target)
|
||||
|
||||
# Install package based on given android version
|
||||
|
@ -96,16 +76,13 @@ def install_package(android_path, emulator_file, api_level, sys_img):
|
|||
api=api_level, sys_img=sys_img)
|
||||
logger.info('SDK package installation command: {install}'.format(install=cmd))
|
||||
titel = 'SDK package installation process'
|
||||
subprocess.check_call('xterm -T "{titel}" -n "{titel}" -e \"{cmd}\"'.format(
|
||||
titel=titel, cmd=cmd), shell=True)
|
||||
subprocess.check_call('xterm -T "{titel}" -n "{titel}" -e \"{cmd}\"'.format(titel=titel, cmd=cmd), shell=True)
|
||||
|
||||
|
||||
def create_avd(android_path, device, avd_name, api_level):
|
||||
def create_avd(device, avd_name, api_level):
|
||||
"""
|
||||
Create android virtual device.
|
||||
|
||||
:param android_path: location where android SDK is installed
|
||||
:type android_path: str
|
||||
:param device: name of device
|
||||
:type device: str
|
||||
:param avd_name: desire name
|
||||
|
@ -115,13 +92,13 @@ def create_avd(android_path, device, avd_name, api_level):
|
|||
"""
|
||||
# Create android emulator
|
||||
cmd = 'echo no | android create avd -f -n {name} -t android-{api}'.format(name=avd_name, api=api_level)
|
||||
if device != 'emulator':
|
||||
if device != EMULATOR:
|
||||
# Link emulator skins
|
||||
from src import ROOT
|
||||
skin_rsc_path = os.path.join(ROOT, 'devices', 'skins')
|
||||
logger.info('Skin ressource path: {rsc}'.format(rsc=skin_rsc_path))
|
||||
|
||||
skin_dst_path = os.path.join(android_path, 'platforms', 'android-{api}'.format(api=api_level), 'skins')
|
||||
skin_dst_path = os.path.join(ANDROID_PATH, 'platforms', 'android-{api}'.format(api=api_level), 'skins')
|
||||
logger.info('Skin destination path: {dst}'.format(dst=skin_dst_path))
|
||||
|
||||
for s in os.listdir(skin_rsc_path):
|
||||
|
@ -146,5 +123,4 @@ def create_avd(android_path, device, avd_name, api_level):
|
|||
|
||||
logger.info('AVD creation command: {cmd}'.format(cmd=cmd))
|
||||
titel = 'AVD creation process'
|
||||
subprocess.check_call('xterm -T "{titel}" -n "{titel}" -e \"{cmd}\"'.format(
|
||||
titel=titel, cmd=cmd), shell=True)
|
||||
subprocess.check_call('xterm -T "{titel}" -n "{titel}" -e \"{cmd}\"'.format(titel=titel, cmd=cmd), shell=True)
|
||||
|
|
|
@ -6,14 +6,14 @@ import subprocess
|
|||
logger = logging.getLogger('appium')
|
||||
|
||||
|
||||
def run(connect_to_grid, emulator_name, android_version):
|
||||
def run(connect_to_grid, avd_name, android_version):
|
||||
"""
|
||||
Run appium server.
|
||||
|
||||
:param connect_to_grid: option to connect with selenium grid
|
||||
:type connect_to_grid: bool
|
||||
:param emulator_name: name of emulator
|
||||
:type emulator_name: str
|
||||
:param avd_name: name of device
|
||||
:type avd_name: str
|
||||
:param android_version: android version
|
||||
:type android_version: str
|
||||
"""
|
||||
|
@ -25,14 +25,13 @@ def run(connect_to_grid, emulator_name, android_version):
|
|||
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))
|
||||
create_node_config(CONFIG_FILE, emulator_name, android_version,
|
||||
appium_host, appium_port, selenium_host, selenium_port)
|
||||
create_node_config(CONFIG_FILE, avd_name, android_version, appium_host, appium_port,
|
||||
selenium_host, selenium_port)
|
||||
cmd += ' --nodeconfig {file}'.format(file=CONFIG_FILE)
|
||||
except ValueError as v_err:
|
||||
logger.error(v_err)
|
||||
titel = 'avd name: {name}'.format(name=emulator_name)
|
||||
subprocess.check_call('xterm -T "{titel}" -n "{titel}" -e \"{cmd}\"'.format(
|
||||
titel=titel, cmd=cmd), shell=True)
|
||||
titel = 'avd name: {name}'.format(name=avd_name)
|
||||
subprocess.check_call('xterm -T "{titel}" -n "{titel}" -e \"{cmd}\"'.format(titel=titel, cmd=cmd), shell=True)
|
||||
|
||||
|
||||
def create_node_config(config_file, emulator_name, android_version, appium_host, appium_port,
|
||||
|
|
|
@ -11,25 +11,20 @@ def start():
|
|||
Installation of needed sdk package, creation of android emulator and execution of appium server.
|
||||
|
||||
"""
|
||||
# Android SDK path
|
||||
android_path = os.getenv('ANDROID_HOME', '/root')
|
||||
logger.info('Android path: {path}'.format(path=android_path))
|
||||
|
||||
# Emulator informations
|
||||
emu_type = os.getenv('EMULATOR_TYPE', android.TYPE_ARMEABI).lower()
|
||||
emu_type = android.TYPE_ARMEABI if emu_type not in [android.TYPE_ARMEABI, android.TYPE_X86] else \
|
||||
emu_type
|
||||
logger.info('Emulator type: {type}'.format(type=emu_type))
|
||||
emu_file = 'emulator64-x86' if emu_type == android.TYPE_X86 else 'emulator64-arm'
|
||||
logger.info('Emulator file: {file}'.format(file=emu_file))
|
||||
|
||||
# Device name
|
||||
device = os.getenv('DEVICE', 'Nexus 5')
|
||||
|
||||
# Android version
|
||||
android_version = os.getenv('ANDROID_VERSION', '4.2.2')
|
||||
android_version = os.getenv('ANDROID_VERSION', '5.0')
|
||||
logger.info('Android version: {version}'.format(version=android_version))
|
||||
|
||||
# Emulator type
|
||||
emu_type = os.getenv('EMULATOR_TYPE', android.TYPE_ARMEABI).lower()
|
||||
emu_type = android.TYPE_ARMEABI if emu_type not in [android.TYPE_ARMEABI, android.TYPE_X86] else emu_type
|
||||
logger.info('Emulator type: {type}'.format(type=emu_type))
|
||||
emu_file = 'emulator64-x86' if emu_type == android.TYPE_X86 else 'emulator64-arm'
|
||||
logger.info('Emulator file: {file}'.format(file=emu_file))
|
||||
|
||||
# Selenium grid connection
|
||||
connect_to_grid = str_to_bool(str(os.getenv('CONNECT_TO_GRID', False)))
|
||||
logger.info('Connect to selenium grid? {input}'.format(input=connect_to_grid))
|
||||
|
@ -38,21 +33,21 @@ def start():
|
|||
api_level = android.get_api_level(android_version)
|
||||
# Bug: cannot use skin for system image x86 with android version < 5.0
|
||||
if emu_type == android.TYPE_X86:
|
||||
if int(api_level) < android.API_LEVEL_ANDROID_5:
|
||||
if int(api_level) < android.get_api_level('5.0'):
|
||||
sys_img = android.TYPE_X86
|
||||
device = 'emulator'
|
||||
device = android.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, emu_file, api_level, sys_img)
|
||||
android.install_package(emu_file, api_level, sys_img)
|
||||
|
||||
# Create android virtual device
|
||||
logger.info('Device: {device}'.format(device=device))
|
||||
avd_name = '{device}_{version}'.format(device=device.replace(' ', '_').lower(), version=android_version)
|
||||
logger.info('AVD name: {avd}'.format(avd=avd_name))
|
||||
android.create_avd(android_path, device, avd_name, api_level)
|
||||
android.create_avd(device, avd_name, api_level)
|
||||
|
||||
# Run appium server
|
||||
appium.run(connect_to_grid, avd_name, android_version)
|
||||
|
|
|
@ -1,33 +1,20 @@
|
|||
"""Unit test for android.py."""
|
||||
from unittest import TestCase
|
||||
|
||||
import mock
|
||||
|
||||
from src import android
|
||||
|
||||
|
||||
@mock.patch('src.android.get_available_sdk_packages')
|
||||
class TestApiLevel(TestCase):
|
||||
"""Unit test class to test method get_api_level."""
|
||||
|
||||
def setUp(self):
|
||||
self.android_version = '4.2.2'
|
||||
|
||||
def test_get_api_level(self, mocked_packages):
|
||||
mocked_packages.return_value = ['9- SDK Platform Android 4.4.2, API 19, revision 4',
|
||||
'10- SDK Platform Android 4.3.1, API 18, revision 3',
|
||||
'11- SDK Platform Android 4.2.2, API 17, revision 3']
|
||||
api_level = android.get_api_level(self.android_version)
|
||||
self.assertEqual(api_level, '17')
|
||||
def test_get_api_level(self):
|
||||
api_level = android.get_api_level('4.2')
|
||||
self.assertEqual(api_level, 19)
|
||||
|
||||
def test_empty_packages(self, mocked_packages):
|
||||
mocked_packages.return_value = None
|
||||
with self.assertRaises(RuntimeError):
|
||||
android.get_api_level(self.android_version)
|
||||
|
||||
def test_index_error(self, mocked_packages):
|
||||
mocked_packages.return_value = ['9 SDK Platform Android 4.4.2, API 19, revision 4',
|
||||
'10 SDK Platform Android 4.3.1, API 18, revision 3',
|
||||
'11 SDK Platform Android 4.2.2, API 17, revision 3']
|
||||
android.get_api_level(self.android_version)
|
||||
self.assertRaises(IndexError)
|
||||
def test_wrong_type(self):
|
||||
api_level = android.get_api_level(4)
|
||||
self.assertRaises(TypeError)
|
||||
self.assertEqual(api_level, None)
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
"""Unit test for android.py."""
|
||||
from unittest import TestCase
|
||||
|
||||
import mock
|
||||
|
||||
from src import android
|
||||
|
||||
|
||||
class TestAvailablePackages(TestCase):
|
||||
"""Unit test class to test method get_available_sdk_packages."""
|
||||
|
||||
@mock.patch('subprocess.check_output')
|
||||
def test_valid_output(self, mocked_output):
|
||||
mocked_output.return_value = 'package 1 \n package 2'
|
||||
output = android.get_available_sdk_packages()
|
||||
self.assertEqual(['package 1', 'package 2'], output)
|
||||
|
||||
@mock.patch('subprocess.check_output')
|
||||
def test_without_line_break(self, mocked_output):
|
||||
mocked_output.return_value = 'package 1, package 2'
|
||||
output = android.get_available_sdk_packages()
|
||||
self.assertEqual(['package 1, package 2'], output)
|
||||
|
||||
@mock.patch('subprocess.check_output')
|
||||
def test_empty_string(self, mocked_output):
|
||||
mocked_output.return_value = None
|
||||
output = android.get_available_sdk_packages()
|
||||
self.assertEqual(None, output)
|
|
@ -12,7 +12,6 @@ class TestAvd(TestCase):
|
|||
"""Unit test class to test method create_avd."""
|
||||
|
||||
def setUp(self):
|
||||
self.android_path = '/root'
|
||||
self.avd_name = 'test_avd'
|
||||
self.api_level = 21
|
||||
|
||||
|
@ -22,7 +21,7 @@ class TestAvd(TestCase):
|
|||
self.assertFalse(mocked_list_dir.called)
|
||||
self.assertFalse(mocked_sys_link.called)
|
||||
self.assertFalse(mocked_suprocess.called)
|
||||
android.create_avd(self.android_path, 'Nexus 5', self.avd_name, self.api_level)
|
||||
android.create_avd('Nexus 5', self.avd_name, self.api_level)
|
||||
self.assertTrue(mocked_list_dir.called)
|
||||
self.assertTrue(mocked_sys_link.called)
|
||||
self.assertTrue(mocked_suprocess.called)
|
||||
|
@ -33,7 +32,7 @@ class TestAvd(TestCase):
|
|||
self.assertFalse(mocked_list_dir.called)
|
||||
self.assertFalse(mocked_sys_link.called)
|
||||
self.assertFalse(mocked_suprocess.called)
|
||||
android.create_avd(self.android_path, 'Samsung Galaxy S6', self.avd_name, self.api_level)
|
||||
android.create_avd('Samsung Galaxy S6', self.avd_name, self.api_level)
|
||||
self.assertTrue(mocked_list_dir.called)
|
||||
self.assertTrue(mocked_sys_link.called)
|
||||
self.assertTrue(mocked_suprocess.called)
|
||||
|
@ -44,5 +43,5 @@ class TestAvd(TestCase):
|
|||
self.assertFalse(mocked_list_dir.called)
|
||||
self.assertFalse(mocked_sys_link.called)
|
||||
self.assertFalse(mocked_suprocess.called)
|
||||
android.create_avd(self.android_path, 'emulator', self.avd_name, self.api_level)
|
||||
android.create_avd('emulator', self.avd_name, self.api_level)
|
||||
self.assertFalse(mocked_list_dir.called)
|
||||
|
|
|
@ -10,7 +10,6 @@ class TestInstallPackage(TestCase):
|
|||
"""Unit test class to test method install_package."""
|
||||
|
||||
def setUp(self):
|
||||
self.android_path = '/root'
|
||||
self.emulator_file = 'emulator64-arm'
|
||||
self.api_level = 21
|
||||
self.sys_img = 'armeabi-v7a'
|
||||
|
@ -20,6 +19,6 @@ class TestInstallPackage(TestCase):
|
|||
def test_package_installation(self, mocked_sys_link, mocked_suprocess):
|
||||
self.assertFalse(mocked_sys_link.called)
|
||||
self.assertFalse(mocked_suprocess.called)
|
||||
android.install_package(self.android_path, self.emulator_file, self.api_level, self.sys_img)
|
||||
android.install_package(self.emulator_file, self.api_level, self.sys_img)
|
||||
self.assertTrue(mocked_sys_link.called)
|
||||
self.assertTrue(mocked_suprocess.called)
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
"""Unit test for android.py."""
|
||||
from unittest import TestCase
|
||||
|
||||
from src import android
|
||||
|
||||
|
||||
class TestItemPosition(TestCase):
|
||||
"""Unit test class to test method get_item_position."""
|
||||
|
||||
def setUp(self):
|
||||
self.items = ['android 4.1', 'android 4.2.2', 'android 4.3', 'android 4.4', 'android 4.4.2']
|
||||
|
||||
def test_valid_params(self):
|
||||
keyword = '4.2'
|
||||
output = android.get_item_position(keyword, self.items)
|
||||
self.assertEqual(4, output)
|
||||
|
||||
def test_invalid_keyword(self):
|
||||
keyword = 'fake'
|
||||
output = android.get_item_position(keyword, self.items)
|
||||
self.assertEqual(0, output)
|
||||
|
||||
def test_empty_array(self):
|
||||
items = []
|
||||
keyword = '4.2'
|
||||
output = android.get_item_position(keyword, items)
|
||||
self.assertEqual(0, output)
|
Loading…
Reference in a new issue