Slide 1

Slide 1 text

Build your APK beyond Docker Misumi_Rize / Docker࣮ફLT (Oct. 14, 2015)

Slide 2

Slide 2 text

Log.d("introduction", me); → Twitter @Misumi_Rize → GitHub @MisumiRize → I'm not Android APK developer

Slide 3

Slide 3 text

Software Engineer in Test

Slide 4

Slide 4 text

Testing strategy 1. Unit tests 2. Instrumentation tests 3. Acceptance tests 4. Exploratory tests

Slide 5

Slide 5 text

Testing tools 1. JUnit, Mockito 2. Espresso 3. UIAutomator, Appium 4. Human power

Slide 6

Slide 6 text

Testing APK is difficult → Developer specific problem → CI service specific problem → APK's state (SQLite, Preference, etc.)

Slide 7

Slide 7 text

Container CI

Slide 8

Slide 8 text

Container as CI Service → Docker as a function (Travis CI, CircleCI, Wercker) → Based on Docker (Drone)

Slide 9

Slide 9 text

Docker is protocol

Slide 10

Slide 10 text

https://hub.docker.com/r/misumirize/android-sdk https://github.com/MisumiRize/dockerfiles/tree/ master/android-sdk

Slide 11

Slide 11 text

FROM misumirize/android-sdk RUN mkdir /project COPY . /project WORKDIR /project RUN echo "sdk.dir=$ANDROID_HOME" > local.properties ENTRYPOINT ["./gradlew"] CMD ["tasks"]

Slide 12

Slide 12 text

Run unit tests and generate APK $ docker build -t android-build . $ docker run android-build build

Slide 13

Slide 13 text

How can we automate Activity tests?

Slide 14

Slide 14 text

Too slow and frustrating ARM emulator cf. Travis CI $ echo no | android create avd --force \ --name test --target android-23 --abi armeabi-v7a $ emulator64-arm -avd test -no-skin -no-audio -no-window & $ android-wait-for-emulator $ adb shell input keyevent 82 & $ ./gradlew connectedCheck

Slide 15

Slide 15 text

Can we connect to another host (e.g. which real device is connected) from container?

Slide 16

Slide 16 text

Problem: → ./gradlew connectedCheck wraps ADB client → We can't configure the host of ADB client → ADB server binds to the loopback address only

Slide 17

Slide 17 text

Solution: HAProxy

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

Client (container) frontend local_adb_server bind 127.0.0.1:5037 mode tcp default_backend remote_adb_server backend remote_adb_server mode tcp server remote01 123.45.67.89:5036 check

Slide 20

Slide 20 text

Server (devices connected) frontend remote_adb_server bind *:5036 mode tcp default_backend internal_adb_server backend internal_adb_server mode tcp server internal01 127.0.0.1:5037 check

Slide 21

Slide 21 text

Separating role is important

Slide 22

Slide 22 text

https://hub.docker.com/r/misumirize/android- remote-client https://github.com/MisumiRize/dockerfiles/tree/ master/android-remote-client

Slide 23

Slide 23 text

FROM misumirize/android-remote-client CMD ["connectedAndroidTest", "--stacktrace"]

Slide 24

Slide 24 text

misumirize/android-remote-client ONBUILD COPY haproxy.cfg /etc/haproxy/haproxy.cfg ONBUILD COPY . /project WORKDIR /project ONBUILD RUN echo "sdk.dir=$ANDROID_HOME" > local.properties ENTRYPOINT ["execute-remote"]

Slide 25

Slide 25 text

ONBUILD is awesome!

Slide 26

Slide 26 text

But a little dirty hack is needed... build.gradle com.android.ddmlib.DdmPreferences.setTimeOut(60000)

Slide 27

Slide 27 text

Example: Connect Docker (CircleCI) and DigitalOcean Droplet (Android Atom emulator working)

Slide 28

Slide 28 text

Example https://github.com/MisumiRize/HackerNews- Android https://circleci.com/gh/MisumiRize/HackerNews- Android/22 → circle.yml → Vagrantfile

Slide 29

Slide 29 text

Conclusion → Docker is protocol → Separating role (even forcefully) is important → ONBUILD is useful. Consider using ONBUILD

Slide 30

Slide 30 text

Thank you!

Slide 31

Slide 31 text

→ Android Lineup - Shadow by Rob Bulmahn → Desastrosos by srgpicker → cyclotron by Robert Couse-Baker → Containing the containers by Erik Söderström → Nexus 7 with Android 5 by Yuri Samoilov → IMAG0191 by Robert → Hornby Separated Bike Lane by Paul Krueger → A Street Called Awesome by Selena N. B. H.