Skip to content

Commit 6faa9c5

Browse files
committed
fix(core): unify FileManager logic for screenshot file with generic logic
1 parent c4e09e6 commit 6faa9c5

File tree

4 files changed

+77
-31
lines changed

4 files changed

+77
-31
lines changed

core/src/main/kotlin/com/malinskiy/marathon/io/FileManager.kt

+27-23
Original file line numberDiff line numberDiff line change
@@ -19,32 +19,26 @@ import java.util.UUID
1919
class FileManager(private val maxPath: Int, private val maxFilename: Int, private val output: File) {
2020
val log = MarathonLogging.logger("FileManager")
2121

22-
fun createFile(fileType: FileType, pool: DevicePoolId, device: DeviceInfo, test: Test? = null, testBatchId: String? = null): File {
22+
fun createFile(
23+
fileType: FileType,
24+
pool: DevicePoolId,
25+
device: DeviceInfo,
26+
test: Test? = null,
27+
testBatchId: String? = null,
28+
id: String? = null
29+
): File {
2330
val directory = when {
2431
test != null || testBatchId != null -> createDirectory(fileType, pool, device)
2532
else -> createDirectory(fileType, pool)
2633
}
2734
val filename = when {
28-
test != null -> createTestFilename(test, fileType, testBatchId)
29-
testBatchId != null -> createBatchFilename(testBatchId, fileType)
30-
else -> createDeviceFilename(device, fileType)
35+
test != null -> createTestFilename(test, fileType, testBatchId, id = id)
36+
testBatchId != null -> createBatchFilename(testBatchId, fileType, id = id)
37+
else -> createDeviceFilename(device, fileType, id = id)
3138
}
3239
return createFile(directory, filename)
3340
}
3441

35-
fun createScreenshotFile(extension: String, pool: DevicePoolId, device: DeviceInfo, test: Test, testBatchId: String): File {
36-
val directory = createDirectory(FileType.SCREENSHOT, pool, device)
37-
val filename =
38-
createTestFilename(
39-
test,
40-
FileType.SCREENSHOT,
41-
testBatchId = null,
42-
extension,
43-
UUID.randomUUID().toString()
44-
)
45-
return createFile(directory, filename)
46-
}
47-
4842
fun createFolder(folderType: FolderType, pool: DevicePoolId? = null, device: DeviceInfo? = null): File {
4943
var path = get(output.absolutePath, folderType.dir)
5044
if (pool != null) {
@@ -57,8 +51,10 @@ class FileManager(private val maxPath: Int, private val maxFilename: Int, privat
5751
val maybeTooLongPath = path.toFile()
5852
path = if (maxPath > 0 && maybeTooLongPath.absolutePath.length > maxPath) {
5953
val trimmed = maybeTooLongPath.absolutePath.take(maxPath)
60-
log.error { "Directory path length cannot exceed $maxPath characters and has been trimmed from $maybeTooLongPath to $trimmed and can create a conflict. " +
61-
"This happened because the combination of file path, pool name and device serial is too long." }
54+
log.error {
55+
"Directory path length cannot exceed $maxPath characters and has been trimmed from $maybeTooLongPath to $trimmed and can create a conflict. " +
56+
"This happened because the combination of file path, pool name and device serial is too long."
57+
}
6258
File(trimmed)
6359
} else {
6460
maybeTooLongPath
@@ -98,17 +94,22 @@ class FileManager(private val maxPath: Int, private val maxFilename: Int, privat
9894
val maybeTooLongPath = File(directory.toFile(), trimmedFilename)
9995
return if (maxPath > 0 && maybeTooLongPath.absolutePath.length > maxPath) {
10096
val trimmed = maybeTooLongPath.absolutePath.substring(0 until maxPath)
101-
log.error { "File path length cannot exceed $maxPath characters and has been trimmed from $maybeTooLongPath to $trimmed and can create a conflict. " +
102-
"This happened because the combination of file path, test class name, and test name is too long." }
97+
log.error {
98+
"File path length cannot exceed $maxPath characters and has been trimmed from $maybeTooLongPath to $trimmed and can create a conflict. " +
99+
"This happened because the combination of file path, test class name, and test name is too long."
100+
}
103101
File(trimmed)
104102
} else {
105103
maybeTooLongPath
106104
}
107105
}
108106

109-
private fun createBatchFilename(testBatchId: String, fileType: FileType): String {
107+
private fun createBatchFilename(testBatchId: String, fileType: FileType, id: String? = null): String {
110108
return StringBuilder().apply {
111109
append(testBatchId)
110+
if (id != null) {
111+
append("-$id")
112+
}
112113
if (fileType.suffix.isNotEmpty()) {
113114
append(".$testBatchId")
114115
}
@@ -139,9 +140,12 @@ class FileManager(private val maxPath: Int, private val maxFilename: Int, privat
139140
return "$testName$testSuffix"
140141
}
141142

142-
private fun createDeviceFilename(device: DeviceInfo, fileType: FileType): String {
143+
private fun createDeviceFilename(device: DeviceInfo, fileType: FileType, id: String? = null): String {
143144
return StringBuilder().apply {
144145
append(device.safeSerialNumber)
146+
if (id != null) {
147+
append("-$id")
148+
}
145149
if (fileType.suffix.isNotEmpty()) {
146150
append(".${fileType.suffix}")
147151
}

core/src/main/kotlin/com/malinskiy/marathon/io/FileType.kt

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ enum class FileType(val dir: String, val suffix: String) {
99
VIDEO("video", "mp4"),
1010
SCREENSHOT("screenshot", "gif"),
1111
SCREENSHOT_PNG("screenshot", "png"),
12+
SCREENSHOT_JPG("screenshot", "jpg"),
13+
SCREENSHOT_WEBP("screenshot", "jpg"),
14+
SCREENSHOT_GIF("screenshot", "jpg"),
1215
XCTESTRUN("xctestrun", "xctestrun"),
1316
BILL("bill", "json"),
1417
}

core/src/test/kotlin/com/malinskiy/marathon/io/FileManagerTest.kt

+22-1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,25 @@ class FileManagerTest {
9494
file.name shouldBeEqualTo "127.0.0.1-5037-emulator-5554.log"
9595
}
9696

97+
@Test
98+
fun testScreenshotfile() {
99+
val fileManager = FileManager(0, 255, output)
100+
val file = fileManager.createFile(
101+
FileType.SCREENSHOT_PNG, poolId, DeviceInfo(
102+
operatingSystem = OperatingSystem("23"),
103+
serialNumber = "127.0.0.1:5037:emulator-5554",
104+
model = "Android SDK built for x86",
105+
manufacturer = "unknown",
106+
networkState = NetworkState.CONNECTED,
107+
deviceFeatures = listOf(DeviceFeature.SCREENSHOT, DeviceFeature.VIDEO),
108+
healthy = true
109+
),
110+
test = shortNameTest,
111+
id = "on-device-test",
112+
)
113+
file.name shouldBeEqualTo "com.example.Clazz#method-on-device-test.png"
114+
}
115+
97116
@Test
98117
fun testTooLongOutputPathUnlimitedFilename() {
99118
val test = com.malinskiy.marathon.test.Test(
@@ -110,5 +129,7 @@ class FileManagerTest {
110129
val limitedOutputDirectory = File(tempDir, "x".repeat(additionalPathCharacters))
111130
val limitedFileManager = FileManager(limitedMaxPath, 0, limitedOutputDirectory)
112131
val file = limitedFileManager.createFile(FileType.LOG, poolId, deviceInfo, test, batchId)
113-
}
132+
133+
file.path.length shouldBeEqualTo 255
134+
}
114135
}

vendor/vendor-android/src/main/kotlin/com/malinskiy/marathon/android/executor/listeners/screenshot/AdamScreenCaptureTestRunListener.kt

+25-7
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ import com.malinskiy.marathon.device.toDeviceInfo
88
import com.malinskiy.marathon.execution.Attachment
99
import com.malinskiy.marathon.execution.AttachmentType
1010
import com.malinskiy.marathon.io.FileManager
11+
import com.malinskiy.marathon.io.FileType
1112
import com.malinskiy.marathon.log.MarathonLogging
1213
import com.malinskiy.marathon.report.attachment.AttachmentListener
1314
import com.malinskiy.marathon.report.attachment.AttachmentProvider
15+
import java.util.UUID
1416

1517
class AdamScreenCaptureTestRunListener(
1618
private val pool: DevicePoolId,
@@ -27,14 +29,30 @@ class AdamScreenCaptureTestRunListener(
2729
val screenshots = testMetrics.filterKeys { it == "com.malinskiy.adam.junit4.android.screencapture.AdamScreenCaptureProcessor.v1" }
2830
screenshots.values.forEach { path ->
2931
val extension = path.substringAfterLast('.')
30-
val attachmentType = when (extension) {
31-
"jpeg", "jpg" -> AttachmentType.SCREENSHOT_JPEG
32-
"png" -> AttachmentType.SCREENSHOT_PNG
33-
"webp" -> AttachmentType.SCREENSHOT_WEBP
34-
else -> null
32+
var attachmentType: AttachmentType? = null
33+
var fileType: FileType? = null
34+
when (extension) {
35+
"jpeg", "jpg" -> {
36+
attachmentType = AttachmentType.SCREENSHOT_JPEG
37+
fileType = FileType.SCREENSHOT_JPG
38+
}
39+
"png" -> {
40+
attachmentType = AttachmentType.SCREENSHOT_PNG
41+
fileType = FileType.SCREENSHOT_PNG
42+
}
43+
"webp" -> {
44+
attachmentType = AttachmentType.SCREENSHOT_WEBP
45+
fileType = FileType.SCREENSHOT_WEBP
46+
}
47+
"gif" -> {
48+
attachmentType = AttachmentType.SCREENSHOT_GIF
49+
fileType = FileType.SCREENSHOT_GIF
50+
}
51+
else -> Unit
3552
}
36-
if (attachmentType != null) {
37-
val localFile = fileManager.createScreenshotFile(extension, pool, device.toDeviceInfo(), test.toTest(), testBatchId)
53+
54+
if (attachmentType != null && fileType != null) {
55+
val localFile = fileManager.createFile(fileType, pool, device.toDeviceInfo(), test.toTest(), testBatchId = testBatchId, id = UUID.randomUUID().toString())
3856
device.safePullFile(path, localFile.absolutePath)
3957
logger.debug { "Received screen capture file $path" }
4058
attachmentListeners.forEach {

0 commit comments

Comments
 (0)