Merge remote-tracking branch 'origin' into update-sdk

This commit is contained in:
butomo1989 2017-11-03 12:26:05 +01:00
commit 7a052b7e2f
9 changed files with 81 additions and 38 deletions

View file

@ -28,7 +28,9 @@ Advantages compare with other docker-android projects
2. Emulator for different devices / skins, such as Samsung Galaxy S6, LG Nexus 4, HTC Nexus One and more. 2. Emulator for different devices / skins, such as Samsung Galaxy S6, LG Nexus 4, HTC Nexus One and more.
3. Ability to connect to Selenium Grid 3. Ability to connect to Selenium Grid
4. Ability to control emulator from outside container by using adb connect 4. Ability to control emulator from outside container by using adb connect
5. Open source with more features coming (monkey test, support real devices with screen mirroring and video recording) 5. Support real devices with screen mirroring
6. Ability to record video during test execution for debugging
7. Open source with more features coming
List of Docker images List of Docker images
--------------------- ---------------------
@ -45,6 +47,7 @@ List of Docker images
|OSX / Windows|6.0|23|butomo1989/docker-android-arm-6.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-6.0.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-6.0 "Get your own image badge on microbadger.com")| |OSX / Windows|6.0|23|butomo1989/docker-android-arm-6.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-6.0.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-6.0 "Get your own image badge on microbadger.com")|
|OSX / Windows|7.0|24|butomo1989/docker-android-arm-7.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-7.0.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-7.0 "Get your own image badge on microbadger.com")| |OSX / Windows|7.0|24|butomo1989/docker-android-arm-7.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-7.0.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-7.0 "Get your own image badge on microbadger.com")|
|OSX / Windows|7.1.1|25|butomo1989/docker-android-arm-7.1.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-7.1.1.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-7.1.1 "Get your own image badge on microbadger.com")| |OSX / Windows|7.1.1|25|butomo1989/docker-android-arm-7.1.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-7.1.1.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-7.1.1 "Get your own image badge on microbadger.com")|
|All |-|-|butomo1989/docker-android-real-device|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-real-device.svg)](https://microbadger.com/images/butomo1989/docker-android-real-device "Get your own image badge on microbadger.com")|
List of Devices List of Devices
--------------- ---------------
@ -127,6 +130,10 @@ If you want to use appium to test UI of your android application, you need to sh
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -v $PWD/example/sample_apk:/root/tmp -e DEVICE="Nexus 5" -e APPIUM=True -e CONNECT_TO_GRID=True -e APPIUM_HOST="127.0.0.1" -e APPIUM_PORT=4723 -e SELENIUM_HOST="172.17.0.1" -e SELENIUM_PORT=4444 --name android-container butomo1989/docker-android-x86-7.1.1 docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -v $PWD/example/sample_apk:/root/tmp -e DEVICE="Nexus 5" -e APPIUM=True -e CONNECT_TO_GRID=True -e APPIUM_HOST="127.0.0.1" -e APPIUM_PORT=4723 -e SELENIUM_HOST="172.17.0.1" -e SELENIUM_PORT=4444 --name android-container butomo1989/docker-android-x86-7.1.1
``` ```
### Share Volume
You can deactivate auto_record by changing the value to "False" in docker-compose file. e.g. change value to "False" in this [line].
### Docker-Compose ### Docker-Compose
![][compose] ![][compose]
@ -202,6 +209,7 @@ docker exec -it android-container tail -f /var/log/supervisor/docker-android.std
[docker android nexus]: <images/docker_android_nexus.png> [docker android nexus]: <images/docker_android_nexus.png>
[compose]: <images/compose.png> [compose]: <images/compose.png>
[connected_devices]: <images/connected_devices.png> [connected_devices]: <images/connected_devices.png>
[line]: <https://github.com/butomo1989/docker-android/blob/master/docker-compose.yml#L30>
[example of compose file]: <docker-compose.yml> [example of compose file]: <docker-compose.yml>
[docker-compose]: <https://docs.docker.com/compose/install/> [docker-compose]: <https://docs.docker.com/compose/install/>
[1.13.0]: <https://github.com/docker/compose/releases/tag/1.13.0> [1.13.0]: <https://github.com/docker/compose/releases/tag/1.13.0>

View file

@ -14,14 +14,13 @@ services:
nexus_7.1.1: nexus_7.1.1:
image: butomo1989/docker-android-x86-7.1.1 image: butomo1989/docker-android-x86-7.1.1
privileged: true privileged: true
# Change path of apk that you want to test. I use sample_apk that I provide in folder "example"
volumes:
- $PWD/example/sample_apk:/root/tmp
# Increase scale number if needed # Increase scale number if needed
scale: 1 scale: 1
ports: ports:
- 6080 - 6080
# Change path of apk that you want to test. I use sample_apk that I provide in folder "example"
volumes: volumes:
- $PWD/example/sample_apk:/root/tmp
- ./video-nexus_7.1.1:/tmp/video - ./video-nexus_7.1.1:/tmp/video
environment: environment:
- DEVICE=Nexus 5 - DEVICE=Nexus 5

View file

@ -34,6 +34,8 @@ WORKDIR /root
#------------------ #------------------
# ffmpeg # ffmpeg
# Video recorder # Video recorder
# jq
# Sed for JSON data
#================== #==================
RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \ RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
xterm \ xterm \
@ -45,6 +47,7 @@ RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
python-numpy \ python-numpy \
net-tools \ net-tools \
ffmpeg \ ffmpeg \
jq \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
#======= #=======

View file

@ -34,6 +34,8 @@ WORKDIR /root
#------------------ #------------------
# ffmpeg # ffmpeg
# Video recorder # Video recorder
# jq
# Sed for JSON data
#------------------ #------------------
# KVM Package # KVM Package
# for emulator x86 # for emulator x86
@ -54,6 +56,7 @@ RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
python-numpy \ python-numpy \
net-tools \ net-tools \
ffmpeg \ ffmpeg \
jq \
qemu-kvm \ qemu-kvm \
libvirt-bin \ libvirt-bin \
ubuntu-vm-builder \ ubuntu-vm-builder \

View file

@ -34,6 +34,8 @@ WORKDIR /root
#------------------ #------------------
# ffmpeg # ffmpeg
# Video recorder # Video recorder
# jq
# Sed for JSON data
#================== #==================
RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \ RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
xterm \ xterm \
@ -45,6 +47,7 @@ RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
python-numpy \ python-numpy \
net-tools \ net-tools \
ffmpeg \ ffmpeg \
jq \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
#======= #=======

View file

@ -4,6 +4,7 @@ import json
import logging import logging
import os import os
import subprocess import subprocess
import errno
from src import CONFIG_FILE, ROOT, CHROME_DRIVER from src import CONFIG_FILE, ROOT, CHROME_DRIVER
from src import log from src import log
@ -11,6 +12,13 @@ from src import log
log.init() log.init()
logger = logging.getLogger('app') logger = logging.getLogger('app')
def symlink_force(target, link_name):
try:
os.symlink(target, link_name)
except OSError as e:
if e.errno == errno.EEXIST:
os.remove(link_name)
os.symlink(target, link_name)
def get_or_raise(env: str) -> str: def get_or_raise(env: str) -> str:
""" """
@ -71,7 +79,7 @@ def prepare_avd(device: str, avd_name: str):
skin_dst_path = os.path.join(ANDROID_HOME, 'platforms', 'android-{api}'.format(api=API_LEVEL), 'skins') skin_dst_path = os.path.join(ANDROID_HOME, 'platforms', 'android-{api}'.format(api=API_LEVEL), 'skins')
logger.info('Skin destination path: {dst}'.format(dst=skin_dst_path)) logger.info('Skin destination path: {dst}'.format(dst=skin_dst_path))
for s in os.listdir(skin_rsc_path): for s in os.listdir(skin_rsc_path):
os.symlink(os.path.join(skin_rsc_path, s), os.path.join(skin_dst_path, s)) symlink_force(os.path.join(skin_rsc_path, s), os.path.join(skin_dst_path, s))
# Hardware and its skin # Hardware and its skin
device_name_bash = device.replace(' ', '\ ') device_name_bash = device.replace(' ', '\ ')
@ -85,7 +93,7 @@ def prepare_avd(device: str, avd_name: str):
profile_src_path = os.path.join(ROOT, 'devices', 'profiles', '{profile}.xml'.format(profile=skin_name)) profile_src_path = os.path.join(ROOT, 'devices', 'profiles', '{profile}.xml'.format(profile=skin_name))
logger.info('Hardware profile resource path: {rsc}'.format(rsc=profile_src_path)) logger.info('Hardware profile resource path: {rsc}'.format(rsc=profile_src_path))
logger.info('Hardware profile destination path: {dst}'.format(dst=profile_dst_path)) logger.info('Hardware profile destination path: {dst}'.format(dst=profile_dst_path))
os.symlink(profile_src_path, profile_dst_path) symlink_force(profile_src_path, profile_dst_path)
# Append command # Append command
cmd += ' -d {device} -s {skin}'.format(device=device_name_bash, skin=skin_name) cmd += ' -d {device} -s {skin}'.format(device=device_name_bash, skin=skin_name)

View file

@ -2,44 +2,46 @@
function start() { function start() {
mkdir -p $VIDEO_PATH mkdir -p $VIDEO_PATH
sw=$(($SCREEN_WIDTH - 1)) name="$(date '+%d_%m_%Y_%H_%M_%S').mp4"
sh=$(($SCREEN_HEIGHT - 1))
name="$DEVICE-$BROWSER-$(date '+%d/%m/%Y-%H:%M:%S')"
echo "Start video recording" echo "Start video recording"
ffmpeg -video_size $swx$sh -framerate 15 -f x11grab -i ${DISPLAY} $VIDEO_PATH/$name -y ffmpeg -video_size 1599x899 -framerate 15 -f x11grab -i $DISPLAY $VIDEO_PATH/$name -y
} }
function stop() { function stop() {
echo "Stop video recording" echo "Stop video recording"
kill $(ps -ef | grep ffmpeg) kill $(ps -ef | grep [f]fmpeg | awk '{print $2}')
} }
function auto_record() { function auto_record() {
if [ ! -z $AUTO_RECORD ]; then echo "Auto record: $AUTO_RECORD"
if [ ${AUTO_RECORD,,} = true ]; then sleep 6
echo "Auto recording is enable. It will record the video automatically as soon as appium receive test scenario!"
while [ $AUTO_RECORD == "True" ]; do
# Check if there is test running # Check if there is test running
no_test=true no_test=true
while $no_test; do while $no_test; do
task=$(curl -s localhost:4723/wd/hub/sessions | jq -r '.value') task=$(curl -s localhost:4723/wd/hub/sessions | jq -r '.value')
if [ -n "$task" ]; then if [ "$task" == "" ] || [ "$task" == "[]" ]; then
sleep .5 sleep .5
else else
start &
no_test=false no_test=false
start
fi fi
done done
# Check if test is finished # Check if test is finished
while [ $no_test = false ]; do while [ $no_test == false ]; do
task=$(curl -s localhost:4723/wd/hub/sessions | jq -r '.value') task=$(curl -s localhost:4723/wd/hub/sessions | jq -r '.value')
if [ -n "$task" ]; then if [ "$task" == "" ] || [ "$task" == "[]" ]; then
stop stop
no_test=true
else else
sleep .5 sleep .5
fi fi
done done
fi done
fi
echo "Auto recording is disabled!"
} }
$@

View file

@ -10,6 +10,23 @@ from src import app
class TestApp(TestCase): class TestApp(TestCase):
"""Unit test class to test other methods in the app.""" """Unit test class to test other methods in the app."""
#create symlink
@classmethod
def test_symlink_correct(self):
os.mknod(os.path.join("./","testFile1.txt"))
app.symlink_force(os.path.join("./","testFile1.txt"),os.path.join("./","link_testFile1.txt"))
os.remove(os.path.join("./","testFile1.txt"))
os.remove(os.path.join("./","link_testFile1.txt"))
#link already exist
@classmethod
def test_symlink_already_exist(self):
os.mknod(os.path.join("./","testFile2.txt"))
os.mknod(os.path.join("./","link_testFile2.txt"))
app.symlink_force(os.path.join("./","testFile2.txt"),os.path.join("./","link_testFile2.txt"))
os.remove(os.path.join("./","testFile2.txt"))
os.remove(os.path.join("./","link_testFile2.txt"))
def test_valid_env(self): def test_valid_env(self):
key = 'ENV_1' key = 'ENV_1'
os.environ[key] = 'test' os.environ[key] = 'test'

View file

@ -50,7 +50,7 @@ stderr_logfile=%(ENV_LOG_PATH)s/docker-android.stderr.log
priority=4 priority=4
[program:auto-recording] [program:auto-recording]
command=./src/record.sh command=./src/record.sh auto_record
autorestart=false autorestart=false
stdout_logfile=%(ENV_LOG_PATH)s/video-recording.stdout.log stdout_logfile=%(ENV_LOG_PATH)s/video-recording.stdout.log
stderr_logfile=%(ENV_LOG_PATH)s/video-recording.stderr.log stderr_logfile=%(ENV_LOG_PATH)s/video-recording.stderr.log