All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.avito.test.gradle.ManualTempFolder.kt Maven / Gradle / Ivy

package com.avito.test.gradle

import java.io.File
import java.io.IOException
import java.nio.file.FileVisitResult
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.SimpleFileVisitor
import java.nio.file.attribute.BasicFileAttributes
import java.util.SortedMap
import java.util.TreeMap
import java.util.function.Consumer
import java.util.stream.Collectors.joining

/**
 * Из-за ограничения в junit5 пока невозможно использовать Extension на каждый dynamicTest
 * Используйте пока ManualTempFolder.runIn(File.() -> Unit)
 *
 * https://github.com/junit-team/junit5/issues/694
 */
public object ManualTempFolder {

    public fun runIn(block: (File) -> Unit): File {
        val tempFolder = Files.createTempDirectory("junit")
        val file = tempFolder.toFile()
        try {
            block(file)
        } finally {
            CloseablePath(tempFolder).close()
        }
        return file
    }

    /**
     * реализация скопирована из [org.junitpioneer.jupiter.TempDirectory]
     */
    private class CloseablePath(private val dir: Path) {

        fun close() {
            val failures = deleteAllFilesAndDirectories()
            if (!failures.isEmpty()) {
                throw createIOExceptionWithAttachedFailures(failures)
            }
        }

        private fun deleteAllFilesAndDirectories(): SortedMap {
            val failures = TreeMap()
            Files.walkFileTree(
                dir,
                object : SimpleFileVisitor() {

                    override fun visitFile(file: Path, attributes: BasicFileAttributes): FileVisitResult {
                        return deleteAndContinue(file)
                    }

                    override fun postVisitDirectory(dir: Path, exc: IOException?): FileVisitResult {
                        return deleteAndContinue(dir)
                    }

                    private fun deleteAndContinue(path: Path): FileVisitResult {
                        try {
                            Files.delete(path)
                        } catch (ex: IOException) {
                            failures[path] = ex
                        }

                        return FileVisitResult.CONTINUE
                    }
                }
            )
            return failures
        }

        private fun createIOExceptionWithAttachedFailures(failures: SortedMap): IOException {
            val joinedPaths = failures.keys.stream()
                .peek { this.tryToDeleteOnExit(it) }
                .map { this.relativizeSafely(it) }
                .map { it.toString() }
                .collect(joining(", "))
            val exception = IOException(
                "Failed to delete temp directory " + dir.toAbsolutePath()
                    + ". The following paths could not be deleted (see suppressed exceptions for details): "
                    + joinedPaths
            )
            failures.values.forEach(Consumer { exception.addSuppressed(it) })
            return exception
        }

        private fun tryToDeleteOnExit(path: Path) {
            try {
                path.toFile().deleteOnExit()
            } catch (ignore: UnsupportedOperationException) {
            }
        }

        private fun relativizeSafely(path: Path): Path {
            return try {
                dir.relativize(path)
            } catch (e: IllegalArgumentException) {
                path
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy