support noVNC
This commit is contained in:
parent
08b0e65216
commit
7785e56a2a
71
Dockerfile
71
Dockerfile
|
@ -1,24 +1,44 @@
|
||||||
FROM ubuntu:16.04
|
FROM ubuntu:14.04
|
||||||
|
|
||||||
#=======================
|
#=======================
|
||||||
# General Configuration
|
# General Configuration
|
||||||
#=======================
|
#=======================
|
||||||
|
ENV DEBIAN_FRONTEND noninteractive
|
||||||
RUN apt-get update && apt-get upgrade -y
|
RUN apt-get update && apt-get upgrade -y
|
||||||
RUN apt-get install wget -y
|
|
||||||
|
#=====================================
|
||||||
|
# Install virtual display framebuffer
|
||||||
|
#=====================================
|
||||||
|
RUN apt-get install Xvfb x11vnc -y
|
||||||
|
|
||||||
|
#================================================
|
||||||
|
# Install Windows Manager, Debian Menu and Numpy
|
||||||
|
# https://github.com/novnc/websockify/issues/77
|
||||||
|
#================================================
|
||||||
|
RUN apt-get install openbox menu python-numpy -y
|
||||||
|
|
||||||
|
#======================
|
||||||
|
# Clone noVNC projects
|
||||||
|
#======================
|
||||||
|
RUN apt-get install git -y
|
||||||
|
WORKDIR /root
|
||||||
|
RUN git clone https://github.com/kanaka/noVNC.git && \
|
||||||
|
cd noVNC/utils && git clone https://github.com/kanaka/websockify websockify
|
||||||
|
|
||||||
#==============
|
#==============
|
||||||
# Install Java
|
# Install Java
|
||||||
#==============
|
#==============
|
||||||
RUN apt-get install openjdk-8-jdk -y
|
RUN apt-get install openjdk-7-jdk -y
|
||||||
ENV JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64/jre"
|
ENV JAVA_HOME="/usr/lib/jvm/java-7-openjdk-amd64/jre"
|
||||||
ENV PATH="${PATH}:${JAVA_HOME}/bin"
|
ENV PATH="${PATH}:${JAVA_HOME}/bin"
|
||||||
|
|
||||||
#=====================
|
#=====================
|
||||||
# Install Android SDK
|
# Install Android SDK
|
||||||
#=====================
|
#=====================
|
||||||
|
RUN apt-get install wget -y
|
||||||
RUN wget http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
|
RUN wget http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
|
||||||
RUN tar -xvzf android-sdk_r24.4.1-linux.tgz
|
RUN tar -xvzf android-sdk_r24.4.1-linux.tgz && rm android-sdk_r24.4.1-linux.tgz
|
||||||
ENV ANDROID_HOME="/android-sdk-linux"
|
ENV ANDROID_HOME="/root/android-sdk-linux"
|
||||||
ENV PATH="${PATH}:${ANDROID_HOME}/tools"
|
ENV PATH="${PATH}:${ANDROID_HOME}/tools"
|
||||||
|
|
||||||
#=====================================================
|
#=====================================================
|
||||||
|
@ -28,26 +48,33 @@ ENV PATH="${PATH}:${ANDROID_HOME}/tools"
|
||||||
RUN echo y | android update sdk --no-ui --filter 2,3
|
RUN echo y | android update sdk --no-ui --filter 2,3
|
||||||
ENV PATH="${PATH}:${ANDROID_HOME}/platform-tools"
|
ENV PATH="${PATH}:${ANDROID_HOME}/platform-tools"
|
||||||
ENV PATH="${PATH}:${ANDROID_HOME}/build-tools"
|
ENV PATH="${PATH}:${ANDROID_HOME}/build-tools"
|
||||||
|
RUN mv ${ANDROID_HOME}/tools/emulator ${ANDROID_HOME}/tools/emulator.backup
|
||||||
|
RUN ln -s ${ANDROID_HOME}/tools/emulator64-arm ${ANDROID_HOME}/tools/emulator
|
||||||
|
|
||||||
#==================================================
|
#====================================
|
||||||
# Fix issue regarding 64bit while running emulator
|
# Install latest nodejs, npm, appium
|
||||||
#==================================================
|
#====================================
|
||||||
RUN dpkg --add-architecture i386
|
RUN apt-get install curl -y
|
||||||
RUN apt-get update
|
RUN curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
|
||||||
RUN apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 -y
|
RUN apt-get install nodejs -y
|
||||||
ENV ANDROID_EMULATOR_FORCE_32BIT=true
|
|
||||||
RUN adb start-server
|
|
||||||
|
|
||||||
#============================================
|
|
||||||
# Install nodejs, npm, appium, appium-doctor
|
|
||||||
#============================================
|
|
||||||
RUN apt-get install npm nodejs-legacy -y
|
|
||||||
ENV APPIUM_VERSION 1.6.3
|
ENV APPIUM_VERSION 1.6.3
|
||||||
RUN npm install -g appium@$APPIUM_VERSION
|
RUN npm install -g appium@$APPIUM_VERSION
|
||||||
|
|
||||||
|
#======================
|
||||||
|
# noVNC Configurations
|
||||||
|
#======================
|
||||||
|
ENV DISPLAY=:0 \
|
||||||
|
SCREEN=0 \
|
||||||
|
SCREEN_WIDTH=1600 \
|
||||||
|
SCREEN_HEIGHT=900 \
|
||||||
|
SCREEN_DEPTH=16 \
|
||||||
|
LOCAL_PORT=5900 \
|
||||||
|
TARGET_PORT=6080 \
|
||||||
|
TIMEOUT=1
|
||||||
|
RUN ln -s noVNC/vnc_auto.html noVNC/index.html
|
||||||
|
|
||||||
#===================
|
#===================
|
||||||
# Run docker-appium
|
# Run docker-appium
|
||||||
#===================
|
#===================
|
||||||
COPY service /service
|
COPY service /root/service
|
||||||
WORKDIR /service
|
CMD python -m service.start
|
||||||
CMD python start.py
|
|
||||||
|
|
|
@ -9,18 +9,27 @@ logger = logging.getLogger('android_appium')
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
"""
|
"""
|
||||||
Run Android emulator and Appium server.
|
Start noVNC, installation of needed android SDK packages and Appium server.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
android_version = os.getenv('ANDROID_VERSION', '4.2.2')
|
android_version = os.getenv('ANDROID_VERSION', '4.2.2')
|
||||||
create_android_emulator(android_version)
|
os.environ['emulator_name'] = 'emulator_{version}'.format(version=android_version)
|
||||||
|
|
||||||
emulator_name = 'emulator_{version}'.format(version=android_version)
|
# Start Xvfb
|
||||||
|
subprocess.check_call('Xvfb ${DISPLAY} -screen ${SCREEN} ${SCREEN_WIDTH}x${SCREEN_HEIGHT}x${SCREEN_DEPTH} & '
|
||||||
|
'sleep ${TIMEOUT}', shell=True)
|
||||||
|
|
||||||
logger.info('android emulator name: {name} '.format(name=emulator_name))
|
# Start noVNC, installation of packages and appium
|
||||||
# TODO: check android emulator is ready to use
|
vnc_cmd = 'openbox-session & x11vnc -display ${DISPLAY} -nopw -ncache 10 -forever & ' \
|
||||||
cmd_run = 'emulator -avd {name} -no-audio -no-window & appium'.format(name=emulator_name)
|
'./noVNC/utils/launch.sh --vnc localhost:${LOCAL_PORT} --listen ${TARGET_PORT}'
|
||||||
subprocess.check_call(cmd_run, shell=True)
|
android_cmd = get_android_bash_commands(android_version)
|
||||||
|
if android_cmd:
|
||||||
|
cmd = '({vnc}) & (xterm -T "Android-Appium" -n "Android-Appium" -e \"{android} && ' \
|
||||||
|
'/bin/echo $emulator_name && appium\")'.format(vnc=vnc_cmd, android=android_cmd)
|
||||||
|
else:
|
||||||
|
logger.warning('There is no android packages installed!')
|
||||||
|
cmd = '({vnc}) & (xterm -e \"appium\")'.format(vnc=vnc_cmd)
|
||||||
|
subprocess.check_call(cmd, shell=True)
|
||||||
|
|
||||||
|
|
||||||
def get_available_sdk_packages():
|
def get_available_sdk_packages():
|
||||||
|
@ -30,12 +39,10 @@ def get_available_sdk_packages():
|
||||||
:return: List of available packages.
|
:return: List of available packages.
|
||||||
:rtype: bytearray
|
:rtype: bytearray
|
||||||
"""
|
"""
|
||||||
logger.info('List of Android SDK: ')
|
|
||||||
cmd = ['android', 'list', 'sdk']
|
cmd = ['android', 'list', 'sdk']
|
||||||
|
|
||||||
output_str = subprocess.check_output(cmd)
|
output_str = subprocess.check_output(cmd)
|
||||||
|
logger.info('List of Android SDK: ')
|
||||||
logger.info(output_str)
|
logger.info(output_str)
|
||||||
|
|
||||||
return [output.strip() for output in output_str.split('\n')] if output_str else None
|
return [output.strip() for output in output_str.split('\n')] if output_str else None
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,17 +61,20 @@ def get_item_position(keyword, items):
|
||||||
return pos
|
return pos
|
||||||
|
|
||||||
|
|
||||||
def create_android_emulator(android_version):
|
def get_android_bash_commands(android_version):
|
||||||
"""
|
"""
|
||||||
Create android emulator based on given android version.
|
Get bash commands to install given android version and to create android emulator.
|
||||||
|
|
||||||
It include installation of sdk package and its armeabi v7a.
|
|
||||||
To see list of available targets: android list targets
|
To see list of available targets: android list targets
|
||||||
To see list to avd: android list avd
|
To see list to avd: android list avd
|
||||||
|
|
||||||
:param android_version: android version
|
:param android_version: android version
|
||||||
:type android_version: str
|
:type android_version: str
|
||||||
|
:return: bash commands
|
||||||
|
:rtype: bytearray
|
||||||
"""
|
"""
|
||||||
|
bash_command = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
packages = get_available_sdk_packages()
|
packages = get_available_sdk_packages()
|
||||||
|
|
||||||
|
@ -79,31 +89,29 @@ def create_android_emulator(android_version):
|
||||||
logger.info(
|
logger.info(
|
||||||
'Package number: {number}, API version: {version}'.format(number=package_number, version=api_version))
|
'Package number: {number}, API version: {version}'.format(number=package_number, version=api_version))
|
||||||
|
|
||||||
# Install SDK package
|
commands = []
|
||||||
logger.info('Installing SDK package...')
|
# Command to install SDK package
|
||||||
cmd_sdk = 'echo y | android update sdk --no-ui --filter {number}'.format(number=package_number)
|
commands.append('echo y | android update sdk --no-ui --filter {number}'.format(number=package_number))
|
||||||
subprocess.check_call(cmd_sdk, shell=True)
|
|
||||||
logger.info('Installation completed')
|
|
||||||
|
|
||||||
# Install armeabi v7a
|
# Command to install armeabi v7a
|
||||||
logger.info('Installing its armeabi...')
|
commands.append('echo y | android update sdk --no-ui -a --filter sys-img-armeabi-v7a-android-{api}'.format(
|
||||||
cmd_arm = 'echo y | android update sdk --no-ui -a --filter sys-img-armeabi-v7a-android-{api}'.format(
|
api=api_version))
|
||||||
api=api_version)
|
|
||||||
subprocess.check_call(cmd_arm, shell=True)
|
|
||||||
logger.info('Installation completed')
|
|
||||||
|
|
||||||
# Create android emulator
|
# Command to create android emulator
|
||||||
logger.info('Creating android emulator...')
|
commands.append(
|
||||||
cmd_emu = 'echo no | android create avd -f -n emulator_{version} -t android-{api} --abi armeabi-v7a'.format(
|
'echo no | android create avd -f -n emulator_{version} -t android-{api} --abi armeabi-v7a'.format(
|
||||||
version=android_version, api=api_version)
|
version=android_version, api=api_version))
|
||||||
subprocess.check_call(cmd_emu, shell=True)
|
|
||||||
logger.info('Android emulator is created')
|
# Join all commands in one str for xterm
|
||||||
|
bash_command = ' && '.join(commands)
|
||||||
else:
|
else:
|
||||||
raise RuntimeError('Packages is empty!')
|
raise RuntimeError('Packages is empty!')
|
||||||
|
|
||||||
except IndexError as i_err:
|
except IndexError as i_err:
|
||||||
logger.error(i_err)
|
logger.error(i_err)
|
||||||
|
|
||||||
|
return bash_command
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
logger.setLevel(logging.INFO)
|
logger.setLevel(logging.INFO)
|
||||||
|
|
|
@ -9,11 +9,22 @@ from service import start
|
||||||
class TestService(TestCase):
|
class TestService(TestCase):
|
||||||
"""Unit test class to test method run."""
|
"""Unit test class to test method run."""
|
||||||
|
|
||||||
@mock.patch('service.start.create_android_emulator')
|
@mock.patch('service.start.get_android_bash_commands')
|
||||||
@mock.patch('subprocess.check_call')
|
@mock.patch('subprocess.check_call')
|
||||||
def test_service(self, mocked_creation, mocked_subprocess):
|
def test_service(self, mocked_bash_cmd, mocked_subprocess):
|
||||||
self.assertFalse(mocked_creation.called)
|
self.assertFalse(mocked_bash_cmd.called)
|
||||||
self.assertFalse(mocked_subprocess.called)
|
self.assertFalse(mocked_subprocess.called)
|
||||||
start.run()
|
start.run()
|
||||||
self.assertTrue(mocked_creation.called)
|
self.assertTrue(mocked_bash_cmd.called)
|
||||||
self.assertTrue(mocked_subprocess.called)
|
self.assertTrue(mocked_subprocess.called)
|
||||||
|
|
||||||
|
@mock.patch('service.start.get_android_bash_commands')
|
||||||
|
@mock.patch('subprocess.check_call')
|
||||||
|
@mock.patch('service.start.logger.warning')
|
||||||
|
def test_empty_android_cmd(self, mocked_bash_cmd, mocked_subprocess, mocked_logger_warning):
|
||||||
|
mocked_bash_cmd.return_value = None
|
||||||
|
self.assertFalse(mocked_subprocess.called)
|
||||||
|
self.assertFalse(mocked_logger_warning.called)
|
||||||
|
start.run()
|
||||||
|
self.assertTrue(mocked_subprocess.called)
|
||||||
|
self.assertTrue(mocked_logger_warning.called)
|
||||||
|
|
|
@ -8,27 +8,28 @@ from service import start
|
||||||
|
|
||||||
@mock.patch('service.start.get_available_sdk_packages')
|
@mock.patch('service.start.get_available_sdk_packages')
|
||||||
class TestRunService(TestCase):
|
class TestRunService(TestCase):
|
||||||
"""Unit test class to test method create_android_emulator."""
|
"""Unit test class to test method get_android_bash_commands."""
|
||||||
|
|
||||||
def test_create_emulator(self, mocked_packages):
|
def test_create_emulator(self, mocked_packages):
|
||||||
mocked_packages.return_value = ['9- SDK Platform Android 4.4.2, API 19, revision 4',
|
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',
|
'10- SDK Platform Android 4.3.1, API 18, revision 3',
|
||||||
'11- SDK Platform Android 4.2.2, API 17, revision 3']
|
'11- SDK Platform Android 4.2.2, API 17, revision 3']
|
||||||
with mock.patch('subprocess.check_call') as mocked_subprocess:
|
|
||||||
self.assertFalse(mocked_subprocess.called)
|
android_version = '4.2.2'
|
||||||
android_version = '4.2.2'
|
cmd = start.get_android_bash_commands(android_version)
|
||||||
start.create_android_emulator(android_version)
|
self.assertIsNotNone(cmd)
|
||||||
self.assertTrue(mocked_subprocess.called)
|
self.assertTrue('android update sdk' in cmd)
|
||||||
|
self.assertTrue('android create avd' in cmd)
|
||||||
|
|
||||||
def test_empty_packages(self, mocked_packages):
|
def test_empty_packages(self, mocked_packages):
|
||||||
mocked_packages.return_value = None
|
mocked_packages.return_value = None
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
start.create_android_emulator('4.2.2')
|
start.get_android_bash_commands('4.2.2')
|
||||||
|
|
||||||
def test_index_error(self, mocked_packages):
|
def test_index_error(self, mocked_packages):
|
||||||
mocked_packages.return_value = ['9 SDK Platform Android 4.4.2, API 19, revision 4',
|
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',
|
'10 SDK Platform Android 4.3.1, API 18, revision 3',
|
||||||
'11 SDK Platform Android 4.2.2, API 17, revision 3']
|
'11 SDK Platform Android 4.2.2, API 17, revision 3']
|
||||||
android_version = '4.2.2'
|
android_version = '4.2.2'
|
||||||
start.create_android_emulator(android_version)
|
start.get_android_bash_commands(android_version)
|
||||||
self.assertRaises(IndexError)
|
self.assertRaises(IndexError)
|
Loading…
Reference in a new issue