Application Bundles Caching Logic
Appium Base driver provides a feature which enables caching of application builds provided, for example,
app capability value or to endpoints similar to the
installApp one. This article explains common caching
principles, so you could create more performant and efficient test suite execution strategies.
Why Caching Is Necessary
Mobile application bundles could reach hundreds of megabytes is size. This could become a serious performance issue if a test suite is executed, and it is necessary to fetch/extract the same application bundle for each test.
What Is Cached
Caching could be applied to application bundles generated by
configureApp helper call. Inherited drivers
can customize their caching logic by providing own
onPostProcess property definition, but the general
rule of thumb is that we need to cache locally all application bundles need to be downloaded and/or extracted
first before they could be actually installed on the device under test. On iOS, for example, these are .ipa or
.zip compressed application bundles or .aab on Android.
How Remote Application Bundles Are Cached
In order to validate whether an app bundle downloaded from the given URL could be (re)used from the cache the following steps are applied:
- The script is sending
HEADrequest to the given link in order to only fetch response headers. If this request fails/ times out then no caching is applied.
- The following header values are being extracted:
Cache-Control. If no
Last-Modifiedheader is present or the header value cannot be parsed as a valid datetime then no caching is applied.
- The script checks if the given URL is already present in the cache. If the app is not cached yet then it gets downloaded and its current header values along with hashsum are added to the cache.
- If the URL was already in the cache then the script verifies that:
- the current
Last-Modifieddatetime is not different from the previous one
- the difference between the current
Last-Modifieddatetime and the cached one is not greater than max-age (if present)
- the hashsum of the cached file/folder is not changed (e.g. it was not corrupted while sitting in the cache)
- If all validations above succeed then the cached build is returned, otherwise the currently cached entry gets deleted and a new one is downloaded instead.
How Local Application Bundles Are Cached
It only makes sense to cache application bundles if they need some preprocessing before being installed on the device under test. For example, on iOS .ipa bundles must be unzipped, because the system installer only works with .app folders.
- The script verifies if the given bundle path is already present in the cache. If the bundle was not in the cache yet then it gets preprocessed and added there.
- The script validates the hashsum of the bundle and compares it to the previously stored one. If hash sums don't match then the cached item gets deleted and the preprocessing of the bundle repeats.
How The Cache File System Is Configured
The cache where the base driver keeps all application bundles is located in the system temp folder. It is configured on per-process basis, so each test session initialized in scope of the same Appium server process takes advantages of it. It is a LRU Cache with the following limitations:
- Max items: 1024
- Max time to live (TTL) for each entry: 24 hours
- TTL is refreshed for each entry upon access
Note: The cache root folder is set up for automatic deletion on Appium process termination. This would only work if Appium server is killed with SIGINT or SIGTERM. If SIGKILL is used then no cache cleanup would be performed.