support noVNC

This commit is contained in:
butomo1989 2017-01-08 17:24:14 +01:00
parent 08b0e65216
commit 7785e56a2a
4 changed files with 111 additions and 64 deletions

View file

@ -1,24 +1,44 @@
FROM ubuntu:16.04
FROM ubuntu:14.04
#=======================
# General Configuration
#=======================
ENV DEBIAN_FRONTEND noninteractive
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
#==============
RUN apt-get install openjdk-8-jdk -y
ENV JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64/jre"
RUN apt-get install openjdk-7-jdk -y
ENV JAVA_HOME="/usr/lib/jvm/java-7-openjdk-amd64/jre"
ENV PATH="${PATH}:${JAVA_HOME}/bin"
#=====================
# Install Android SDK
#=====================
RUN apt-get install wget -y
RUN wget http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
RUN tar -xvzf android-sdk_r24.4.1-linux.tgz
ENV ANDROID_HOME="/android-sdk-linux"
RUN tar -xvzf android-sdk_r24.4.1-linux.tgz && rm android-sdk_r24.4.1-linux.tgz
ENV ANDROID_HOME="/root/android-sdk-linux"
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
ENV PATH="${PATH}:${ANDROID_HOME}/platform-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
#==================================================
RUN dpkg --add-architecture i386
RUN apt-get update
RUN apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 -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
#====================================
# Install latest nodejs, npm, appium
#====================================
RUN apt-get install curl -y
RUN curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
RUN apt-get install nodejs -y
ENV APPIUM_VERSION 1.6.3
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
#===================
COPY service /service
WORKDIR /service
CMD python start.py
COPY service /root/service
CMD python -m service.start

View file

@ -9,18 +9,27 @@ logger = logging.getLogger('android_appium')
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')
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))
# TODO: check android emulator is ready to use
cmd_run = 'emulator -avd {name} -no-audio -no-window & appium'.format(name=emulator_name)
subprocess.check_call(cmd_run, shell=True)
# Start noVNC, installation of packages and appium
vnc_cmd = 'openbox-session & x11vnc -display ${DISPLAY} -nopw -ncache 10 -forever & ' \
'./noVNC/utils/launch.sh --vnc localhost:${LOCAL_PORT} --listen ${TARGET_PORT}'
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():
@ -30,12 +39,10 @@ def get_available_sdk_packages():
:return: List of available packages.
:rtype: bytearray
"""
logger.info('List of Android SDK: ')
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
@ -54,17 +61,20 @@ def get_item_position(keyword, items):
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 to avd: android list avd
:param android_version: android version
:type android_version: str
:return: bash commands
:rtype: bytearray
"""
bash_command = None
try:
packages = get_available_sdk_packages()
@ -79,31 +89,29 @@ def create_android_emulator(android_version):
logger.info(
'Package number: {number}, API version: {version}'.format(number=package_number, version=api_version))
# Install SDK package
logger.info('Installing SDK package...')
cmd_sdk = 'echo y | android update sdk --no-ui --filter {number}'.format(number=package_number)
subprocess.check_call(cmd_sdk, shell=True)
logger.info('Installation completed')
commands = []
# Command to install SDK package
commands.append('echo y | android update sdk --no-ui --filter {number}'.format(number=package_number))
# Install armeabi v7a
logger.info('Installing its armeabi...')
cmd_arm = 'echo y | android update sdk --no-ui -a --filter sys-img-armeabi-v7a-android-{api}'.format(
api=api_version)
subprocess.check_call(cmd_arm, shell=True)
logger.info('Installation completed')
# Command to install armeabi v7a
commands.append('echo y | android update sdk --no-ui -a --filter sys-img-armeabi-v7a-android-{api}'.format(
api=api_version))
# Create android emulator
logger.info('Creating android emulator...')
cmd_emu = 'echo no | android create avd -f -n emulator_{version} -t android-{api} --abi armeabi-v7a'.format(
version=android_version, api=api_version)
subprocess.check_call(cmd_emu, shell=True)
logger.info('Android emulator is created')
# Command to create android emulator
commands.append(
'echo no | android create avd -f -n emulator_{version} -t android-{api} --abi armeabi-v7a'.format(
version=android_version, api=api_version))
# 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
if __name__ == '__main__':
logger.setLevel(logging.INFO)

View file

@ -9,11 +9,22 @@ from service import start
class TestService(TestCase):
"""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')
def test_service(self, mocked_creation, mocked_subprocess):
self.assertFalse(mocked_creation.called)
def test_service(self, mocked_bash_cmd, mocked_subprocess):
self.assertFalse(mocked_bash_cmd.called)
self.assertFalse(mocked_subprocess.called)
start.run()
self.assertTrue(mocked_creation.called)
self.assertTrue(mocked_bash_cmd.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)

View file

@ -8,27 +8,28 @@ from service import start
@mock.patch('service.start.get_available_sdk_packages')
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):
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']
with mock.patch('subprocess.check_call') as mocked_subprocess:
self.assertFalse(mocked_subprocess.called)
android_version = '4.2.2'
start.create_android_emulator(android_version)
self.assertTrue(mocked_subprocess.called)
android_version = '4.2.2'
cmd = start.get_android_bash_commands(android_version)
self.assertIsNotNone(cmd)
self.assertTrue('android update sdk' in cmd)
self.assertTrue('android create avd' in cmd)
def test_empty_packages(self, mocked_packages):
mocked_packages.return_value = None
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):
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_version = '4.2.2'
start.create_android_emulator(android_version)
start.get_android_bash_commands(android_version)
self.assertRaises(IndexError)