diff options
author | Piotr Jaszczyk <piotr.jaszczyk@nokia.com> | 2018-11-28 15:46:50 +0100 |
---|---|---|
committer | Piotr Jaszczyk <piotr.jaszczyk@nokia.com> | 2018-11-29 14:41:42 +0100 |
commit | dde383a2aa75f94c26d7949665b79cc95486a223 (patch) | |
tree | 75f3e8f564067afd0e67dbe6254183e45ca26944 /build/hv-collector-analysis/src/test/kotlin | |
parent | 77f896523f2065b1da1be21545155a29edea5122 (diff) |
Custom detekt rule for logger usage check
Check if logger invocations don't use unoptimal invocations, eg.
concatenation `debug("a=" + a)` instead of lambda use `debug {"a=" + a}`
Unfortunately to avoid defining dependencies in many places and having
circural dependencies it was necessarry to reorganize the maven module
structure. The goal was to have `sources` module with production code and
`build` module with build-time tooling (detekt rules among them).
Issue-ID: DCAEGEN2-1002
Change-Id: I36e677b98972aaae6905d722597cbce5e863d201
Signed-off-by: Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
Diffstat (limited to 'build/hv-collector-analysis/src/test/kotlin')
-rw-r--r-- | build/hv-collector-analysis/src/test/kotlin/org/onap/dcae/collectors/veshv/analysis/SuboptimalLoggerUsageTest.kt | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/build/hv-collector-analysis/src/test/kotlin/org/onap/dcae/collectors/veshv/analysis/SuboptimalLoggerUsageTest.kt b/build/hv-collector-analysis/src/test/kotlin/org/onap/dcae/collectors/veshv/analysis/SuboptimalLoggerUsageTest.kt new file mode 100644 index 00000000..0a1d658b --- /dev/null +++ b/build/hv-collector-analysis/src/test/kotlin/org/onap/dcae/collectors/veshv/analysis/SuboptimalLoggerUsageTest.kt @@ -0,0 +1,126 @@ +/* + * ============LICENSE_START======================================================= + * dcaegen2-collectors-veshv + * ================================================================================ + * Copyright (C) 2018 NOKIA + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.dcae.collectors.veshv.analysis + +import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.test.TestConfig +import io.gitlab.arturbosch.detekt.test.assertThat +import io.gitlab.arturbosch.detekt.test.compileAndLint +import org.jetbrains.spek.api.Spek +import org.jetbrains.spek.api.dsl.describe +import org.jetbrains.spek.api.dsl.it +import org.jetbrains.spek.api.dsl.xdescribe + +/** + * @author Piotr Jaszczyk <piotr.jaszczyk></piotr.jaszczyk>@nokia.com> + * @since November 2018 + */ +internal class SuboptimalLoggerUsageTest : Spek({ + + fun checkPassingCase(code: String, cut: SuboptimalLoggerUsage = SuboptimalLoggerUsage(Config.empty)) { + describe(code) { + val findings = cut.compileAndLint(CodeSamples.code(code)) + + it("should pass") { + assertThat(findings).isEmpty() + } + } + } + + fun checkFailingCase(code: String, cut: SuboptimalLoggerUsage = SuboptimalLoggerUsage(Config.empty)) { + describe(code) { + val findings = cut.compileAndLint(CodeSamples.code(code)) + + it("should fail") { + assertThat(findings).isNotEmpty() + } + } + } + + describe("passing cases") { + checkPassingCase(CodeSamples.noConcatCall) + checkPassingCase(CodeSamples.exceptionCall) + checkPassingCase(CodeSamples.lambdaCall) + checkPassingCase(CodeSamples.lambdaFunctionCall) + checkPassingCase(CodeSamples.lambdaExceptionCall) + } + + + describe("failing cases") { + checkFailingCase(CodeSamples.plainConcatCall) + checkFailingCase(CodeSamples.expansionCall) + checkFailingCase(CodeSamples.plainConcatExceptionCall) + checkFailingCase(CodeSamples.expansionExceptionCall) + } + + describe("custom configuration") { + val cut = SuboptimalLoggerUsage(TestConfig(mapOf("loggerNames" to "l,lo", "loggingMethodNames" to "print"))) + val strangeLogger = """ + val l = object { + fun print(m: String) { } + } + val lo = l + """.trimIndent() + + checkPassingCase(CodeSamples.plainConcatCall, cut) + + checkPassingCase(""" + $strangeLogger + l.print("n")""".trimIndent(), cut) + + checkFailingCase(""" + $strangeLogger + l.print("n=" + n)""".trimIndent(), cut) + + checkFailingCase(""" + $strangeLogger + lo.print("n=${'$'}n")""".trimIndent(), cut) + } +}) + +object CodeSamples { + private val codeBefore = """ + object logger { + fun debug(msg: String) { println(msg) } + fun debug(msg: String, ex: Throwable) { println(msg + ". Cause: " + ex) } + fun debug(msg: () -> String) { println(msg()) } + fun debug(ex: Throwable, msg: () -> String) { println(msg() + ". Cause: " + ex) } + } + + fun execute(n: Integer) { + val ex = Exception() + + """.trimIndent() + private const val codeAfter = """}""" + + const val noConcatCall = """logger.debug("Executing...")""" + const val exceptionCall = """logger.debug("Fail", ex)""" + const val lambdaCall = """logger.debug{ "n=${'$'}n" }""" + const val lambdaFunctionCall = """logger.debug { n.toString() }""" + const val lambdaExceptionCall = """logger.debug(ex) { "epic fail on n=" + n }""" + + const val plainConcatCall = """logger.debug("n=" + n)""" + const val expansionCall = """logger.debug("n=${'$'}n")""" + const val plainConcatExceptionCall = """logger.debug("Fail. n=" + n, ex)""" + const val expansionExceptionCall = """logger.debug("Fail. n=${'$'}n", ex)""" + + + fun code(core: String) = codeBefore + core + codeAfter +}
\ No newline at end of file |