11package org.cqfn.diktat.ruleset.smoke
22
3+ import org.cqfn.diktat.common.utils.loggerWithKtlintConfig
34import org.cqfn.diktat.util.SAVE_VERSION
4- import org.apache.commons.io.FileUtils
5- import org.apache.http.client.methods.CloseableHttpResponse
6- import org.apache.http.client.methods.HttpGet
7- import org.apache.http.impl.client.HttpClients
5+ import org.cqfn.diktat.util.deleteIfExistsSilently
6+ import org.cqfn.diktat.util.prependPath
7+ import org.cqfn.diktat.util.retry
8+
9+ import mu.KotlinLogging
10+ import org.assertj.core.api.Assertions.fail
11+ import org.assertj.core.api.SoftAssertions.assertSoftly
812import org.junit.jupiter.api.AfterAll
9- import org.junit.jupiter.api.Assertions
1013import org.junit.jupiter.api.BeforeAll
1114import org.junit.jupiter.api.condition.DisabledOnOs
1215import org.junit.jupiter.api.condition.OS
13- import java.io.File
14- import java.io.FileOutputStream
15- import java.nio.file.Paths
16+
17+ import java.net.URL
18+ import java.nio.file.Path
19+ import kotlin.io.path.Path
20+ import kotlin.io.path.absolute
21+ import kotlin.io.path.copyTo
22+ import kotlin.io.path.createDirectories
23+ import kotlin.io.path.div
1624import kotlin.io.path.exists
25+ import kotlin.io.path.isSameFileAs
1726import kotlin.io.path.listDirectoryEntries
1827import kotlin.io.path.name
28+ import kotlin.io.path.outputStream
1929import kotlin.io.path.pathString
30+ import kotlin.io.path.readText
31+ import kotlin.io.path.relativeTo
32+ import kotlin.system.measureNanoTime
2033
2134@DisabledOnOs(OS .MAC )
2235class DiktatSaveSmokeTest : DiktatSmokeTestBase () {
@@ -26,7 +39,7 @@ class DiktatSaveSmokeTest : DiktatSmokeTestBase() {
2639 expected : String ,
2740 test : String ,
2841 ) {
29- saveSmokeTest(config, test)
42+ saveSmokeTest(Path ( config) , test)
3043 }
3144
3245 /* *
@@ -35,97 +48,150 @@ class DiktatSaveSmokeTest : DiktatSmokeTestBase() {
3548 */
3649 @Suppress(" TOO_LONG_FUNCTION" )
3750 private fun saveSmokeTest (
38- configFilePath : String ,
51+ configFilePath : Path ,
3952 testPath : String
4053 ) {
41- val processBuilder = createProcessBuilderWithCmd(testPath)
54+ assertSoftly { softly ->
55+ softly.assertThat(configFilePath).isRegularFile
4256
43- val file = File (" src/test/resources/test/smoke/tmpSave.txt" )
44- val configFile = File (" src/test/resources/test/smoke/diktat-analysis.yml" )
45- val configFileFrom = File (configFilePath)
57+ val configFile = (baseDirectory / " diktat-analysis.yml" ).apply {
58+ parent.createDirectories()
59+ }
60+ val saveLog = (baseDirectory / " tmpSave.txt" ).apply {
61+ parent.createDirectories()
62+ deleteIfExistsSilently()
63+ }
4664
47- configFile.createNewFile()
48- file.createNewFile( )
65+ try {
66+ configFilePath.copyTo(configFile, overwrite = true )
4967
50- FileUtils .copyFile(configFileFrom, configFile)
68+ val processBuilder = createProcessBuilderWithCmd(testPath).apply {
69+ redirectErrorStream(true )
70+ redirectOutput(ProcessBuilder .Redirect .appendTo(saveLog.toFile()))
5171
52- processBuilder.redirectErrorStream(true )
53- processBuilder.redirectOutput(ProcessBuilder .Redirect .appendTo(file))
72+ /*
73+ * Inherit JAVA_HOME for the child process.
74+ */
75+ val javaHome = System .getProperty(" java.home" )
76+ environment()[" JAVA_HOME" ] = javaHome
77+ prependPath(Path (javaHome) / " bin" )
78+ }
5479
55- val process = processBuilder.start()
56- process.waitFor()
80+ val saveProcess = processBuilder.start()
81+ val saveExitCode = saveProcess.waitFor()
82+ softly.assertThat(saveExitCode).describedAs(" The exit code of SAVE" ).isZero
5783
58- val output = file.readLines()
59- val saveOutput = output.joinToString(" \n " )
84+ softly.assertThat(saveLog).isRegularFile
6085
61- file.delete ()
86+ val saveOutput = saveLog.readText ()
6287
63- Assertions .assertTrue(
64- saveOutput.contains(" SUCCESS" )
65- )
88+ val saveCommandLine = processBuilder.command().joinToString(separator = " " )
89+ softly.assertThat(saveOutput)
90+ .describedAs(" The output of \" $saveCommandLine \" " )
91+ .isNotEmpty
92+ .contains(" SUCCESS" )
93+ } finally {
94+ configFile.deleteIfExistsSilently()
95+ saveLog.deleteIfExistsSilently()
96+ }
97+ }
6698 }
6799
100+ @Suppress(" WRONG_ORDER_IN_CLASS_LIKE_STRUCTURES" ) // False positives
68101 companion object {
69102 private const val KTLINT_VERSION = " 0.46.1"
70103
71- private fun getSaveForCurrentOs () = when {
72- System .getProperty(" os.name" ).startsWith(" Linux" , ignoreCase = true ) -> " save-$SAVE_VERSION -linuxX64.kexe"
73- System .getProperty(" os.name" ).startsWith(" Mac" , ignoreCase = true ) -> " save-$SAVE_VERSION -macosX64.kexe"
74- System .getProperty(" os.name" ).startsWith(" Windows" , ignoreCase = true ) -> " save-$SAVE_VERSION -mingwX64.exe"
75- else -> " "
104+ @Suppress(" EMPTY_BLOCK_STRUCTURE_ERROR" )
105+ private val logger = KotlinLogging .loggerWithKtlintConfig { }
106+ private val baseDirectory = Path (" src/test/resources/test/smoke" ).absolute()
107+
108+ private fun getSaveForCurrentOs (): String {
109+ val osName = System .getProperty(" os.name" )
110+
111+ return when {
112+ osName.startsWith(" Linux" , ignoreCase = true ) -> " save-$SAVE_VERSION -linuxX64.kexe"
113+ osName.startsWith(" Mac" , ignoreCase = true ) -> " save-$SAVE_VERSION -macosX64.kexe"
114+ osName.startsWith(" Windows" , ignoreCase = true ) -> " save-$SAVE_VERSION -mingwX64.exe"
115+ else -> fail(" SAVE doesn't support $osName (version ${System .getProperty(" os.version" )} )" )
116+ }
76117 }
77118
78- private fun downloadFile (url : String , file : File ) {
79- val httpClient = HttpClients .createDefault()
80- val request = HttpGet (url)
81- httpClient.use {
82- val response: CloseableHttpResponse = httpClient.execute(request)
83- response.use {
84- val fileSave = response.entity
85- fileSave?.let {
86- FileOutputStream (file).use { outstream -> fileSave.writeTo(outstream) }
119+ @Suppress(" FLOAT_IN_ACCURATE_CALCULATIONS" )
120+ private fun downloadFile (from : URL , to : Path ) {
121+ logger.info {
122+ " Downloading $from to ${to.relativeTo(baseDirectory)} ..."
123+ }
124+
125+ val attempts = 5
126+
127+ val lazyDefault: (Throwable ) -> Unit = { error ->
128+ fail(" Failure downloading $from after $attempts attempt(s)" , error)
129+ }
130+
131+ retry(attempts, lazyDefault = lazyDefault) {
132+ from.openStream().use { source ->
133+ to.outputStream().use { target ->
134+ val bytesCopied: Long
135+ val timeNanos = measureNanoTime {
136+ bytesCopied = source.copyTo(target)
137+ }
138+ logger.info {
139+ " $bytesCopied byte(s) copied in ${timeNanos / 1000 / 1e3} ms."
140+ }
87141 }
88142 }
89143 }
90144 }
91145
92146 @BeforeAll
93147 @JvmStatic
148+ @Suppress(" AVOID_NULL_CHECKS" )
94149 internal fun beforeAll () {
150+ val forkedJavaHome = System .getenv(" JAVA_HOME" )
151+ if (forkedJavaHome != null ) {
152+ val javaHome = System .getProperty(" java.home" )
153+ if (javaHome != null && ! Path (javaHome).isSameFileAs(Path (forkedJavaHome))) {
154+ logger.warn {
155+ " Current JDK home is $javaHome . Forked tests may use a different JDK at $forkedJavaHome ."
156+ }
157+ }
158+ logger.warn {
159+ " Make sure JAVA_HOME ($forkedJavaHome ) points to a Java 8 or Java 11 home. Java 17 is not yet supported."
160+ }
161+ }
162+
163+ logger.info {
164+ " The base directory for the smoke test is $baseDirectory ."
165+ }
166+
95167 val diktatDir: String =
96- Paths .get (" ../diktat-ruleset/target" )
168+ Path (" ../diktat-ruleset/target" )
97169 .takeIf { it.exists() }
98170 ?.listDirectoryEntries()
99171 ?.single { it.name.contains(" diktat" ) }
100172 ?.pathString ? : " "
101173
102- val diktat = File (" src/test/resources/test/smoke/diktat.jar" )
103- val diktatFrom = File (diktatDir)
104- val save = File (" src/test/resources/test/smoke/${getSaveForCurrentOs()} " )
105- val ktlint = File (" src/test/resources/test/smoke/ktlint" )
106-
107- ktlint.createNewFile()
108- save.createNewFile()
109- diktat.createNewFile()
174+ val diktatFrom = Path (diktatDir)
175+ val diktat = baseDirectory / " diktat.jar"
176+ val save = baseDirectory / getSaveForCurrentOs()
177+ val ktlint = baseDirectory / " ktlint"
110178
111- downloadFile(" https://github.com/saveourtool/save-cli/releases/download/v$SAVE_VERSION /${getSaveForCurrentOs()} " , save)
112- downloadFile(" https://github.com/pinterest/ktlint/releases/download/$KTLINT_VERSION /ktlint" , ktlint)
179+ downloadFile(URL ( " https://github.com/saveourtool/save-cli/releases/download/v$SAVE_VERSION /${getSaveForCurrentOs()} " ) , save)
180+ downloadFile(URL ( " https://github.com/pinterest/ktlint/releases/download/$KTLINT_VERSION /ktlint" ) , ktlint)
113181
114- FileUtils .copyFile(diktatFrom, diktat)
182+ diktatFrom.copyTo( diktat)
115183 }
116184
117185 @AfterAll
118186 @JvmStatic
119187 internal fun afterAll () {
120- val diktat = File (" src/test/resources/test/smoke/diktat.jar" )
121- val configFile = File (" src/test/resources/test/smoke/diktat-analysis.yml" )
122- val save = File (" src/test/resources/test/smoke/${getSaveForCurrentOs()} " )
123- val ktlint = File (" src/test/resources/test/smoke/ktlint" )
124-
125- diktat.delete()
126- configFile.delete()
127- ktlint.delete()
128- save.delete()
188+ val diktat = baseDirectory / " diktat.jar"
189+ val save = baseDirectory / getSaveForCurrentOs()
190+ val ktlint = baseDirectory / " ktlint"
191+
192+ diktat.deleteIfExistsSilently()
193+ ktlint.deleteIfExistsSilently()
194+ save.deleteIfExistsSilently()
129195 }
130196 }
131197}
0 commit comments