Skip to content

Commit

Permalink
Moved tests with CLI from GitHub actions to JUnit test (#1784)
Browse files Browse the repository at this point in the history
- removed steps from `build_and_test.yml`
- added a new test `DiktatCliTest.kt`
  • Loading branch information
nulls committed Nov 8, 2023
1 parent a812bf0 commit dc0f747
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 181 deletions.
154 changes: 0 additions & 154 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,166 +65,12 @@ jobs:
name: gradle-reports
path: '**/build/reports/'
retention-days: 1
- name: Upload diktat-ruleset jar
uses: actions/upload-artifact@v3
with:
name: diktat-ruleset
path: diktat-ruleset/build/libs/diktat-*.jar
# no need to store artifact longer, it is used only by dependant jobs
retention-days: 1
- name: Upload diktat-cli jar
uses: actions/upload-artifact@v3
with:
name: diktat-cli
path: diktat-cli/build/libs/diktat-cli-*.jar
# no need to store artifact longer, it is used only by dependant jobs
retention-days: 1
- name: Code coverage report
uses: codecov/codecov-action@v3
with:
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}

run_diktat_from_CLI:
name: Run diktat via CLI
runs-on: ${{ matrix.os }}
needs: build_and_test_with_code_coverage
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
java-version: [8, 11]
type: [ ktlint, cli ]

steps:
- uses: actions/checkout@v4

- name: Retrieve Ktlint version
if: matrix.type == 'ktlint'
run: |
ktlint_version=$(cat gradle/libs.versions.toml | grep '^ktlint =' | awk -F'[=]' '{print $2}' | tr -d '" ')
echo KTLINT_VERSION=$ktlint_version >> $GITHUB_ENV
shell: bash

- name: Setup environment
if: matrix.type == 'ktlint'
run: |
curl -o ktlint -sSL https://github.com/pinterest/ktlint/releases/download/${{ env.KTLINT_VERSION }}/ktlint && chmod a+x ktlint
java -version
shell: bash

- name: Download diktat jar
if: matrix.type == 'ktlint'
uses: actions/download-artifact@v3
with:
name: diktat-ruleset

- name: Generate run command using ktlint
if: matrix.type == 'ktlint'
run: |
filename=$(ls -1 diktat-*.jar | head -n1)
echo DIKTAT_RUN="java -jar ktlint -R \"$filename\"" >> $GITHUB_ENV
shell: bash

- name: Download diktat cli jar
if: matrix.type == 'cli'
uses: actions/download-artifact@v3
with:
name: diktat-cli

- name: Generate run command using cli
if: matrix.type == 'cli'
run: |
filename=$(ls -1 diktat-cli-*.jar | head -n1)
echo DIKTAT_RUN="java -jar \"$filename\"" >> $GITHUB_ENV
shell: bash

- name: Run diKTat from cli
continue-on-error: true
run: |
${{ env.DIKTAT_RUN }} 'examples/maven/src/main/kotlin/Test.kt' &>out.txt
shell: bash

- name: Check output
run: |
cat out.txt
grep -E "\[VARIABLE_NAME_INCORRECT_FORMAT\]" out.txt
rm out.txt
shell: bash

- name: Run diKTat from cli (absolute paths)
continue-on-error: true
if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}
run: |
${{ env.DIKTAT_RUN }} "$PWD/examples/maven/src/main/kotlin/Test.kt" &>out.txt
shell: bash

- name: Run diKTat from cli on windows (absolute paths)
continue-on-error: true
if: runner.os == 'Windows'
# cannot use '&>out.txt' since it's Windows
run: |
${{ env.DIKTAT_RUN }} "%cd%/examples/maven/src/main/kotlin/Test.kt" > out.txt 2>&1
shell: cmd

- name: Check output (absolute paths)
run: |
cat out.txt
grep -E "\[VARIABLE_NAME_INCORRECT_FORMAT\]" out.txt
rm out.txt
shell: bash

- name: Run diKTat from cli (glob paths, 1 of 4)
continue-on-error: true
run: |
${{ env.DIKTAT_RUN }} 'examples/maven/src/main/kotlin/*.kt' &>out.txt
shell: bash

