9

Мы настраиваем сервер непрерывной интеграции для нашей разработки под Android, и мы быстро столкнулись с ожиданием проблем с устройством в АБР.

Напомним, что мы уже перепробовали множество комбинаций adb kill-server , adb start-server , adb devices и т.д. Безрезультатно.

К сожалению, все, что я нашел в интернете, это варианты "отключить и снова подключить устройство", что, очевидно, не является решением для нас (мы не можем позволить человеку сидеть рядом с сервером CI, чтобы отключить и снова подключить устройства перед каждая сборка).

В качестве предыстории мы используем Jenkins на Mac, поскольку он также запускает наш CI для iOS.

Подходя к проблеме, я подумал, что если на уровне ОС устройство найдено, то это как минимум начало. Действительно, выполнение такой команды, как system_profiler SPUSBDataType успешно находит устройство, включая серийный номер, который ADB сообщает при правильной работе.

Я попытался выполнить несколько довольно слабых команд, чтобы "обновить" всю активность USB, но я никуда не попал. Дело не в том, что вы можете монтировать / размонтировать устройство, но, честно говоря, я даже не уверен, в чем проблема, я недостаточно знаю о протоколах USB низкого уровня, не говоря уже о Mac. Мое скрытие исходного кода АБР было очень, очень длинным выстрелом.

Так что на данный момент я полностью заинтересован в решении, которое позволило бы нам постоянно запускать Android на нашем CI-сервере. Будь то несколько команд перед каждой работой Дженкинса, исправление ADB или любой другой фокус черной магии.

6 ответов6

9

Нашел способ ее решения, поэтому выкладываю сюда для полноты. Обратите внимание, что я не говорю, что это лучший способ решить эту проблему, но у нас это сработало.

Итак, мы поняли, что проблема возникла после длительных периодов бездействия КИ (в диапазоне часов). Поэтому мы создали простой скрипт, который вызывает adb devices каждые 10 секунд. И проблема исчезла, больше нет проблем с "ожиданием устройства".

В Linux вы можете сделать это с помощью простой задачи cron а в OSX - с launchctl и я уверен, что есть эквивалент Windows.

Несмотря на это, "пинг" устройств каждые 10 секунд решил для нас это.

5

Помогло включение отладки по USB (Настройки => Параметры разработчика) в телефоне.

1

У нас были некоторые похожие проблемы с нашей средой непрерывной интеграции с устройствами Android с машины OSX (также используемой как для iOS, так и для Android).

Я считаю, что проблема в том, что вы разрешаете Дженкинсу запускать сервер adb. Причины проблемы, потому что рабочие места Jenkins связаны с оболочками, которые входят и выходят из существования. Если Jenkins запускает демон adb с помощью вызова "adb devices" (например), тогда демон adb будет принадлежать какой-то недолгой оболочке Jenkins, а когда эта оболочка завершит работу и закроется, демон adb будет очищен До тех пор, пока он не будет запущен автоматически другим вызовом ADB. Это приводит к циклу запуска и остановки демона adb, но вам нужно, чтобы он просто оставался на неопределенное время.

Один из способов исправить это - просто запустить "adb devices" из оболочки, которая остается открытой на машине CI. Вы можете сказать, является ли это родительским процессом, по тому, отображается ли это сообщение после запуска

blah$ adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
xxxxxxxxxxx          device

Это раздражающий шаг, который приходится выполнять каждый раз, когда ваша машина перезагружается, и если кто-то закроет это командное окно, вы вернетесь к предыдущей проблеме.

Теоретически, лучшим способом было бы создать файл .plist для запуска демона adb при загрузке. Вот пример: ~/Library/LaunchAgents/server.adb.plist. Это в основном просто запускает adb start-server из демона запуска пользователя, чтобы избежать владения им у Jenkins.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>server.adb</string>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <false/>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/Shared/Jenkins/android-sdk/platform-tools/adb</string>
        <string>start-server</string>
    </array>
  </dict>
</plist>

Проблема с этим, однако, в том, что он просто запускает adb, но не блокирует, поэтому вы не можете использовать функцию контроля запуска KeepAlive. Кроме того, это, кажется, не работает для желаемой цели. Если кто-нибудь знает способ запуска adb в режиме "daemon", чтобы он не возвращался, то этот механизм launchctl может быть настроен на автоматический перезапуск, если он умрет, что гарантирует, что Jenkins никогда не получит право собственности. Ну что ж, сейчас я буду просто запускать "adb devices" в окне оболочки и оставлять его открытым.

0

Я просто хотел последовать прекрасному предложению Хуан-Дельгадо. Я обнаружил на MacOS High Sierra, что запуск adb каждые 10 секунд с помощью команды watch также был эффективным решением проблемы:

watch -n 10 adb -d devices

Это позволяет мне избежать создания файла .plist , но очевидным недостатком является то, что это не постоянное решение. Команда watch доступна в предыдущих версиях OSX, поэтому она также должна быть эффективной.

0

Решается здесь, меняя USB-кабель

0

Я решил эту проблему, используя программируемый удлинитель для перезагрузки USB-концентраторов перед каждым тестом. Это было то же самое, что отключить и снова подключить USB-кабели.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .