mirror of
https://github.com/budtmo/docker-android.git
synced 2026-02-06 11:26:45 +00:00
Merge branch 'budtmo:master' into master
This commit is contained in:
commit
6bb2e1cde7
42
.github/workflows/release.yml
vendored
42
.github/workflows/release.yml
vendored
@ -7,7 +7,7 @@ on:
|
||||
|
||||
jobs:
|
||||
run_test:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.8"]
|
||||
@ -15,23 +15,11 @@ jobs:
|
||||
- name: Checkout the repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
cd cli
|
||||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
||||
|
||||
- name: Run test
|
||||
run: |
|
||||
cd cli && nosetests -v
|
||||
- name: Run unit-test
|
||||
run: script -e -c "./app.sh test emulator test 11.0 && sudo mv tmp/* ."
|
||||
|
||||
release_base:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
needs: run_test
|
||||
steps:
|
||||
- name: Checkout the repo
|
||||
@ -47,7 +35,7 @@ jobs:
|
||||
docker logout
|
||||
|
||||
release_emulator:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
needs: release_base
|
||||
strategy:
|
||||
matrix:
|
||||
@ -56,9 +44,18 @@ jobs:
|
||||
- name: Checkout the repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Get release version
|
||||
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up extension
|
||||
run: |
|
||||
echo "${{ secrets.extension }}" > extension.sh
|
||||
chmod 700 extension.sh
|
||||
shell: bash
|
||||
|
||||
- name: Build and push emulator image ${{ matrix.android }} (${RELEASE_VERSION})
|
||||
run: |
|
||||
docker login -u=${{secrets.DOCKER_USERNAME}} -p=${{secrets.DOCKER_PASSWORD}}
|
||||
@ -66,15 +63,24 @@ jobs:
|
||||
docker logout
|
||||
|
||||
release_genymotion:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
needs: release_base
|
||||
steps:
|
||||
- name: Checkout the repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Get release version
|
||||
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up extension
|
||||
run: |
|
||||
echo "${{ secrets.extension }}" > extension.sh
|
||||
chmod 700 extension.sh
|
||||
shell: bash
|
||||
|
||||
- name: Build and push genymotion image (${RELEASE_VERSION})
|
||||
run: |
|
||||
docker login -u=${{secrets.DOCKER_USERNAME}} -p=${{secrets.DOCKER_PASSWORD}}
|
||||
|
||||
32
.github/workflows/test-on-demand.yml
vendored
Normal file
32
.github/workflows/test-on-demand.yml
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
name: Run Test on Demand
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build_and_test:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout the repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Set up extension
|
||||
run: |
|
||||
echo "${{ secrets.extension }}" > extension.sh
|
||||
chmod 700 extension.sh
|
||||
shell: bash
|
||||
|
||||
- name: Build base image
|
||||
run: script -e -c "./app.sh build base test"
|
||||
|
||||
- name: Build sample image
|
||||
run: script -e -c "./app.sh build emulator test 11.0"
|
||||
|
||||
- name: Run unit-test
|
||||
run: script -e -c "./app.sh test emulator test 11.0 && sudo mv tmp/* ."
|
||||
|
||||
- name: Publish test result
|
||||
run: bash <(curl -s https://codecov.io/bash)
|
||||
20
.github/workflows/test.yml
vendored
20
.github/workflows/test.yml
vendored
@ -4,21 +4,31 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build_and_test:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.actor == 'budtmo'
|
||||
steps:
|
||||
- name: Checkout the repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Set up extension
|
||||
run: |
|
||||
echo "${{ secrets.extension }}" > extension.sh
|
||||
chmod 700 extension.sh
|
||||
shell: bash
|
||||
|
||||
- name: Build base image
|
||||
run: script -e -c "./app.sh build base test"
|
||||
|
||||
- name: Build emulator image and run unit-test
|
||||
- name: Build sample image
|
||||
run: script -e -c "./app.sh build emulator test 11.0"
|
||||
|
||||
- name: Run unit-test
|
||||
run: script -e -c "./app.sh test emulator test 11.0 && sudo mv tmp/* ."
|
||||
|
||||
- name: Publish test result
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -17,4 +17,4 @@ tmp/
|
||||
|
||||
# Dev-files
|
||||
n*.txt
|
||||
test-*.sh
|
||||
e*.sh
|
||||
|
||||
@ -45,6 +45,7 @@ Phone | Nexus 5
|
||||
Phone | Nexus One
|
||||
Phone | Nexus S
|
||||
Tablet | Nexus 7
|
||||
Tablet | Pixel C
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
26
app.sh
26
app.sh
@ -81,9 +81,15 @@ echo "${IMAGE_NAME_SPECIFIC_RELEASE} or ${IMAGE_NAME_LATEST} "
|
||||
|
||||
function build() {
|
||||
# autopep8 --recursive --exclude=.git,__pycache__,venv --max-line-length=120 --in-place .
|
||||
cmd="docker build -t ${IMAGE_NAME_SPECIFIC_RELEASE} --build-arg DOCKER_ANDROID_VERSION=${r_v} "
|
||||
cmd="docker build --no-cache -t ${IMAGE_NAME_SPECIFIC_RELEASE} --build-arg DOCKER_ANDROID_VERSION=${r_v} "
|
||||
if [ -n "${a_v}" ]; then
|
||||
cmd+="--build-arg EMULATOR_ANDROID_VERSION=${a_v} --build-arg EMULATOR_API_LEVEL=${a_l} "
|
||||
DOCKER_BUILDKIT=1
|
||||
cmd="${cmd} --secret id=extension,src=extension.sh --build-arg EMULATOR_ANDROID_VERSION=${a_v} --build-arg EMULATOR_API_LEVEL=${a_l} "
|
||||
fi
|
||||
|
||||
if [[ "${p}" == *"genymotion"* ]]; then
|
||||
DOCKER_BUILDKIT=1
|
||||
cmd="${cmd} --secret id=extension,src=extension.sh "
|
||||
fi
|
||||
|
||||
cmd+="-f ${FOLDER_PATH} ."
|
||||
@ -97,18 +103,14 @@ function build() {
|
||||
}
|
||||
|
||||
function test() {
|
||||
cli_path="/home/androidusr/docker-android/cli"
|
||||
results_path="test-results"
|
||||
tmp_folder="tmp"
|
||||
tmp_folder="/app/tmp"
|
||||
|
||||
mkdir -p tmp
|
||||
build
|
||||
docker run -it --rm --name test --entrypoint /bin/bash \
|
||||
-v $PWD/${tmp_folder}:${cli_path}/${tmp_folder} ${IMAGE_NAME_SPECIFIC_RELEASE} \
|
||||
-c "cd ${cli_path} && sudo rm -rf ${tmp_folder}/* && \
|
||||
nosetests -v && sudo mv .coverage ${tmp_folder} && \
|
||||
sudo cp -r ${results_path}/* ${tmp_folder} && sudo chown -R 1300:1301 ${tmp_folder} &&
|
||||
sudo chmod a+x -R ${tmp_folder}"
|
||||
docker run -it --rm -v "$PWD":/app -w /app python:3.12-slim bash \
|
||||
-c "cd cli && rm -rf ${tmp_folder}/* && \
|
||||
pip install --upgrade pip && pip install -r requirements.txt && \
|
||||
PYTHONPATH=src pytest -v && mv test-results/* ${tmp_folder}/ && chown -R 1300:1301 ${tmp_folder} && \
|
||||
chmod a+x -R ${tmp_folder}"
|
||||
}
|
||||
|
||||
function push() {
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
autopep8==2.3.1
|
||||
click==8.1.8
|
||||
coverage==7.6.1
|
||||
mock==5.1.0
|
||||
nose==1.3.7
|
||||
autopep8==2.3.2
|
||||
click==8.2.1
|
||||
coverage==7.9.2
|
||||
mock==5.2.0
|
||||
pytest==8.4.1
|
||||
pytest-cov==6.2.1
|
||||
pytest-xdist==3.8.0
|
||||
requests==2.32.3
|
||||
setuptools==80.9.0
|
||||
|
||||
@ -1,10 +1,7 @@
|
||||
[nosetests]
|
||||
cover-xml=true
|
||||
cover-xml-file=test-results/coverage.xml
|
||||
with-coverage=true
|
||||
cover-package=src
|
||||
cover-erase=true
|
||||
with-xunit=true
|
||||
xunit-file=test-results/xunit.xml
|
||||
cover-html=true
|
||||
cover-html-dir=test-results/coverage
|
||||
[tool:pytest]
|
||||
addopts =
|
||||
--cov=src
|
||||
--cov-report=html:test-results/html
|
||||
--cov-report=xml:test-results/coverage.xml
|
||||
--junit-xml=test-results/junit-report.xml
|
||||
testpaths = src/tests
|
||||
|
||||
10
cli/setup.py
10
cli/setup.py
@ -1,6 +1,6 @@
|
||||
import os
|
||||
|
||||
from setuptools import setup
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
|
||||
app_version = os.getenv("DOCKER_ANDROID_VERSION", "test-version")
|
||||
@ -10,12 +10,14 @@ with open("requirements.txt", "r") as f:
|
||||
|
||||
setup(
|
||||
name="docker-android",
|
||||
version=app_version,
|
||||
version="0.1",
|
||||
url="https://github.com/budtmo/docker-android",
|
||||
description="CLI for docker-android",
|
||||
author="Budi Utomo",
|
||||
author_email="budtmo.os@gmail.com",
|
||||
install_requires=reqs,
|
||||
packages=find_packages(where="src"),
|
||||
package_dir={"": "src"},
|
||||
py_modules=["cli", "docker-android"],
|
||||
entry_points={"console_scripts": "docker-android=src.app:cli"}
|
||||
)
|
||||
entry_points={"console_scripts": "docker-android=app:cli"}
|
||||
)
|
||||
@ -8,14 +8,14 @@ import os
|
||||
|
||||
from enum import Enum
|
||||
|
||||
from src.application import Application
|
||||
from src.device import DeviceType
|
||||
from src.device.emulator import Emulator
|
||||
from src.device.geny_aws import GenyAWS
|
||||
from src.device.geny_saas import GenySAAS
|
||||
from src.helper import convert_str_to_bool, get_env_value_or_raise
|
||||
from src.constants import ENV
|
||||
from src.logger import log
|
||||
from application import Application
|
||||
from device import DeviceType
|
||||
from device.emulator import Emulator
|
||||
from device.geny_aws import GenyAWS
|
||||
from device.geny_saas import GenySAAS
|
||||
from helper import convert_str_to_bool, get_env_value_or_raise
|
||||
from constants import ENV
|
||||
from logger import log
|
||||
|
||||
log.init()
|
||||
logger = logging.getLogger("App")
|
||||
|
||||
@ -30,6 +30,7 @@ EMULATOR_IMG_TYPE = "EMULATOR_IMG_TYPE"
|
||||
EMULATOR_NAME = "EMULATOR_NAME"
|
||||
EMULATOR_NO_SKIN = "EMULATOR_NO_SKIN"
|
||||
EMULATOR_SYS_IMG = "EMULATOR_SYS_IMG"
|
||||
EMULATOR_CONFIG_PATH = "EMULATOR_CONFIG_PATH"
|
||||
|
||||
# Device (Genymotion - General)
|
||||
GENYMOTION_TEMPLATE_PATH = "GENYMOTION_TEMPLATE_PATH"
|
||||
@ -37,6 +38,7 @@ GENYMOTION_TEMPLATE_PATH = "GENYMOTION_TEMPLATE_PATH"
|
||||
# Device (Geny_SAAS)
|
||||
GENY_SAAS_USER = "GENY_SAAS_USER"
|
||||
GENY_SAAS_PASS = "GENY_SAAS_PASS"
|
||||
GENY_AUTH_TOKEN = "GENY_AUTH_TOKEN"
|
||||
GENY_SAAS_TEMPLATE_FILE_NAME = "saas.json"
|
||||
|
||||
# Device (Geny_AWS)
|
||||
|
||||
@ -9,8 +9,8 @@ import time
|
||||
from abc import ABC, abstractmethod
|
||||
from enum import Enum
|
||||
|
||||
from src.helper import convert_str_to_bool, get_env_value_or_raise
|
||||
from src.constants import DEVICE, ENV
|
||||
from helper import convert_str_to_bool, get_env_value_or_raise
|
||||
from constants import DEVICE, ENV
|
||||
|
||||
|
||||
class DeviceType(Enum):
|
||||
|
||||
@ -5,9 +5,9 @@ import time
|
||||
|
||||
from enum import Enum
|
||||
|
||||
from src.device import Device, DeviceType
|
||||
from src.helper import convert_str_to_bool, get_env_value_or_raise, symlink_force
|
||||
from src.constants import ENV, UTF8
|
||||
from device import Device, DeviceType
|
||||
from helper import convert_str_to_bool, get_env_value_or_raise, symlink_force
|
||||
from constants import ENV, UTF8
|
||||
|
||||
|
||||
class Emulator(Device):
|
||||
@ -22,7 +22,8 @@ class Emulator(Device):
|
||||
"Samsung Galaxy S7 Edge",
|
||||
"Samsung Galaxy S8",
|
||||
"Samsung Galaxy S9",
|
||||
"Samsung Galaxy S10"
|
||||
"Samsung Galaxy S10",
|
||||
"Pixel C"
|
||||
)
|
||||
|
||||
API_LEVEL = {
|
||||
@ -108,6 +109,30 @@ class Emulator(Device):
|
||||
symlink_force(path_device_profile_source, self.path_device_profile_target)
|
||||
self.logger.info("Samsung device profile is linked")
|
||||
|
||||
def _use_override_config(self) -> None:
|
||||
override_confg_path = os.getenv(ENV.EMULATOR_CONFIG_PATH)
|
||||
|
||||
if override_confg_path is None:
|
||||
self.logger.info(f"The environment variable 'EMULATOR_CONFIG_PATH' is not set")
|
||||
return
|
||||
|
||||
self.logger.info(f"Environment variable 'EMULATOR_CONFIG_PATH' found: {override_confg_path}")
|
||||
|
||||
if not os.path.isfile(override_confg_path):
|
||||
self.logger.warning(f"Source file '{override_confg_path}' does not exist.")
|
||||
return
|
||||
|
||||
if not os.access(override_confg_path, os.R_OK):
|
||||
self.logger.warning(f"Source file '{override_confg_path}' is not readable.")
|
||||
return
|
||||
|
||||
try:
|
||||
with open(override_confg_path, 'r') as src, open(self.path_emulator_config, 'a') as dst:
|
||||
dst.write(src.read())
|
||||
self.logger.info(f"Content from '{override_confg_path}' successfully appended to '{self.path_emulator_config}'.")
|
||||
except Exception as e:
|
||||
self.logger.error(f"An error occurred while copying file content: {e}")
|
||||
|
||||
def _add_skin(self) -> None:
|
||||
device_skin_path = os.path.join(
|
||||
self.path_emulator_skins, "{fn}".format(fn=self.file_name))
|
||||
@ -132,6 +157,7 @@ class Emulator(Device):
|
||||
self.logger.info(f"Command to create emulator: '{creation_cmd}'")
|
||||
subprocess.check_call(creation_cmd, shell=True)
|
||||
self._add_skin()
|
||||
self._use_override_config()
|
||||
self.logger.info(f"{self.device_type} is created!")
|
||||
|
||||
def change_permission(self) -> None:
|
||||
|
||||
@ -5,9 +5,9 @@ import shutil
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
from src.device import Genymotion, DeviceType
|
||||
from src.helper import get_env_value_or_raise
|
||||
from src.constants import ENV, UTF8
|
||||
from device import Genymotion, DeviceType
|
||||
from helper import get_env_value_or_raise
|
||||
from constants import ENV, UTF8
|
||||
|
||||
|
||||
class GenyAWS(Genymotion):
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from src.device import Genymotion, DeviceType
|
||||
from src.helper import get_env_value_or_raise
|
||||
from src.constants import ENV, UTF8
|
||||
from device import Genymotion, DeviceType
|
||||
from helper import get_env_value_or_raise
|
||||
from constants import ENV, UTF8
|
||||
|
||||
|
||||
class GenySAAS(Genymotion):
|
||||
@ -14,9 +15,13 @@ class GenySAAS(Genymotion):
|
||||
self.created_devices = []
|
||||
|
||||
def login(self) -> None:
|
||||
user = get_env_value_or_raise(ENV.GENY_SAAS_USER)
|
||||
password = get_env_value_or_raise(ENV.GENY_SAAS_PASS)
|
||||
subprocess.check_call(f"gmsaas auth login {user} {password} > /dev/null 2>&1", shell=True)
|
||||
if os.getenv(ENV.GENY_AUTH_TOKEN):
|
||||
auth_token = get_env_value_or_raise(ENV.GENY_AUTH_TOKEN)
|
||||
subprocess.check_call(f"gmsaas auth token {auth_token} > /dev/null 2>&1", shell=True)
|
||||
else:
|
||||
user = get_env_value_or_raise(ENV.GENY_SAAS_USER)
|
||||
password = get_env_value_or_raise(ENV.GENY_SAAS_PASS)
|
||||
subprocess.check_call(f"gmsaas auth login {user} {password} > /dev/null 2>&1", shell=True)
|
||||
self.logger.info("successfully logged in!")
|
||||
|
||||
def create(self) -> None:
|
||||
@ -68,5 +73,8 @@ class GenySAAS(Genymotion):
|
||||
for n, i in d.items():
|
||||
subprocess.check_call(f"gmsaas instances stop {i}", shell=True)
|
||||
self.logger.info(f"device '{n}' is successfully removed!")
|
||||
subprocess.check_call("gmsaas auth logout", shell=True)
|
||||
if os.getenv(ENV.GENY_AUTH_TOKEN):
|
||||
subprocess.check_call("gmsaas auth reset", shell=True)
|
||||
else:
|
||||
subprocess.check_call("gmsaas auth logout", shell=True)
|
||||
self.logger.info("successfully logged out!")
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import logging.config
|
||||
|
||||
from src.logger import LOGGING_FILE
|
||||
from logger import LOGGING_FILE
|
||||
|
||||
|
||||
def init():
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import os
|
||||
|
||||
from src.constants import ENV
|
||||
from src.tests import BaseTest
|
||||
from constants import ENV
|
||||
from tests import BaseTest
|
||||
|
||||
|
||||
class BaseDeviceTest(BaseTest):
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
from src.device import Device
|
||||
from src.tests.device import BaseDeviceTest
|
||||
from device import Device
|
||||
from tests.device import BaseDeviceTest
|
||||
|
||||
|
||||
class TestDevice(BaseDeviceTest):
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import mock
|
||||
|
||||
from src.device.emulator import Emulator
|
||||
from src.tests.device import BaseDeviceTest
|
||||
from device.emulator import Emulator
|
||||
from tests.device import BaseDeviceTest
|
||||
|
||||
|
||||
class TestEmulator(BaseDeviceTest):
|
||||
@ -52,29 +52,6 @@ class TestEmulator(BaseDeviceTest):
|
||||
def test_initialisation_device_exists(self):
|
||||
self.assertEqual(self.emu.is_initialized(), True)
|
||||
|
||||
@mock.patch("src.device.Device.set_status")
|
||||
@mock.patch("src.device.emulator.Emulator._add_profile")
|
||||
@mock.patch("subprocess.check_call")
|
||||
@mock.patch("src.device.emulator.Emulator._add_skin")
|
||||
@mock.patch("src.device.emulator.Emulator.is_initialized", mock.MagicMock(return_value=False))
|
||||
def test_create_device_not_exist(self, mocked_status, mocked_profile, mocked_subprocess, mocked_skin):
|
||||
self.emu.create()
|
||||
self.assertEqual(mocked_status.called, True)
|
||||
self.assertEqual(mocked_profile.called, True)
|
||||
self.assertEqual(mocked_subprocess.called, True)
|
||||
self.assertEqual(mocked_skin.called, True)
|
||||
|
||||
@mock.patch("src.device.Device.set_status")
|
||||
@mock.patch("src.device.emulator.Emulator._add_profile")
|
||||
@mock.patch("subprocess.check_call")
|
||||
@mock.patch("src.device.emulator.Emulator._add_skin")
|
||||
@mock.patch("src.device.emulator.Emulator.is_initialized", mock.MagicMock(return_value=True))
|
||||
def test_create_device_exists(self, mocked_status, mocked_profile, mocked_subprocess, mocked_skin):
|
||||
self.emu.create()
|
||||
self.assertEqual(mocked_status.called, False)
|
||||
self.assertEqual(mocked_profile.called, False)
|
||||
self.assertEqual(mocked_subprocess.called, False)
|
||||
|
||||
def test_check_adb_command(self):
|
||||
with mock.patch("subprocess.check_output", mock.MagicMock(return_value="1".encode("utf-8"))):
|
||||
self.emu.check_adb_command(
|
||||
@ -85,3 +62,25 @@ class TestEmulator(BaseDeviceTest):
|
||||
with self.assertRaises(RuntimeError):
|
||||
self.emu.check_adb_command(
|
||||
self.emu.ReadinessCheck.BOOTED, "mocked_command", "1", 3, 0)
|
||||
|
||||
def test_use_override_config_no_env(self):
|
||||
with mock.patch("os.getenv", return_value=None):
|
||||
self.emu._use_override_config()
|
||||
|
||||
def test_use_override_config_file_not_exist(self):
|
||||
with mock.patch("os.getenv", return_value="mock/path/to/config"):
|
||||
with mock.patch("os.path.isfile", return_value=False):
|
||||
self.emu._use_override_config()
|
||||
|
||||
def test_use_override_config_file_not_readable(self):
|
||||
with mock.patch("os.getenv", return_value="mock/path/to/config"):
|
||||
with mock.patch("os.path.isfile", return_value=True):
|
||||
with mock.patch("os.access", return_value=False):
|
||||
self.emu._use_override_config()
|
||||
|
||||
def test_use_override_config_malformed_content(self):
|
||||
with mock.patch("os.getenv", return_value="mock/path/to/config"):
|
||||
with mock.patch("os.path.isfile", return_value=True):
|
||||
with mock.patch("os.access", return_value=True):
|
||||
with mock.patch("builtins.open", mock.mock_open(read_data="malformed data")):
|
||||
self.emu._use_override_config()
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import os
|
||||
import mock
|
||||
|
||||
from src.helper import convert_str_to_bool, get_env_value_or_raise, symlink_force
|
||||
from src.tests import BaseTest
|
||||
from helper import convert_str_to_bool, get_env_value_or_raise, symlink_force
|
||||
from tests import BaseTest
|
||||
|
||||
|
||||
class TestHelperMethods(BaseTest):
|
||||
@ -45,10 +45,6 @@ class TestHelperMethods(BaseTest):
|
||||
with self.assertRaises(RuntimeError):
|
||||
get_env_value_or_raise("env_key02")
|
||||
|
||||
def test_get_env_value_with_invalid_format(self):
|
||||
with mock.patch("src.logger"):
|
||||
get_env_value_or_raise(True)
|
||||
|
||||
def test_symlink(self):
|
||||
s = os.path.join("source.txt")
|
||||
t = os.path.join("target_file.txt")
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
FROM appium/appium:v2.15.0-p1
|
||||
FROM appium/appium:v2.19.0-p0
|
||||
|
||||
LABEL maintainer "Budi Utomo <budtmo.os@gmail.com>"
|
||||
ARG AUTHORS="Budi Utomo"
|
||||
LABEL author="${AUTHORS} <budtmo.os@gmail.com>"
|
||||
|
||||
USER root
|
||||
|
||||
|
||||
@ -83,8 +83,8 @@ ENV APP_PATH=${WORK_PATH}/${SCRIPT_PATH}
|
||||
RUN mkdir -p ${APP_PATH}
|
||||
COPY mixins ${APP_PATH}/mixins
|
||||
COPY cli ${APP_PATH}/cli
|
||||
RUN chown -R 1300:1301 ${APP_PATH} \
|
||||
&& pip install --quiet -e ${APP_PATH}/cli
|
||||
RUN --mount=type=secret,id=extension,dst=/tmp/extension.sh \
|
||||
bash /tmp/extension.sh
|
||||
|
||||
#===================
|
||||
# Configure OpenBox
|
||||
|
||||
@ -1,12 +1,7 @@
|
||||
ARG DOCKER_ANDROID_VERSION
|
||||
FROM budtmo/docker-android:base_${DOCKER_ANDROID_VERSION}
|
||||
|
||||
#===================================================
|
||||
# Install Genymotion CLI
|
||||
# (for user management and deployment on Geny Cloud)
|
||||
#===================================================
|
||||
ENV GMSAAS_CLI_VERSION="1.7.1"
|
||||
RUN pip install gmsaas==${GMSAAS_CLI_VERSION}
|
||||
ENV GMSAAS_CLI_VERSION="1.14.1"
|
||||
|
||||
#================
|
||||
# Cloud Packages
|
||||
@ -40,8 +35,8 @@ ENV APP_PATH=${WORK_PATH}/${SCRIPT_PATH}
|
||||
RUN mkdir -p ${APP_PATH}
|
||||
COPY mixins ${APP_PATH}/mixins
|
||||
COPY cli ${APP_PATH}/cli
|
||||
RUN chown -R 1300:1301 ${APP_PATH} \
|
||||
&& pip install --quiet -e ${APP_PATH}/cli
|
||||
RUN --mount=type=secret,id=extension,dst=/tmp/extension.sh \
|
||||
bash /tmp/extension.sh
|
||||
|
||||
#===================================
|
||||
# Create Genymotion Template folder
|
||||
|
||||
@ -57,5 +57,18 @@ Possible environment variable to configure the Emulator:
|
||||
|
||||
The user can also pass needed arguments to android emulator through environment variable ***EMULATOR_ADDITIONAL_ARGS***. Please check [this page](https://developer.android.com/studio/run/emulator-commandline) for possible arguments that can be passed.
|
||||
|
||||
EMULATOR - OVERRIDE CONFIG FILE
|
||||
-------------------------------
|
||||
|
||||
To utilize this feature, ensure the following setup:
|
||||
|
||||
- Set the config file path into environment variable EMULATOR_CONFIG_PATH, eg. `/tmp/emulator-override-config.ini` (the file name doesn't matter)
|
||||
- Mount the file as Docker volume (parameter `-v` for Docker run command) to the path as you set into ENV
|
||||
|
||||
Example:
|
||||
|
||||
```shell
|
||||
docker run -d -p 6080:6080 -e /tmp/emulator-override-config.ini -v /path/on/your/machine/emulator-override-config.ini:/tmp/emulator-override-config.ini -e EMULATOR_DEVICE="Samsung Galaxy S10" -e WEB_VNC=true --device /dev/kvm --name android-container budtmo/docker-android:emulator_14.0
|
||||
```
|
||||
|
||||
[<- BACK TO README](../README.md)
|
||||
|
||||
@ -59,6 +59,7 @@ Phone | Nexus 5
|
||||
Phone | Nexus One
|
||||
Phone | Nexus S
|
||||
Tablet | Nexus 7
|
||||
Tablet | Pixel C
|
||||
|
||||
|
||||
Proxy
|
||||
|
||||
@ -1,3 +1,9 @@
|
||||
```
|
||||
export USER="xxx"
|
||||
export PASS="xxx"
|
||||
|
||||
docker run -d -p 4723:4723 -v ${PWD}/example/genycloud/saas.json:/home/androidusr/genymotion_template/saas.json -e DEVICE_TYPE=geny_saas -e GENY_SAAS_USER=${USER} -e GENY_SAAS_PASS=${PASS} -e APPIUM=true --name android-container budtmo/docker-android:genymotion
|
||||
```
|
||||
Genymotion Cloud
|
||||
----------------
|
||||
|
||||
@ -9,12 +15,13 @@ You can use Genymotion Android virtual devices in the cloud. They are available
|
||||
Use [saas.json](../example/genymotion/saas.json) to define the devices that you want to use. You can specify the port on which the device will start so you don't need to change the device name in your tests every time you need to run those tests. Then run following command
|
||||
|
||||
```
|
||||
export USER="xxx"
|
||||
export PASS="xxx"
|
||||
export AUTH_TOKEN="xxx"
|
||||
|
||||
docker run -d -p 4723:4723 -v ${PWD}/example/genycloud/saas.json:/home/androidusr/genymotion_template/saas.json -e DEVICE_TYPE=geny_saas -e GENY_SAAS_USER=${USER} -e GENY_SAAS_PASS=${PASS} -e APPIUM=true --name android-container budtmo/docker-android:genymotion
|
||||
docker run -d -p 4723:4723 -v ${PWD}/example/genycloud/saas.json:/home/androidusr/genymotion_template/saas.json -e DEVICE_TYPE=geny_saas -e GENY_AUTH_TOKEN=${AUTH_TOKEN} -e APPIUM=true --name android-container budtmo/docker-android:genymotion
|
||||
```
|
||||
|
||||
Genymotion has deprecated credential based login since gmsaas 1.10.0, but if necessary, you can still provide them using `-e GENY_SAAS_USER=${USER} -e GENY_SAAS_PASS=${PASS}` instead of `-e GENY_AUTH_TOKEN=${AUTH_TOKEN}`.
|
||||
|
||||
The deployed device(s) are automatically connected with adb inside docker container. Stopping the emulator will remove all deployed device(s) on Genymotion SaaS and user will be logged out at the end.
|
||||
|
||||
```
|
||||
|
||||
Loading…
Reference in New Issue
Block a user