Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test for actual warning in SAVE from the file #366

Merged
merged 11 commits into from
Jan 23, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
"version": "2.1.0",
"runs": [
{
"originalUriBaseIds": {
"%SRCROOT%": {
"uri": "file://D:/projects/"
}
},
"results": [
{
"level": "error",
"locations": [
{
"physicalLocation": {
"artifactLocation": {
"uri": "src\\kotlin\\EnumValueSnakeCaseTest.kt",
"uriBaseId": "%SRCROOT%"
},
"region": {
"startColumn": 5,
"startLine": 18
}
}
}
],
"message": {
"text": "[ENUM_VALUE] enum values should be in selected UPPER_CASE snake/PascalCase format: NAme_MYa_sayR_"
},
"ruleId": "diktat-ruleset:identifier-naming"
}
],
"tool": {
"driver": {
"downloadUri": "https://github.com/pinterest/ktlint/releases/tag/0.42.0",
"fullName": "ktlint",
"informationUri": "https://github.com/pinterest/ktlint/",
"language": "en",
"name": "ktlint",
"organization": "pinterest",
"rules": [
],
"semanticVersion": "0.42.0",
"version": "0.42.0"
}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
"version": "2.1.0",
"runs": [
{
"originalUriBaseIds": {
"%SRCROOT%": {
"uri": "file://D:/projects/"
}
},
"results": [
{
"level": "error",
"locations": [
{
"physicalLocation": {
"artifactLocation": {
"uri": "src\\kotlin\\EnumValueSnakeCaseTest.kt",
"uriBaseId": "%SRCROOT%"
},
"region": {
"startColumn": 5,
"startLine": 18
}
}
}
],
"message": {
"text": "[ENUM_VALUE] enum values should be in selected UPPER_CASE snake/PascalCase format: NAme_MYa_sayR_"
},
"ruleId": "diktat-ruleset:identifier-naming"
}
],
"tool": {
"driver": {
"downloadUri": "https://github.com/pinterest/ktlint/releases/tag/0.42.0",
"fullName": "ktlint",
"informationUri": "https://github.com/pinterest/ktlint/",
"language": "en",
"name": "ktlint",
"organization": "pinterest",
"rules": [
],
"semanticVersion": "0.42.0",
"version": "0.42.0"
}
}
}
]
}
21 changes: 21 additions & 0 deletions examples/kotlin-diktat/sarif-actual-expected/save.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[general]
tags = ["warn", "sarif"]
description = "Test warnings discovered by diKTat, reading expected warnings from SARIF file"
suiteName = "Only Warnings: with SARIF format"

[warn]
# regular expression to detect tests
testNameRegex = ".*Test.kt"
expectedWarningsFormat = "SARIF"
expectedWarningsFileName = "save-warnings-expected.sarif"
actualWarningsFormat = "SARIF"
actualWarningsFileName = "save-warnings-actual.sarif"
# diktat warnings have the following format: filename.kt:1:15: [WARN_NAME] my warning
actualWarningsPattern="(\\w+\\..+):(\\d+):(\\d+): (\\[.*\\].*)"
fileNameCaptureGroupOut = 1
lineCaptureGroupOut = 2
columnCaptureGroupOut = 3
messageCaptureGroupOut = 4
exactWarningsMatch = false
warningTextHasColumn = true
warningTextHasLine = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.cqfn.diktat.test.resources.test.paragraph1.naming.enum_

// ;warn:3:1: [MISSING_KDOC_TOP_LEVEL] all public and internal top-level classes and functions should have Kdoc: EnumValueSnakeCaseTest (cannot be auto-corrected)
// ;warn:35: [WRONG_DECLARATIONS_ORDER] declarations of constants and enum members should be sorted alphabetically: enum entries order is incorrect
// ;warn:10:5: [ENUMS_SEPARATED] enum is incorrectly formatted: enums must end with semicolon
enum class EnumValueSnakeCaseTest {
// ;warn:$line+1:5: [ENUM_VALUE] enum values should be{{ in }}selected UPPER_CASE snake/PascalCase format: paSC_SAl_l
paSC_SAl_l,

// ;warn:5: [ENUM_VALUE] enum values{{ should }}be in selected{{ UPPER_CASE }}snake/PascalCase format: PascAsl_f
PascAsl_f
// ;warn:$line-2:5: [ENUMS_SEPARATED] enum is incorrectly formatted: last enum entry must end with a comma

// ;warn:1:9: {{.*}}[PACKAGE_NAME_INCORRECT_PREFIX] package name should start from company's domain: org.cqfn.save{{.*}}
}
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,12 @@ class ClassicWarnTest {
1
)
}

@Test
fun `execute warn-plugin with actual and expected warnings from SARIF`() {
runTestsWithDiktat(
listOf("sarif-actual-expected"),
1
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.saveourtool.save.core.utils.ExecutionResult
import com.saveourtool.save.core.utils.ProcessExecutionException
import com.saveourtool.save.core.utils.ProcessTimeoutException
import com.saveourtool.save.core.utils.SarifParsingException
import com.saveourtool.save.core.utils.calculatePathToSarifFile
import com.saveourtool.save.core.utils.singleIsInstance
import com.saveourtool.save.plugin.warn.sarif.toWarnings
import com.saveourtool.save.plugin.warn.utils.CmdExecutorWarn
Expand All @@ -34,7 +35,6 @@ import com.saveourtool.save.plugin.warn.utils.getLineNumber
import io.github.detekt.sarif4k.SarifSchema210
import okio.FileSystem
import okio.Path
import okio.Path.Companion.toPath

import kotlin.random.Random
import kotlinx.serialization.decodeFromString
Expand All @@ -46,6 +46,7 @@ private typealias WarningMap = Map<String, List<Warning>>
* A plugin that runs an executable and verifies that it produces required warning messages.
* @property testConfig
*/
@Suppress("TooManyFunctions")
class WarnPlugin(
testConfig: TestConfig,
testFiles: List<String>,
Expand Down Expand Up @@ -151,26 +152,20 @@ class WarnPlugin(
warnMissingExpectedWarnings(warnPluginConfig, generalConfig, originalPaths)
}

val result = try {
cmdExecutor.execCmdAndGetExecutionResults(redirectTo)
} catch (ex: ProcessTimeoutException) {
logWarn("The following tests took too long to run and were stopped: $originalPaths, timeout for single test: ${ex.timeoutMillis}")
return failTestResult(originalPaths, ex, execCmd)
} catch (ex: ProcessExecutionException) {
return failTestResult(originalPaths, ex, execCmd)
}

val actualWarningsMap = try {
warnPluginConfig.actualWarningsFileName?.let {
val execResult = ExecutionResult(
result.code,
fs.readLines(warnPluginConfig.actualWarningsFileName.toPath()),
result.stderr
)
collectActualWarningsWithLineNumbers(execResult, warnPluginConfig, workingDirectory)
} ?: collectActualWarningsWithLineNumbers(result, warnPluginConfig, workingDirectory)
val (actualWarningsMap, result) = try {
actualWarningsIfExistActualWarningsFile(warnPluginConfig, originalPaths, workingDirectory)
} catch (ex: SarifParsingException) {
return failTestResult(originalPaths, ex, execCmd)
} ?: run {
val result = try {
cmdExecutor.execCmdAndGetExecutionResults(redirectTo)
} catch (ex: ProcessTimeoutException) {
logWarn("The following tests took too long to run and were stopped: $originalPaths, timeout for single test: ${ex.timeoutMillis}")
return failTestResult(originalPaths, ex, execCmd)
} catch (ex: ProcessExecutionException) {
return failTestResult(originalPaths, ex, execCmd)
}
collectActualWarningsWithLineNumbers(result, warnPluginConfig, workingDirectory) to result
}

val resultsChecker = ResultsChecker(
Expand All @@ -195,6 +190,23 @@ class WarnPlugin(
}.asSequence()
}

private fun actualWarningsIfExistActualWarningsFile(
warnPluginConfig: WarnPluginConfig,
originalPaths: List<Path>,
workingDirectory: Path,
) = warnPluginConfig.actualWarningsFileName?.let {
val sarif = calculatePathToSarifFile(
sarifFileName = warnPluginConfig.actualWarningsFileName,
anchorTestFilePath = originalPaths.first()
)
val execResult = ExecutionResult(
0,
fs.readLines(sarif),
listOf("Warnings were obtained from SARIF file, no debug info is available")
)
collectActualWarningsWithLineNumbers(execResult, warnPluginConfig, workingDirectory) to execResult
}

private fun createTestFiles(paths: List<Path>, warnPluginConfig: WarnPluginConfig): List<Path> {
logDebug("Creating temp copy files of resources for WarnPlugin...")
logTrace("Trying to create temp files for: $paths")
Expand Down