- name: Check output (glob paths, 1 of 4)
run: |
cat out.txt
grep -E "\[VARIABLE_NAME_INCORRECT_FORMAT\]" out.txt
rm out.txt
shell: bash

- name: Run diKTat from cli (glob paths, 2 of 4)
continue-on-error: true
run: |
${{ env.DIKTAT_RUN }} 'examples/**/main/kotlin/*.kt' &>out.txt
shell: bash

- name: Check output (glob paths, 2 of 4)
run: |
cat out.txt
grep -E "\[VARIABLE_NAME_INCORRECT_FORMAT\]" out.txt
rm out.txt
shell: bash

- name: Run diKTat from cli (glob paths, 3 of 4)
continue-on-error: true
run: |
${{ env.DIKTAT_RUN }} 'examples/**/*.kt' &>out.txt
shell: bash

- name: Check output (glob paths, 3 of 4)
run: |
cat out.txt
grep -E "\[VARIABLE_NAME_INCORRECT_FORMAT\]" out.txt
rm out.txt
shell: bash

- name: Run diKTat from cli (glob paths, 4 of 4)
continue-on-error: true
run: |
${{ env.DIKTAT_RUN }} '**/*.kt' &>out.txt
shell: bash

- name: Check output (glob paths, 4 of 4)
run: |
cat out.txt
grep -E "\[VARIABLE_NAME_INCORRECT_FORMAT\]" out.txt
rm out.txt
shell: bash

build_and_test:
name: Build and test
runs-on: ${{ matrix.os }}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package com.saveourtool.diktat.smoke

import com.saveourtool.diktat.test.framework.util.checkForkedJavaHome
import com.saveourtool.diktat.test.framework.util.deleteIfExistsSilently
import com.saveourtool.diktat.test.framework.util.inheritJavaHome
import com.saveourtool.diktat.test.framework.util.isWindows
import com.saveourtool.diktat.test.framework.util.temporaryDirectory
import io.github.oshai.kotlinlogging.KotlinLogging
import org.assertj.core.api.SoftAssertions.assertSoftly
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.PathWalkOption
import kotlin.io.path.absolutePathString
import kotlin.io.path.copyTo
import kotlin.io.path.createDirectories
import kotlin.io.path.div
import kotlin.io.path.isDirectory
import kotlin.io.path.readText
import kotlin.io.path.walk

