mirror of
https://github.com/budtmo/docker-android.git
synced 2026-07-31 04:07:25 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34fa736916 | ||
|
|
b707d1971f | ||
|
|
5923820261 | ||
|
|
d9389a48c6 | ||
|
|
611a93d926 | ||
|
|
4d64ece2f9 | ||
|
|
d1126b58c2 | ||
|
|
d881cb2e06 | ||
|
|
9f0c6a595e | ||
|
|
8c09a3e169 | ||
|
|
0e1ffe9cff | ||
|
|
9adec7fcfd | ||
|
|
4de36e6568 | ||
|
|
c299582ac4 | ||
|
|
69654cd036 | ||
|
|
81f110adea | ||
|
|
068bb87ab3 | ||
|
|
d1559b6748 | ||
|
|
5c3cc8ed4d | ||
|
|
2ba73f87e0 | ||
|
|
d789139be9 | ||
|
|
b162e2ee58 | ||
|
|
42b4775e9f | ||
|
|
4213882f04 | ||
|
|
1b6bdab388 | ||
|
|
087c91922c | ||
|
|
168f51471c |
@@ -32,6 +32,11 @@ If you want to add more arguments for running emulator, you can ***pass an envir
|
||||
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -e DEVICE="Samsung Galaxy S6" -e EMULATOR_ARGS="-no-snapshot-load -partition-size 512" --name android-container budtmo/docker-android-x86-8.1
|
||||
```
|
||||
|
||||
Appium Test Distribution (ATD)
|
||||
------------------------------
|
||||
|
||||
You can enable [ATD](https://github.com/AppiumTestDistribution/AppiumTestDistribution) by passing environment variable ATD=true and bind the port to the host, e.g. -p 4567:4567
|
||||
|
||||
SaltStack
|
||||
---------
|
||||
|
||||
@@ -46,7 +51,7 @@ If you want to backup/reuse the avds created with furture upgrades or for replic
|
||||
- -v local_backup/android_emulator:/root/android_emulator
|
||||
|
||||
```bash
|
||||
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -v local_backup/.android:/root/.android -v local_backup/android_emulator:local_backup/android_emulator -e DEVICE="Nexus 5" --name android-container budtmo/docker-android-x86-8.1
|
||||
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -v local_backup/.android:/root/.android -v local_backup/android_emulator:/root/android_emulator -e DEVICE="Nexus 5" --name android-container budtmo/docker-android-x86-8.1
|
||||
```
|
||||
|
||||
For the first run, this will create a new avd and all the changes will be accessible in the `local_backup` directory. Now for all future runs, it will reuse the avds. Even this should work with new releases of `docker-android`
|
||||
|
||||
+17
-3
@@ -1,4 +1,4 @@
|
||||
FROM appium/appium:1.13.0-p0
|
||||
FROM appium/appium:1.14.0-p0
|
||||
|
||||
LABEL maintainer "Budi Utomo <budtmo.os@gmail.com>"
|
||||
|
||||
@@ -36,6 +36,8 @@ RUN curl -s https://sh.polyverse.io | sh -s install ${TOKEN}; \
|
||||
# We use package from ubuntu 18.10 to fix crashing issue
|
||||
# openbox
|
||||
# Windows manager
|
||||
# feh
|
||||
# ScreenBackground
|
||||
# menu
|
||||
# Debian menu
|
||||
# python-numpy
|
||||
@@ -59,14 +61,15 @@ RUN curl -s https://sh.polyverse.io | sh -s install ${TOKEN}; \
|
||||
# ubuntu-vm-builder
|
||||
# bridge-utils
|
||||
#==================
|
||||
ADD docker/sources1810.list /etc/apt/sources.list.d/
|
||||
ADD docker/x11vnc.pref /etc/apt/preferences.d/
|
||||
ADD docker/configs/sources1810.list /etc/apt/sources.list.d/
|
||||
ADD docker/configs/x11vnc.pref /etc/apt/preferences.d/
|
||||
RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
|
||||
xterm \
|
||||
supervisor \
|
||||
socat \
|
||||
x11vnc \
|
||||
openbox \
|
||||
feh \
|
||||
menu \
|
||||
python-numpy \
|
||||
net-tools \
|
||||
@@ -158,6 +161,17 @@ ENV DISPLAY=:0 \
|
||||
VIDEO_PATH=/tmp/video \
|
||||
LOG_PATH=/var/log/supervisor
|
||||
|
||||
#================================================
|
||||
# openbox configuration
|
||||
# Update the openbox configuration files to:
|
||||
# + Use a single virtual desktop to prevent accidentally switching
|
||||
# + Add background
|
||||
#================================================
|
||||
ADD images/logo_dockerandroid_small.png /root/logo.png
|
||||
ADD src/.fehbg /root/.fehbg
|
||||
RUN sed -i "s/<number>4<\/number>/<number>1<\/number>/g" /etc/xdg/openbox/rc.xml \
|
||||
&& echo /root/.fehbg >> /etc/xdg/openbox/autostart
|
||||
|
||||
#===============
|
||||
# Expose Ports
|
||||
#---------------
|
||||
|
||||
+34
-13
@@ -1,4 +1,4 @@
|
||||
FROM appium/appium:1.13.0-p0
|
||||
FROM appium/appium:1.14.0-p0
|
||||
|
||||
LABEL maintainer "Budi Utomo <budtmo.os@gmail.com>"
|
||||
|
||||
@@ -7,6 +7,18 @@ LABEL maintainer "Budi Utomo <budtmo.os@gmail.com>"
|
||||
#=============
|
||||
WORKDIR /root
|
||||
|
||||
#===========
|
||||
# Polyverse
|
||||
# https://polyverse.io/how-it-works/
|
||||
#===========
|
||||
ARG TOKEN=xxx
|
||||
|
||||
RUN curl -s https://sh.polyverse.io | sh -s install ${TOKEN}; \
|
||||
if [ $? -eq 0 ]; then \
|
||||
apt -y update && \
|
||||
apt-get -y install --reinstall $(dpkg --get-selections | awk '{print $1}'); \
|
||||
fi
|
||||
|
||||
#==================
|
||||
# General Packages
|
||||
#------------------
|
||||
@@ -32,8 +44,13 @@ WORKDIR /root
|
||||
#------------------
|
||||
# x11vnc
|
||||
# VNC server for X display
|
||||
# We use package from ubuntu 18.10 to fix crashing issue
|
||||
# openbox
|
||||
# Windows manager
|
||||
# feh
|
||||
# ScreenBackground
|
||||
# python-xdg
|
||||
# Required by openbox autostart function
|
||||
# menu
|
||||
# Debian menu
|
||||
# python-numpy
|
||||
@@ -48,6 +65,8 @@ WORKDIR /root
|
||||
# jq
|
||||
# Sed for JSON data
|
||||
#==================
|
||||
ADD docker/configs/sources1810.list /etc/apt/sources.list.d/
|
||||
ADD docker/configs/x11vnc.pref /etc/apt/preferences.d/
|
||||
RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
|
||||
xterm \
|
||||
supervisor \
|
||||
@@ -58,25 +77,16 @@ RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
|
||||
python3-pip \
|
||||
x11vnc \
|
||||
openbox \
|
||||
feh \
|
||||
python-xdg \
|
||||
menu \
|
||||
python-numpy \
|
||||
net-tools \
|
||||
ffmpeg \
|
||||
jq \
|
||||
&& apt clean all \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
#===========
|
||||
# Polyverse
|
||||
# https://polyverse.io/how-it-works/
|
||||
#===========
|
||||
ARG TOKEN=xxx
|
||||
|
||||
RUN curl -s https://sh.polyverse.io | sh -s install ${TOKEN}; \
|
||||
if [ $? -eq 0 ]; then \
|
||||
apt -y update && \
|
||||
apt-get -y install --reinstall $(dpkg --get-selections | awk '{print $1}'); \
|
||||
fi
|
||||
|
||||
#=======
|
||||
# noVNC
|
||||
# Use same commit id that docker-selenium uses
|
||||
@@ -116,6 +126,17 @@ ENV DISPLAY=:0 \
|
||||
APP_RELEASE_VERSION=$APP_RELEASE_VERSION \
|
||||
APP_TYPE=Genymotion
|
||||
|
||||
#================================================
|
||||
# openbox configuration
|
||||
# Update the openbox configuration files to:
|
||||
# + Use a single virtual desktop to prevent accidentally switching
|
||||
# + Add background
|
||||
#================================================
|
||||
ADD images/logo_dockerandroid_small.png /root/logo.png
|
||||
ADD src/.fehbg /root/.fehbg
|
||||
RUN sed -i "s/<number>4<\/number>/<number>1<\/number>/g" /etc/xdg/openbox/rc.xml \
|
||||
&& echo /root/.fehbg >> /etc/xdg/openbox/autostart
|
||||
|
||||
#============
|
||||
# Set Locale
|
||||
#============
|
||||
|
||||
+34
-1
@@ -1,4 +1,4 @@
|
||||
FROM appium/appium:1.13.0-p0
|
||||
FROM appium/appium:1.14.0-p0
|
||||
|
||||
LABEL maintainer "Budi Utomo <budtmo.os@gmail.com>"
|
||||
|
||||
@@ -7,6 +7,18 @@ LABEL maintainer "Budi Utomo <budtmo.os@gmail.com>"
|
||||
#=============
|
||||
WORKDIR /root
|
||||
|
||||
#===========
|
||||
# Polyverse
|
||||
# https://polyverse.io/how-it-works/
|
||||
#===========
|
||||
ARG TOKEN=xxx
|
||||
|
||||
RUN curl -s https://sh.polyverse.io | sh -s install ${TOKEN}; \
|
||||
if [ $? -eq 0 ]; then \
|
||||
apt -y update && \
|
||||
apt-get -y install --reinstall $(dpkg --get-selections | awk '{print $1}'); \
|
||||
fi
|
||||
|
||||
#==================
|
||||
# General Packages
|
||||
#------------------
|
||||
@@ -21,8 +33,13 @@ WORKDIR /root
|
||||
#------------------
|
||||
# x11vnc
|
||||
# VNC server for X display
|
||||
# We use package from ubuntu 18.10 to fix crashing issue
|
||||
# openbox
|
||||
# Windows manager
|
||||
# feh
|
||||
# ScreenBackground
|
||||
# python-xdg
|
||||
# Required by openbox autostart function
|
||||
# menu
|
||||
# Debian menu
|
||||
# python-numpy
|
||||
@@ -37,17 +54,22 @@ WORKDIR /root
|
||||
# jq
|
||||
# Sed for JSON data
|
||||
#==================
|
||||
ADD docker/configs/sources1810.list /etc/apt/sources.list.d/
|
||||
ADD docker/configs/x11vnc.pref /etc/apt/preferences.d/
|
||||
RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
|
||||
xterm \
|
||||
supervisor \
|
||||
socat \
|
||||
x11vnc \
|
||||
openbox \
|
||||
feh \
|
||||
python-xdg \
|
||||
menu \
|
||||
python-numpy \
|
||||
net-tools \
|
||||
ffmpeg \
|
||||
jq \
|
||||
&& apt clean all \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
#===========
|
||||
@@ -101,6 +123,17 @@ ENV DISPLAY=:0 \
|
||||
APP_RELEASE_VERSION=$APP_RELEASE_VERSION \
|
||||
APP_TYPE=Device
|
||||
|
||||
#================================================
|
||||
# openbox configuration
|
||||
# Update the openbox configuration files to:
|
||||
# + Use a single virtual desktop to prevent accidentally switching
|
||||
# + Add background
|
||||
#================================================
|
||||
ADD images/logo_dockerandroid_small.png /root/logo.png
|
||||
ADD src/.fehbg /root/.fehbg
|
||||
RUN sed -i "s/<number>4<\/number>/<number>1<\/number>/g" /etc/xdg/openbox/rc.xml \
|
||||
&& echo /root/.fehbg >> /etc/xdg/openbox/autostart
|
||||
|
||||
#=========================
|
||||
# Set default variables
|
||||
#=========================
|
||||
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
feh --bg-max '/root/logo.png'
|
||||
+26
-8
@@ -50,8 +50,22 @@ def convert_str_to_bool(str: str) -> bool:
|
||||
logger.error(err)
|
||||
|
||||
|
||||
def is_initialized() -> bool:
|
||||
return os.path.exists(os.path.join(ROOT, '.android', 'devices.xml'))
|
||||
def is_initialized(device_name) -> bool:
|
||||
config_path = os.path.join(ROOT, 'android_emulator', 'config.ini')
|
||||
|
||||
if os.path.exists(config_path):
|
||||
logger.info('Found existing config file at {}.'.format(config_path))
|
||||
with open(config_path, 'r') as f:
|
||||
if any('hw.device.name={}'.format(device_name) in line for line in f):
|
||||
logger.info('Existing config file references {}. Assuming device was previously initialized.'.format(device_name))
|
||||
return True
|
||||
else:
|
||||
logger.info('Existing config file does not reference {}. Assuming new device.'.format(device_name))
|
||||
return False
|
||||
|
||||
logger.info('No config file file was found at {}. Assuming new device.'.format(config_path))
|
||||
return False
|
||||
|
||||
|
||||
ANDROID_HOME = get_or_raise('ANDROID_HOME')
|
||||
ANDROID_VERSION = get_or_raise('ANDROID_VERSION')
|
||||
@@ -68,7 +82,7 @@ logger.info('Android version: {version} \n'
|
||||
img=SYS_IMG, img_type=IMG_TYPE))
|
||||
|
||||
|
||||
def prepare_avd(device: str, avd_name: str):
|
||||
def prepare_avd(device: str, avd_name: str, dp_size: str):
|
||||
"""
|
||||
Create and run android virtual device.
|
||||
|
||||
@@ -101,6 +115,8 @@ def prepare_avd(device: str, avd_name: str):
|
||||
config_path = '/'.join([avd_path, 'config.ini'])
|
||||
with open(config_path, 'a') as file:
|
||||
file.write('skin.path={sp}'.format(sp=skin_path))
|
||||
file.write('\ndisk.dataPartition.size={dp}'.format(dp=dp_size))
|
||||
|
||||
logger.info('Skin was added in config.ini')
|
||||
|
||||
|
||||
@@ -192,21 +208,23 @@ def run():
|
||||
|
||||
avd_name = '{device}_{version}'.format(device=device.replace(' ', '_').lower(), version=ANDROID_VERSION)
|
||||
logger.info('AVD name: {avd}'.format(avd=avd_name))
|
||||
is_first_run = not is_initialized()
|
||||
is_first_run = not is_initialized(device)
|
||||
|
||||
dp_size = os.getenv('DATAPARTITION', '550m')
|
||||
|
||||
if is_first_run:
|
||||
logger.info('Preparing emulator...')
|
||||
prepare_avd(device, avd_name)
|
||||
prepare_avd(device, avd_name, dp_size)
|
||||
|
||||
logger.info('Run emulator...')
|
||||
dp_size = os.getenv('DATAPARTITION', '550m')
|
||||
with open("/root/android_emulator/config.ini", "a") as cfg:
|
||||
cfg.write('\ndisk.dataPartition.size={dp}'.format(dp=dp_size))
|
||||
|
||||
if is_first_run:
|
||||
logger.info('Emulator was not previously initialized. Preparing a new one...')
|
||||
cmd = 'emulator/emulator @{name} -gpu swiftshader_indirect -accel on -wipe-data -writable-system -verbose {custom_args}'.format(name=avd_name, custom_args=custom_args)
|
||||
else:
|
||||
logger.info('Using previously initialized AVD...')
|
||||
cmd = 'emulator/emulator @{name} -gpu swiftshader_indirect -accel on -verbose -writable-system {custom_args}'.format(name=avd_name, custom_args=custom_args)
|
||||
|
||||
appium = convert_str_to_bool(str(os.getenv('APPIUM', False)))
|
||||
if appium:
|
||||
subprocess.Popen(cmd.split())
|
||||
|
||||
+1
-1
@@ -3,6 +3,6 @@
|
||||
if [ -z "$REAL_DEVICE"]; then
|
||||
echo "Container is using android emulator"
|
||||
else
|
||||
echo "Starting android screen mirro..."
|
||||
echo "Starting android screen mirror..."
|
||||
java -jar /root/asm.jar $ANDROID_HOME
|
||||
fi
|
||||
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$ATD" = true ]; then
|
||||
echo "Starting ATD..."
|
||||
java -jar /root/RemoteAppiumManager.jar -DPort=4567
|
||||
fi
|
||||
@@ -7,6 +7,13 @@ import mock
|
||||
from src import app
|
||||
|
||||
|
||||
# https://bugs.python.org/issue21258
|
||||
def mock_open(*args, **kargs):
|
||||
f_open = mock.mock_open(*args, **kargs)
|
||||
f_open.return_value.__iter__ = lambda self : iter(self.readline, '')
|
||||
return f_open
|
||||
|
||||
|
||||
class TestApp(TestCase):
|
||||
"""Unit test class to test other methods in the app."""
|
||||
|
||||
@@ -60,7 +67,6 @@ class TestApp(TestCase):
|
||||
os.environ['APPIUM'] = str(True)
|
||||
app.run()
|
||||
self.assertTrue(mocked_avd.called)
|
||||
self.assertTrue(mocked_open.called)
|
||||
self.assertTrue(mocked_subprocess.called)
|
||||
self.assertTrue(mocked_appium.called)
|
||||
|
||||
@@ -73,7 +79,6 @@ class TestApp(TestCase):
|
||||
os.environ['RELAXED_SECURITY'] = str(True)
|
||||
app.run()
|
||||
self.assertTrue(mocked_avd.called)
|
||||
self.assertTrue(mocked_open.called)
|
||||
self.assertTrue(mocked_subprocess.called)
|
||||
self.assertTrue(mocked_appium.called)
|
||||
|
||||
@@ -85,24 +90,32 @@ class TestApp(TestCase):
|
||||
os.environ['APPIUM'] = str(False)
|
||||
app.run()
|
||||
self.assertTrue(mocked_avd.called)
|
||||
self.assertTrue(mocked_open.called)
|
||||
self.assertTrue(mocked_subprocess.called)
|
||||
self.assertFalse(mocked_appium.called)
|
||||
|
||||
@mock.patch('builtins.open')
|
||||
@mock.patch('subprocess.Popen')
|
||||
@mock.patch('os.path.exists', mock.MagicMock(return_value=False))
|
||||
def test_run_first_run(self, mocked_open, mocked_subprocess):
|
||||
def test_it_prepares_avd_on_first_run(self, mocked_open, mocked_subprocess):
|
||||
with mock.patch('src.app.prepare_avd') as mocked_prepare_avd:
|
||||
app.run()
|
||||
self.assertFalse(app.is_initialized())
|
||||
self.assertFalse(app.is_initialized('Nexus 5'))
|
||||
self.assertTrue(mocked_prepare_avd.called)
|
||||
|
||||
@mock.patch('builtins.open')
|
||||
@mock.patch('subprocess.Popen')
|
||||
@mock.patch('os.path.exists', mock.MagicMock(return_value=True))
|
||||
def test_run_next_run(self, mocked_open, mocked_subprocess):
|
||||
@mock.patch('builtins.open', mock_open(read_data="\nhw.device.name=Nexus 5\n"))
|
||||
def test_it_doesnt_prepare_avd_if_config_exists(self, mocked_subprocess):
|
||||
with mock.patch('src.app.prepare_avd') as mocked_prepare_avd:
|
||||
app.run()
|
||||
self.assertTrue(app.is_initialized())
|
||||
self.assertTrue(app.is_initialized('Nexus 5'))
|
||||
self.assertFalse(mocked_prepare_avd.called)
|
||||
|
||||
@mock.patch('subprocess.Popen')
|
||||
@mock.patch('os.path.exists', mock.MagicMock(return_value=True))
|
||||
@mock.patch('builtins.open', mock_open(read_data="\nhw.device.name=Samsung S7\n"))
|
||||
def test_it_prepares_avd_if_config_is_for_another_device(self, mocked_subprocess):
|
||||
with mock.patch('src.app.prepare_avd') as mocked_prepare_avd:
|
||||
app.run()
|
||||
self.assertFalse(app.is_initialized('Nexus 5'))
|
||||
self.assertTrue(mocked_prepare_avd.called)
|
||||
|
||||
@@ -18,7 +18,7 @@ class TestAvd(TestCase):
|
||||
def test_nexus_avd_as_default(self, mocked_suprocess, mocked_open):
|
||||
self.assertFalse(mocked_suprocess.called)
|
||||
self.assertFalse(mocked_open.called)
|
||||
app.prepare_avd('Nexus 5', self.avd_name)
|
||||
app.prepare_avd('Nexus 5', self.avd_name, '550m')
|
||||
self.assertTrue(mocked_suprocess.called)
|
||||
self.assertTrue(mocked_open.called)
|
||||
|
||||
@@ -28,7 +28,7 @@ class TestAvd(TestCase):
|
||||
self.assertFalse(mocked_sys_link.called)
|
||||
self.assertFalse(mocked_suprocess.called)
|
||||
self.assertFalse(mocked_open.called)
|
||||
app.prepare_avd('Samsung Galaxy S6', self.avd_name)
|
||||
app.prepare_avd('Samsung Galaxy S6', self.avd_name, '550m')
|
||||
self.assertTrue(mocked_sys_link.called)
|
||||
self.assertTrue(mocked_suprocess.called)
|
||||
self.assertTrue(mocked_open.called)
|
||||
|
||||
+2
-8
@@ -17,7 +17,7 @@ function wait_emulator_to_be_ready () {
|
||||
function change_language_if_needed() {
|
||||
if [ ! -z "${LANGUAGE// }" ] && [ ! -z "${COUNTRY// }" ]; then
|
||||
wait_emulator_to_be_ready
|
||||
echo "Languge will be changed to ${LANGUAGE}-${COUNTRY}"
|
||||
echo "Language will be changed to ${LANGUAGE}-${COUNTRY}"
|
||||
adb root && adb shell "setprop persist.sys.language $LANGUAGE; setprop persist.sys.country $COUNTRY; stop; start" && adb unroot
|
||||
echo "Language is changed!"
|
||||
fi
|
||||
@@ -55,15 +55,9 @@ function enable_proxy_if_needed () {
|
||||
echo "Enable proxy on Android emulator. Please make sure that docker-container has internet access!"
|
||||
adb root
|
||||
|
||||
echo "Mount system to read write access"
|
||||
adb shell "mount -o rw,remount /system"
|
||||
|
||||
echo "Updateing Proxy"
|
||||
|
||||
echo "Set up the Proxy"
|
||||
adb shell "content update --uri content://telephony/carriers --bind proxy:s:"${p[0]}" --bind port:s:"${p[1]}" --where "mcc=310" --where "mnc=260""
|
||||
|
||||
echo "remount system back to read only"
|
||||
adb shell "mount -o ro,remount /system"
|
||||
adb unroot
|
||||
else
|
||||
echo "Please use http:// in the beginning!"
|
||||
|
||||
@@ -43,6 +43,13 @@ stdout_logfile=%(ENV_LOG_PATH)s/android-screen-mirror.stdout.log
|
||||
stderr_logfile=%(ENV_LOG_PATH)s/android-screen-mirror.stderr.log
|
||||
priority=3
|
||||
|
||||
[program:atd]
|
||||
command=./src/atd.sh
|
||||
autorestart=false
|
||||
stdout_logfile=%(ENV_LOG_PATH)s/atd.stdout.log
|
||||
stderr_logfile=%(ENV_LOG_PATH)s/atd.stderr.log
|
||||
priority=4
|
||||
|
||||
[program:docker-appium]
|
||||
command=./src/appium.sh
|
||||
autorestart=false
|
||||
|
||||
Reference in New Issue
Block a user