web-dev-qa-db-ja.com

AndroidテストはShellCommandUnresponsiveExceptionでTravisで失敗します

TravisでのAndroidプロジェクトのプルリクエストの最初と2回目の実行で、ビルドの失敗がたくさん見られます。ただし、まったく同じビルドを十分な回数再起動すると、最終的には合格します。

失敗した場合のエラーは次のようになります。

:onebusaway-Android:connectedAndroidTest
09:48:14 E/Device: Error during Shell execution: null
Unable to install /home/travis/build/OneBusAway/onebusaway-Android/onebusaway-Android/build/outputs/apk/onebusaway-Android-debug.apk
com.Android.ddmlib.InstallException
at com.Android.ddmlib.Device.installPackages(Device.Java:927)
at com.Android.builder.testing.ConnectedDevice.installPackages(ConnectedDevice.Java:105)
at com.Android.builder.internal.testing.SimpleTestCallable.call(SimpleTestCallable.Java:125)
at com.Android.builder.internal.testing.SimpleTestCallable.call(SimpleTestCallable.Java:48)
at Java.util.concurrent.FutureTask.run(FutureTask.Java:262)
at Java.util.concurrent.Executors$RunnableAdapter.call(Executors.Java:471)
at Java.util.concurrent.FutureTask.run(FutureTask.Java:262)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1145)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:615)
at Java.lang.Thread.run(Thread.Java:745)
Caused by: com.Android.ddmlib.ShellCommandUnresponsiveException
at com.Android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.Java:513)
at com.Android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.Java:390)
at com.Android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.Java:359)
at com.Android.ddmlib.Device.executeShellCommand(Device.Java:566)
at com.Android.ddmlib.Device.createMultiInstallSession(Device.Java:987)
at com.Android.ddmlib.Device.installPackages(Device.Java:884)
... 9 more
com.Android.builder.testing.ConnectedDevice > runTests[test(AVD) - 5.0.1] FAILED 
com.Android.builder.testing.api.DeviceException: com.Android.ddmlib.InstallException
    at com.Android.builder.testing.ConnectedDevice.installPackages(ConnectedDevice.Java:108)
null
com.Android.builder.testing.api.DeviceException: com.Android.ddmlib.InstallException
at com.Android.builder.testing.ConnectedDevice.installPackages(ConnectedDevice.Java:108)
at com.Android.builder.internal.testing.SimpleTestCallable.call(SimpleTestCallable.Java:125)
at com.Android.builder.internal.testing.SimpleTestCallable.call(SimpleTestCallable.Java:48)
at Java.util.concurrent.FutureTask.run(FutureTask.Java:262)
at Java.util.concurrent.Executors$RunnableAdapter.call(Executors.Java:471)
at Java.util.concurrent.FutureTask.run(FutureTask.Java:262)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1145)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:615)
at Java.lang.Thread.run(Thread.Java:745)
Caused by: com.Android.ddmlib.InstallException
at com.Android.ddmlib.Device.installPackages(Device.Java:927)
at     com.Android.builder.testing.ConnectedDevice.installPackages(ConnectedDevice.Java:105)
... 8 more
Caused by: com.Android.ddmlib.ShellCommandUnresponsiveException
at com.Android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.Java:513)
at com.Android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.Java:390)
at com.Android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.Java:359)
at com.Android.ddmlib.Device.executeShellCommand(Device.Java:566)
at com.Android.ddmlib.Device.createMultiInstallSession(Device.Java:987)
at com.Android.ddmlib.Device.installPackages(Device.Java:884)
... 9 more
:onebusaway-Android:connectedAndroidTest FAILED
FAILURE: Build failed with an exception.

gradlew connectedTestを使用して、Travisのエミュレーターでテストを実行しています。

これが私たちの.travis.ymlです:

# Test format changes to this .travis.yml file before submitting a PR with:
# http://lint.travis-ci.org/OneBusAway/onebusaway-Android

language: Android
jdk: oraclejdk7
# Turn off caching to avoid any caching problems
cache: false
# Use the Travis Container-Based Infrastructure (see #203)
Sudo: false
env:
  global:
    - Android_API_LEVEL=21
    - Android_BUILD_TOOLS_VERSION=21.1.2
    - Android_ABI=google_apis/armeabi-v7a

Android:
  components:
    - platform-tools
    - tools
    - build-tools-$Android_BUILD_TOOLS_VERSION
    - Android-$Android_API_LEVEL
    # For Google Maps API v1
    - addon-google_apis-google-$Android_API_LEVEL
    # Google Play Services
    - extra-google-google_play_services
    # Support library
    - extra-Android-support
    # Latest artifacts in local repository
    - extra-google-m2repository
    - extra-Android-m2repository
    # Specify at least one system image
    - sys-img-armeabi-v7a-addon-google_apis-google-$Android_API_LEVEL

before_script:
  # Create and start emulator
  - echo no | Android create avd --force -n test -t "Google Inc.:Google APIs:"$Android_API_LEVEL --abi $Android_ABI
  - emulator -avd test -no-skin -no-audio -no-window &

script:
  - ./wait_for_emulator
  - ./gradlew connectedCheck -PdisablePreDex

# Integration with Gitter (https://gitter.im/OneBusAway/onebusaway-Android)
notifications:
  webhooks:
    urls:
      - https://webhooks.gitter.im/e/493b93a98ed03a010c4c
    on_success: change  # options: [always|never|change] default: always
    on_failure: always  # options: [always|never|change] default: always
    on_start: false     # default: false
20
Sean Barbeau

この問題を回避するために、Travisの環境変数ADB_INSTALL_TIMEOUTを8分などの値に設定できます。

たとえば、.travis.ymlでは次のようになります。

language: Android
jdk: oraclejdk7
# Turn off caching to avoid any caching problems
cache: false
# Use the Travis Container-Based Infrastructure
Sudo: false
env:
  global:
    - Android_API_LEVEL=21
    - Android_BUILD_TOOLS_VERSION=21.1.2
    - Android_ABI=armeabi-v7a
    - ADB_INSTALL_TIMEOUT=8 # minutes (2 minutes by default)

Android:
  components:
    - platform-tools
    - tools
    - build-tools-$Android_BUILD_TOOLS_VERSION
    - Android-$Android_API_LEVEL

ShellCommandUnresponsiveExceptionAOSP問題69735:DdmlibがDevice.Javaのタイムアウトで攻撃的すぎる に関連しているため、入力を受け取らない場合、ddmlibはすぐにタイムアウトします。上記の環境変数は、TravisVMでこのタイムアウト期間を延長します。

また、以前のバージョンではこの環境変数の設定が許可されていないため、最新のAPIレベルのSDKおよびビルドツール(少なくとも上記のバージョン)を使用していることを確認してください。

これは、テストが時々Travisに合格した場合にのみ問題を解決する可能性があることに注意してください。ビルドが常に失敗する場合は、他の問題が発生している可能性があります。

2016年3月編集

特にAPIレベル23エミュレーターで引き続き障害が発生する場合は、問題を引き起こしている可能性のある別のエミュレータータイムアウトの問題があることに注意してください。

これを回避するには、Gradleプラグインを少なくとも2.0.0-beta3に更新する必要があります-例:

dependencies {
    classpath 'com.Android.tools.build:gradle:2.0.0-beta5'
}

詳細については、以下を参照してください。

19
Sean Barbeau