class DiktatCliTest {

@Test
fun `Run diKTat from cli`() {
cliTest("examples/maven/src/main/kotlin/Test.kt")
}

@Test
fun `Run diKTat from cli (absolute paths)`() {
cliTest(tempDir.resolve("examples/maven/src/main/kotlin/Test.kt").absolutePathString())
}

@Test
fun `Run diKTat from cli (glob paths, 1 of 4)`() {
cliTest("examples/maven/src/main/kotlin/*.kt")
}

@Test
fun `Run diKTat from cli (glob paths, 2 of 4)`() {
cliTest("examples/**/main/kotlin/*.kt")
}

@Test
fun `Run diKTat from cli (glob paths, 3 of 4)`() {
cliTest("examples/**/*.kt")
}

@Test
fun `Run diKTat from cli (glob paths, 4 of 4)`() {
cliTest("**/*.kt")
}

@Suppress("TOO_LONG_FUNCTION")
private fun cliTest(
vararg cliArgs: String,
) {
assertSoftly { softly ->
val diktatCliLog = (tempDir / "log.txt").apply {
parent.createDirectories()
deleteIfExistsSilently()
}

val processBuilder = createProcessBuilderWithCmd(*cliArgs).apply {
redirectErrorStream(true)
redirectOutput(ProcessBuilder.Redirect.appendTo(diktatCliLog.toFile()))

/*
* Inherit JAVA_HOME for the child process.
*/
inheritJavaHome()

temporaryDirectory(tempDir / ".tmp")
}

val diktatCliProcess = processBuilder.start()
val exitCode = diktatCliProcess.waitFor()
softly.assertThat(exitCode).describedAs("The exit code of Diktat CLI").isZero

softly.assertThat(diktatCliLog).isRegularFile

val diktatCliOutput = diktatCliLog.readText()

val commandLine = processBuilder.command().joinToString(separator = " ")
softly.assertThat(diktatCliOutput)
.describedAs("The output of \"$commandLine\"")
.isNotEmpty
.contains("[VARIABLE_NAME_INCORRECT_FORMAT]")
.doesNotContain("WARNING:")
}
}

private fun createProcessBuilderWithCmd(vararg cliArgs: String): ProcessBuilder {
return when {
System.getProperty("os.name").isWindows() -> arrayOf(*javaArgs, DIKTAT_CLI_JAR, *defaultArgs, *cliArgs)
else -> arrayOf("sh", "-c", arrayOf(*javaArgs, DIKTAT_CLI_JAR, *defaultArgs, *cliArgs).joinToString(" "))
}.let { args -> ProcessBuilder(*args).directory(tempDir.toFile()) }
}

companion object {
private val logger = KotlinLogging.logger {}

private val javaArgs = arrayOf("java", "-showversion", "-jar")
private val defaultArgs = arrayOf("--log-level", "debug")

@JvmStatic
@TempDir
internal var tempDir: Path = Paths.get("/invalid")

@BeforeAll
@JvmStatic
@OptIn(ExperimentalPathApi::class)
internal fun beforeAll() {
assertSoftly { softly ->
checkForkedJavaHome()

logger.info {
"The temp directory for the test is $tempDir."
}
val sourceDirectory = Paths.get("../examples")
val targetDirectory = (tempDir / "examples").also {
it.createDirectories()
}
sourceDirectory.walk(PathWalkOption.INCLUDE_DIRECTORIES).forEach { file ->
if (file.isDirectory()) {
targetDirectory.resolve(sourceDirectory.relativize(file)).createDirectories()
} else {
val dest = targetDirectory.resolve(sourceDirectory.relativize(file))
file.copyTo(dest)
}
}
copyDiktatCli(softly, tempDir / DIKTAT_CLI_JAR)

val defaultConfigFile = Paths.get("../diktat-analysis.yml")
softly.assertThat(defaultConfigFile)
.describedAs("Default config file for diktat")
.isRegularFile
defaultConfigFile.copyTo(tempDir / "diktat-analysis.yml", overwrite = true)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@ import org.junit.jupiter.api.condition.OS

import java.net.URL
import java.nio.file.Path
import kotlin.io.path.Path
import kotlin.io.path.absolute
import kotlin.io.path.copyTo
import kotlin.io.path.createDirectories
import kotlin.io.path.div
import kotlin.io.path.exists
import kotlin.io.path.listDirectoryEntries
import kotlin.io.path.readText

@DisabledOnOs(OS.MAC)
Expand Down Expand Up @@ -139,29 +136,10 @@ class DiktatSaveSmokeTest : DiktatSmokeTestBase() {
"The base directory for the smoke test is $baseDirectoryPath."
}

/*
* The fat JAR should reside in the same directory as `save*` and
* be named `diktat.jar`
* (see `diktat-cli/src/test/resources/test/smoke/save.toml`).
*/
val buildDirectory = Path(BUILD_DIRECTORY)
softly.assertThat(buildDirectory)
.isDirectory
val diktatFrom = buildDirectory
.takeIf(Path::exists)
?.listDirectoryEntries(DIKTAT_FAT_JAR_GLOB)
?.singleOrNull()
softly.assertThat(diktatFrom)
.describedAs(diktatFrom?.toString() ?: "$BUILD_DIRECTORY/$DIKTAT_FAT_JAR_GLOB")
.isNotNull
.isRegularFile

val diktat = baseDirectoryPath / DIKTAT_FAT_JAR
val diktat = baseDirectoryPath / DIKTAT_CLI_JAR
copyDiktatCli(softly, diktat)
val save = baseDirectoryPath / getSaveForCurrentOs()

downloadFile(URL("https://github.com/saveourtool/save-cli/releases/download/v$SAVE_VERSION/${getSaveForCurrentOs()}"), save)

diktatFrom?.copyTo(diktat, overwrite = true)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,6 @@ abstract class DiktatSmokeTestBase {
@BeforeAll
@JvmStatic
@OptIn(ExperimentalPathApi::class)
@Suppress("AVOID_NULL_CHECKS")
internal fun createTmpFiles() {
val resourceFilePath = DiktatSmokeTestBase::class.java
.classLoader
Expand Down
Loading

0 comments on commit dc0f747

Please sign in to comment.