@@ -12,97 +12,113 @@ import java.nio.file.Path
12
12
import java.nio.file.Paths.get
13
13
import java.util.UUID
14
14
15
+ /* *
16
+ * Validation logic should check filename first, then check if the resulting path is within max path len
17
+ */
15
18
@Suppress(" TooManyFunctions" )
16
- class FileManager (private val maxPath : Int , private val output : File ) {
19
+ class FileManager (private val maxPath : Int , private val maxFilename : Int , private val output : File ) {
17
20
val log = MarathonLogging .logger(" FileManager" )
18
21
19
- fun createFile (fileType : FileType , pool : DevicePoolId , device : DeviceInfo , test : Test , testBatchId : String? = null): File {
20
- val directory = createDirectory(fileType, pool, device)
21
- val filename = createFilename(test, fileType, maxPath - (directory.toAbsolutePath().toString().length + 1 ), testBatchId)
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 {
30
+ val directory = when {
31
+ test != null || testBatchId != null -> createDirectory(fileType, pool, device)
32
+ else -> createDirectory(fileType, pool)
33
+ }
34
+ val filename = when {
35
+ test != null -> createTestFilename(test, fileType, testBatchId, id = id)
36
+ testBatchId != null -> createBatchFilename(testBatchId, fileType, id = id)
37
+ else -> createDeviceFilename(device, fileType, id = id)
38
+ }
22
39
return createFile(directory, filename)
23
40
}
24
41
25
- fun createFile (fileType : FileType , pool : DevicePoolId , device : DeviceInfo , testBatchId : String ): File {
26
- val directory = createDirectory(fileType, pool, device)
27
- val filename = createFilename(fileType, testBatchId)
28
- return createFile(directory, filename)
29
- }
42
+ fun createFolder (folderType : FolderType , pool : DevicePoolId ? = null, device : DeviceInfo ? = null): File {
43
+ var path = get(output.absolutePath, folderType.dir)
44
+ if (pool != null ) {
45
+ path = path.resolve(pool.name)
46
+ }
47
+ if (device != null ) {
48
+ path = path.resolve(device.safeSerialNumber)
49
+ }
30
50
31
- fun createFile (fileType : FileType , pool : DevicePoolId , device : DeviceInfo ): File {
32
- val directory = createDirectory(fileType, pool)
33
- val filename = createFilename(device, fileType)
34
- return createFile(directory, filename)
35
- }
51
+ val maybeTooLongPath = path.toFile()
52
+ path = if (maxPath > 0 && maybeTooLongPath.absolutePath.length > maxPath) {
53
+ val trimmed = maybeTooLongPath.absolutePath.take(maxPath)
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
+ }
58
+ File (trimmed)
59
+ } else {
60
+ maybeTooLongPath
61
+ }.toPath()
36
62
37
- fun createScreenshotFile (extension : String , pool : DevicePoolId , device : DeviceInfo , test : Test , testBatchId : String ): File {
38
- val directory = createDirectory(FileType .SCREENSHOT , pool, device)
39
- val filename =
40
- createFilename(
41
- test,
42
- FileType .SCREENSHOT ,
43
- maxPath - (directory.toAbsolutePath().toString().length + 1 ),
44
- testBatchId = null ,
45
- extension,
46
- UUID .randomUUID().toString()
47
- )
48
- return createFile(directory, filename)
63
+ return createDirectories(path).toFile()
49
64
}
50
65
51
- fun createFolder (folderType : FolderType ): File = createDirectories(get(output.absolutePath, folderType.dir)).toFile()
52
- fun createFolder (folderType : FolderType , pool : DevicePoolId , device : DeviceInfo ): File =
53
- createDirectories(get(output.absolutePath, folderType.dir, pool.name, device.safeSerialNumber)).toFile()
54
-
55
- fun createFolder (folderType : FolderType , pool : DevicePoolId ): File =
56
- createDirectories(get(output.absolutePath, folderType.dir, pool.name)).toFile()
57
-
58
- fun createFolder (folderType : FolderType , device : DeviceInfo ): File =
59
- createDirectories(get(output.absolutePath, folderType.dir, device.safeSerialNumber)).toFile()
60
-
61
66
fun createTestResultFile (filename : String ): File {
62
- val resultsFolder = get(output.absolutePath, FileType .TEST_RESULT .dir).toFile()
63
- resultsFolder.mkdirs()
64
- return File (resultsFolder, filename)
67
+ val resultsFolder = get(output.absolutePath, FileType .TEST_RESULT .dir)
68
+ resultsFolder.toFile(). mkdirs()
69
+ return createFile (resultsFolder, filename)
65
70
}
66
71
67
- private fun createDirectory (fileType : FileType , pool : DevicePoolId , device : DeviceInfo ): Path =
68
- createDirectories(getDirectory(fileType, pool, device))
69
-
70
- private fun createDirectory (fileType : FileType , pool : DevicePoolId ): Path =
71
- createDirectories(getDirectory(fileType, pool))
72
-
73
- private fun getDirectory (fileType : FileType , pool : DevicePoolId , device : DeviceInfo ): Path =
74
- getDirectory(fileType, pool, device.safeSerialNumber)
75
-
76
- private fun getDirectory (fileType : FileType , pool : DevicePoolId , serial : String ): Path =
77
- get(output.absolutePath, fileType.dir, pool.name, serial)
72
+ private fun createDirectory (fileType : FileType , pool : DevicePoolId , device : DeviceInfo ? = null): Path {
73
+ return createDirectories(getDirectory(fileType, pool, serial = device?.safeSerialNumber))
74
+ }
78
75
79
- private fun getDirectory (fileType : FileType , pool : DevicePoolId ): Path =
80
- get(output.absolutePath, fileType.dir, pool.name)
76
+ private fun getDirectory (fileType : FileType , pool : DevicePoolId , serial : String? = null): Path {
77
+ val path = get(output.absolutePath, fileType.dir, pool.name)
78
+ return serial?.let {
79
+ path.resolve(serial)
80
+ } ? : path
81
+ }
81
82
82
83
private fun createFile (directory : Path , filename : String ): File {
83
- val maybeTooLongPath = File (directory.toFile(), filename)
84
- return if (maybeTooLongPath.absolutePath.length > maxPath) {
84
+ val trimmedFilename = if (maxFilename > 0 && filename.length > maxFilename) {
85
+ val safeFilename = filename.take(maxFilename)
86
+ log.error {
87
+ " File name length cannot exceed $maxFilename characters and has been trimmed to $safeFilename and can create a conflict." +
88
+ " This usually happens because the test name is too long."
89
+ }
90
+ safeFilename
91
+ } else {
92
+ filename
93
+ }
94
+ val maybeTooLongPath = File (directory.toFile(), trimmedFilename)
95
+ return if (maxPath > 0 && maybeTooLongPath.absolutePath.length > maxPath) {
85
96
val trimmed = maybeTooLongPath.absolutePath.substring(0 until maxPath)
86
- log.error { " File path length cannot exceed $maxPath characters and has been trimmed to $trimmed and can create a conflict. 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
+ }
87
101
File (trimmed)
88
102
} else {
89
103
maybeTooLongPath
90
104
}
91
105
}
92
106
93
- private fun createFilename ( fileType : FileType , testBatchId : String ): String {
107
+ private fun createBatchFilename ( testBatchId : String , fileType : FileType , id : String? = null ): String {
94
108
return StringBuilder ().apply {
95
109
append(testBatchId)
110
+ if (id != null ) {
111
+ append(" -$id " )
112
+ }
96
113
if (fileType.suffix.isNotEmpty()) {
97
114
append(" .$testBatchId " )
98
115
}
99
116
}.toString()
100
117
}
101
118
102
- private fun createFilename (
119
+ private fun createTestFilename (
103
120
test : Test ,
104
121
fileType : FileType ,
105
- limit : Int ,
106
122
testBatchId : String? = null,
107
123
overrideExtension : String? = null,
108
124
id : String? = null,
@@ -120,24 +136,16 @@ class FileManager(private val maxPath: Int, private val output: File) {
120
136
append(" .${fileType.suffix} " )
121
137
}
122
138
}.toString()
123
- val rawTestName = test.toTestName().escape()
124
- val testName = when {
125
- limit - testSuffix.length >= 0 -> rawTestName.take(limit - testSuffix.length)
126
- else -> " "
127
- }
128
- val fileName = " $testName$testSuffix "
129
- if (rawTestName.length > testName.length) {
130
- when {
131
- limit >= 0 -> log.error { " File name length cannot exceed $limit characters and has been trimmed to $fileName and can create a conflict. This happened because the combination of file path, test class name, and test name is too long." }
132
- else -> log.error { " Base path for writing a file ${rawTestName}$testSuffix is already maxed out and is ${- limit} characters more than the allowed limit of ${maxPath} ." }
133
- }
134
- }
135
- return fileName
139
+ val testName = test.toTestName().escape()
140
+ return " $testName$testSuffix "
136
141
}
137
142
138
- private fun createFilename (device : DeviceInfo , fileType : FileType ): String {
143
+ private fun createDeviceFilename (device : DeviceInfo , fileType : FileType , id : String? = null ): String {
139
144
return StringBuilder ().apply {
140
145
append(device.safeSerialNumber)
146
+ if (id != null ) {
147
+ append(" -$id " )
148
+ }
141
149
if (fileType.suffix.isNotEmpty()) {
142
150
append(" .${fileType.suffix} " )
143
151
}
0 commit comments