Tuesday, February 14, 2017

CircleCI: waiting for Android emulator with Google Play Services to fully boot

The standard circle-android wait-for-boot command works quite well for a vanilla Android image. However, when starting to use google_apis images (those which include Google Play Services, necessary to test e.g. Firebase-enabled apps), the performance of the emulator right after boot is very slow. Lots of services try to start up simultaneously, consuming all available CPU power, which is already not a lot on a free CircleCI container. This results in flaky tests because of timeouts, ANRs of the tested app because of insufficient CPU power, and crashes.

It might seem easy to resolve by saving a snapshot of a fully-booted Android emulator into CircleCI cache, but snapshots are proven to be unstable and crash the device upon load. It's not very convenient on a CI because makes the tests unnecessarily flaky.

One stable way to wait until everything has settled down is to monitor emulator logs with adb logcat command. Once the log spam goes down, it is very likely that most of the work is finished.

Below a small snippet that implements this kind of wait. As a bonus, it keeps logcat entries, which are actually related to the test, separate from that of the other services. Oh and don't forget to unlock the screen, as it might autolock while we wait, and interfere with your tests!

On an Android SDK 19 image the waiting time is about 6 minutes.