Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class SemanticDataRepository private constructor() {
validatorMap.putAll(DocumentationOptionValue.validators)
validatorMap.putAll(ModeStringOptionValue.validators)
validatorMap.putAll(ExecOptionValue.validators)
validatorMap.putAll(ExecOutputOptionValue.validators)
validatorMap.putAll(UnitDependencyOptionValue.validators)
validatorMap.putAll(NullOptionValue.validators)
validatorMap.putAll(MemoryLimitOptionValue.validators)
Expand All @@ -85,6 +86,7 @@ class SemanticDataRepository private constructor() {
validatorMap.putAll(ConfigParseSecValidators.validators)
validatorMap.putAll(AllowedCpuSetOptionValue.validators)
validatorMap.putAll(TtySizeOptionValue.validators)
validatorMap.putAll(ExecDirectoriesOptionValue.validators)

// Scopes are not supported since they aren't standard unit files.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues

import com.intellij.openapi.project.Project
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.Validator

class ExecDirectoriesOptionValue : OptionValueInformation {

override fun getAutoCompleteOptions(project: Project): Set<String> {
return emptySet()
}

override fun getErrorMessage(value: String): String? {
val values = value.split("\\s+")

// loop over element in values
for (element in values) {
if (element.startsWith("/")) {
return "Invalid path: '${element}'. Takes a list of absolute paths."
} else if (element.contains("..")) {
return "Invalid path: '${element}'. Path cannot contain `..`."
}
continue
}

return null
}


override val validatorName: String
get() = VALIDATOR_NAME

companion object {
private val VALIDATOR_NAME = "config_parse_exec_directories"

val validators = mapOf(Validator(VALIDATOR_NAME, "0") to ExecDirectoriesOptionValue())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues

import com.intellij.openapi.project.Project
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.Validator

class ExecOutputOptionValue() : OptionValueInformation {
override fun getAutoCompleteOptions(project: Project): Set<String> {
return emptySet()
}

override fun getErrorMessage(value: String): String? {

if (value.startsWith("file:") || value.startsWith("append:") || value.startsWith("truncate:") || value.startsWith("fd:")) {
val firstArg = value.split(":", limit = 2)[0]
val secondArg = value.split(":", limit = 2)[1]

if (secondArg.trim().isEmpty()) {
when(firstArg) {
"file", "append", "truncate" -> return "path must be specified after the colon."
"fd" -> return "name must be specified after the colon."
}
}

// We could do a better job of validating paths later
return null
}

when (value) {
"inherit", "null", "tty", "journal", "kmsg", "journal+console", "kmsg+console", "socket" -> return null
else -> return "Takes one of inherit, null, tty, journal, kmsg, journal+console, kmsg+console, file:path, append:path, truncate:path, socket or fd:name."

}
}

override val validatorName: String
get() = VALIDATOR_NAME


companion object {
private val VALIDATOR_NAME = "config_parse_exec_output"

val validators = mapOf(Validator(VALIDATOR_NAME, "0") to ExecOutputOptionValue())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package net.sjrx.intellij.plugins.systemdunitfiles.inspections

import junit.framework.TestCase
import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest

class InvalidValueInspectionForExecDirectoriesOptionsTest : AbstractUnitFileTest() {

fun testNoWarningWhenUsingASingleRelativeDirectory() {
// Fixture Setup
// language="unit file (systemd)"
val file = """
[Service]
RuntimeDirectory=foo

""".trimIndent()


// Execute SUT
setupFileInEditor("file.service", file)
enableInspection(InvalidValueInspection::class.java)
val highlights = myFixture.doHighlighting()

// Verification
assertSize(0, highlights)
}

fun testNoWarningWhenUsingSeveralRelativeDirectories() {
// Fixture Setup
// language="unit file (systemd)"
val file = """
[Service]
RuntimeDirectory=foo bar \
hello

""".trimIndent()


// Execute SUT
setupFileInEditor("file.service", file)
enableInspection(InvalidValueInspection::class.java)
val highlights = myFixture.doHighlighting()

// Verification
assertSize(0, highlights)
}

fun testWarningWhenUsingASingleAbsoluteDirectory() {
// Fixture Setup
// language="unit file (systemd)"
val file = """
[Service]
RuntimeDirectory=/tmp/myunit

""".trimIndent()


// Execute SUT
setupFileInEditor("file.service", file)
enableInspection(InvalidValueInspection::class.java)
val highlights = myFixture.doHighlighting()

// Verification
assertSize(1, highlights)
val info = highlights[0]
AbstractUnitFileTest.Companion.assertStringContains("Takes a list of absolute paths", info!!.description)
TestCase.assertEquals("/tmp/myunit", info.text)
}

fun testWarningWhenUsingSeveralAbsoluteDirectory() {
// Fixture Setup
// language="unit file (systemd)"
val file = """
[Service]
RuntimeDirectory=/tmp/myunit /tmp/myunit2

""".trimIndent()


// Execute SUT
setupFileInEditor("file.service", file)
enableInspection(InvalidValueInspection::class.java)
val highlights = myFixture.doHighlighting()

// Verification
assertSize(1, highlights)
val info = highlights[0]
AbstractUnitFileTest.Companion.assertStringContains("Takes a list of absolute paths", info!!.description)
TestCase.assertEquals("/tmp/myunit /tmp/myunit2", info.text)
}

fun testWarningWhenUsingParentDirectoryOperator() {
// Fixture Setup
// language="unit file (systemd)"
val file = """
[Service]
RuntimeDirectory=../myunit

""".trimIndent()


// Execute SUT
setupFileInEditor("file.service", file)
enableInspection(InvalidValueInspection::class.java)
val highlights = myFixture.doHighlighting()

// Verification
assertSize(1, highlights)
val info = highlights[0]
AbstractUnitFileTest.Companion.assertStringContains("Path cannot contain `..`", info!!.description)
TestCase.assertEquals("../myunit", info.text)
}

fun testWarningWhenUsingParentDirectoryOperatorInAThirdDirectory() {
// Fixture Setup
// language="unit file (systemd)"
val file = """
[Service]
RuntimeDirectory=foo/bar test/tmp/ ../myunit

""".trimIndent()


// Execute SUT
setupFileInEditor("file.service", file)
enableInspection(InvalidValueInspection::class.java)
val highlights = myFixture.doHighlighting()

// Verification
assertSize(1, highlights)
val info = highlights[0]
AbstractUnitFileTest.Companion.assertStringContains("Path cannot contain `..`", info!!.description)
TestCase.assertEquals("foo/bar test/tmp/ ../myunit", info.text)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package net.sjrx.intellij.plugins.systemdunitfiles.inspections

import junit.framework.TestCase
import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest

class InvalidValueInspectionForExecOutputOptionsTest : AbstractUnitFileTest() {


fun testNoWarningWhenUsingValidValuesForOutput() {
runValidValueTest("inherit")
runValidValueTest("null")
runValidValueTest("tty")
runValidValueTest("journal")
runValidValueTest("kmsg")
runValidValueTest("journal+console")
runValidValueTest("kmsg+console")
runValidValueTest("file:/dev/null")
runValidValueTest("append:/tmp/log.txt")
runValidValueTest("truncate:/tmp/path")
runValidValueTest("socket")
runValidValueTest("fd:stdout")
}

fun runValidValueTest(validValue : String) {
// Fixture Setup
// language="unit file (systemd)"
val file = """
[Service]
StandardOutput=$validValue

""".trimIndent()


// Execute SUT
setupFileInEditor("file.service", file)
enableInspection(InvalidValueInspection::class.java)
val highlights = myFixture.doHighlighting()

// Verification
assertSize(0, highlights)
}


fun testWeakWarningWhenUsingInvalidValueForExecOption() {
// Fixture Setup
// language="unit file (systemd)"
val file = """
[Service]
StandardOutput=foo

""".trimIndent()


// Execute SUT
setupFileInEditor("file.service", file)
enableInspection(InvalidValueInspection::class.java)
val highlights = myFixture.doHighlighting()

// Verification
assertSize(1, highlights)
val info = highlights[0]
AbstractUnitFileTest.Companion.assertStringContains("Takes one of", info!!.description)
TestCase.assertEquals("foo", info.text)
}

fun testWeakWarningWhenMissingSecondArgumentForFd() {
// Fixture Setup
// language="unit file (systemd)"
val file = """
[Service]
StandardOutput=fd:

""".trimIndent()


// Execute SUT
setupFileInEditor("file.service", file)
enableInspection(InvalidValueInspection::class.java)
val highlights = myFixture.doHighlighting()

// Verification
assertSize(1, highlights)
val info = highlights[0]
AbstractUnitFileTest.Companion.assertStringContains("name must be specified after the colon", info!!.description)
TestCase.assertEquals("fd:", info.text)
}

fun testWeakWarningWhenMissingSecondArgumentForFile() {
// Fixture Setup
// language="unit file (systemd)"
val file = """
[Service]
StandardOutput=file:

""".trimIndent()


// Execute SUT
setupFileInEditor("file.service", file)
enableInspection(InvalidValueInspection::class.java)
val highlights = myFixture.doHighlighting()

// Verification
assertSize(1, highlights)
val info = highlights[0]
AbstractUnitFileTest.Companion.assertStringContains("path must be specified after the colon", info!!.description)
TestCase.assertEquals("file:", info.text)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class OptionValueTest : AbstractUnitFileTest() {

val missingValidators = hashMapOf<Validator, Int>()
var totalMissingValidators = 0
var totalFoundValidators = 0
for (sectionName in SemanticDataRepository.instance.sectionNamesFromValidators) {
for (key in SemanticDataRepository.instance.getAllowedKeywordsInSectionFromValidators(sectionName)) {

Expand All @@ -21,6 +22,8 @@ class OptionValueTest : AbstractUnitFileTest() {
if (!validatorMap.containsKey(validator)) {
missingValidators[validator] = (missingValidators[validator] ?: 0) + 1
totalMissingValidators++
} else {
totalFoundValidators++
}
}
}
Expand All @@ -29,8 +32,9 @@ class OptionValueTest : AbstractUnitFileTest() {

val sortedList = missingValidatorList.sortedDescending().joinToString("\n")

println(totalMissingValidators)
if (totalMissingValidators > 630) {
println("Missing:$totalMissingValidators")
println("Found:$totalFoundValidators")
if (totalMissingValidators > 600) {
assertEquals(sortedList, "")
}

Expand Down