Skip to content

Commit

Permalink
Get coroutines back
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivan Dyatlov committed Jul 2, 2024
1 parent 04ab876 commit 53a2d23
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.malinskiy.marathon.android
import com.android.ddmlib.InstallException
import com.malinskiy.marathon.analytics.internal.pub.Track
import com.malinskiy.marathon.execution.Configuration
import com.malinskiy.marathon.execution.withRetry
import com.malinskiy.marathon.io.FileHasher
import com.malinskiy.marathon.log.MarathonLogging
import kotlinx.coroutines.runBlocking
Expand All @@ -26,7 +27,7 @@ class AndroidAppInstaller(
private val androidConfiguration = configuration.vendorConfiguration as AndroidConfiguration
private val installedApps: MutableMap<String, MutableMap<String, String>> = hashMapOf()

fun ensureInstalled(device: AndroidDevice, componentInfo: AndroidComponentInfo) {
suspend fun ensureInstalled(device: AndroidDevice, componentInfo: AndroidComponentInfo) {
val applicationInfo = ApkParser().parseInstrumentationInfo(componentInfo.testApplicationOutput)
logger.debug { "Installing application output to ${device.serialNumber}" }
componentInfo.applicationOutput?.let {
Expand All @@ -42,45 +43,51 @@ class AndroidAppInstaller(
}

@Suppress("TooGenericExceptionThrown")
private fun ensureInstalled(device: AndroidDevice, appPackage: String, appApk: File) {
try {
val checkStarted = Instant.now()
val fileHash = runBlocking { fileHasher.getHash(appApk) }
val isApkInstalled = isApkInstalled(device, appPackage, fileHash)
track.installationCheck(device.serialNumber, checkStarted, Instant.now())

if (isApkInstalled) {
logger.info("Skipping installation of $appPackage on ${device.serialNumber} - APK is already installed")
} else {
logger.info("Installing $appPackage, ${appApk.absolutePath} to ${device.serialNumber}")
val installationStarted = Instant.now()
val installMessage = device.safeInstallPackage(appApk.absolutePath, true, optionalParams(device))
installMessage?.let { logger.info { it } }
track.installation(device.serialNumber, installationStarted, Instant.now())
installedApps
.getOrPut(device.serialNumber) { hashMapOf() }
.put(appPackage, fileHash)
val storageUsedPercentage = device
.safeExecuteShellCommand("df /storage/emulated -h | grep '/storage/emulated' | awk '{print \$5}'")
.substringBefore("%")
.toInt()
logger.info { "Used $storageUsedPercentage% of storage" }
val storageUsageLimit = 30
if (storageUsedPercentage < storageUsageLimit) {
logger.warn { "Not enough space left" }
androidConfiguration.cleanupDeviceScript?.let {
logger.info { "Less than $storageUsageLimit% left\nLaunching cleanup shell script `$it`" }
device.safeExecuteShellCommand(it).let { logger.info { it } }
}
private suspend fun ensureInstalled(device: AndroidDevice, appPackage: String, appApk: File) {
withRetry(attempts = MAX_RETIRES, delayTime = 1000) {
try {
val checkStarted = Instant.now()
val fileHash = fileHasher.getHash(appApk)
val isApkInstalled = isApkInstalled(device, appPackage, fileHash)
track.installationCheck(device.serialNumber, checkStarted, Instant.now())

if (isApkInstalled) {
logger.info("Skipping installation of $appPackage on ${device.serialNumber} - APK is already installed")
} else {
cleanupSpaceBeforeInstallation(device)
logger.info("Installing $appPackage, ${appApk.absolutePath} to ${device.serialNumber}")
val installationStarted = Instant.now()
val installMessage = device.safeInstallPackage(appApk.absolutePath, true, optionalParams(device))
installMessage?.let { logger.info { it } }
track.installation(device.serialNumber, installationStarted, Instant.now())
installedApps
.getOrPut(device.serialNumber) { hashMapOf() }
.put(appPackage, fileHash)
}
} catch (e: InstallException) {
logger.error(e) { "Error while installing $appPackage, ${appApk.absolutePath} on ${device.serialNumber}" }
throw RuntimeException("Error while installing $appPackage on ${device.serialNumber}", e)
}
} catch (e: InstallException) {
logger.error(e) { "Error while installing $appPackage, ${appApk.absolutePath} on ${device.serialNumber}" }
throw RuntimeException("Error while installing $appPackage on ${device.serialNumber}", e)
}
}

private fun isApkInstalled(device: AndroidDevice, appPackage: String, fileHash: String): Boolean {
private fun cleanupSpaceBeforeInstallation(device: AndroidDevice) {
val storageUsedPercentage = device
.safeExecuteShellCommand("df /storage/emulated -h | grep '/storage/emulated' | awk '{print \$5}'")
.substringBefore("%")
.toInt()
logger.info { "Used $storageUsedPercentage% of storage" }
val storageUsageLimit = 70
if (storageUsedPercentage >= storageUsageLimit) {
logger.warn { "Not enough space left" }
androidConfiguration.cleanupDeviceScript?.let {
logger.info { "More than $storageUsageLimit% used\nLaunching cleanup shell script `$it`" }
device.safeExecuteShellCommand(it).let { logger.info { it } }
}
}
}

private suspend fun isApkInstalled(device: AndroidDevice, appPackage: String, fileHash: String): Boolean {
if (installedApps[device.serialNumber]?.get(appPackage) == fileHash) {
return true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ class DdmlibAndroidDevice(
val androidComponentInfo = testBatch.componentInfo as AndroidComponentInfo

try {
ensureInstalled(androidComponentInfo)
async { ensureInstalled(androidComponentInfo) }.await()
} catch (exception: Throwable) {
logger.error { "Terminating device $serialNumber due to installation failures" }
throw DeviceLostException(exception)
Expand All @@ -300,7 +300,7 @@ class DdmlibAndroidDevice(
}
}

private fun ensureInstalled(componentInfo: AndroidComponentInfo) {
private suspend fun ensureInstalled(componentInfo: AndroidComponentInfo) {
androidAppInstaller.ensureInstalled(this, componentInfo)
}

Expand Down

0 comments on commit 53a2d23

Please sign in to comment.