From 6253ae530a1e7797138394ba1096425d444e0662 Mon Sep 17 00:00:00 2001 From: Kirill Shishin Date: Thu, 9 Nov 2023 18:01:59 +0300 Subject: [PATCH 1/2] Add summarization for usvm-sbft --- .../org/utbot/contest/usvm/ContestUsvm.kt | 4 +- .../kotlin/org/utbot/summary/Summarization.kt | 18 +++-- .../fuzzer/names/MethodBasedNameSuggester.kt | 4 +- .../org/utbot/summary/usvm/USummarization.kt | 77 +++++++++++++++++++ 4 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 utbot-summary/src/main/kotlin/org/utbot/summary/usvm/USummarization.kt diff --git a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/ContestUsvm.kt b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/ContestUsvm.kt index 97b073b2f0..5d01559386 100644 --- a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/ContestUsvm.kt +++ b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/ContestUsvm.kt @@ -35,7 +35,7 @@ import org.utbot.framework.plugin.api.util.method import org.utbot.framework.plugin.services.JdkInfoService import org.utbot.fuzzer.ReferencePreservingIntIdGenerator import org.utbot.fuzzer.UtFuzzedExecution -import org.utbot.summary.summarizeAll +import org.utbot.summary.usvm.summarizeAll import java.io.File import java.net.URLClassLoader import java.util.* @@ -265,7 +265,7 @@ fun runUsvmGeneration( val testSets = testsByMethod.map { (method, executions) -> UtMethodTestSet(method, minimizeExecutions(executions), jimpleBody = null) - }.summarizeAll(cut.classfileDir.toPath(), sourceFile = null) + }.summarizeAll(sourceFile = null) logger.info().measureTime({ "Flushing tests for [${cut.simpleName}] on disk" }) { writeTestClass(cut, codeGenerator.generateAsString(testSets)) diff --git a/utbot-summary/src/main/kotlin/org/utbot/summary/Summarization.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/Summarization.kt index db03adf89b..1583cf2664 100644 --- a/utbot-summary/src/main/kotlin/org/utbot/summary/Summarization.kt +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/Summarization.kt @@ -83,7 +83,7 @@ private fun UtMethodTestSet.summarizeOne(searchDirectory: Path, sourceFile: File ) // TODO: looks weird and don't create the real copy } -class Summarization(val sourceFile: File?, val invokeDescriptions: List) { +open class Summarization(val sourceFile: File?, val invokeDescriptions: List) { private val tagGenerator = TagGenerator() private val jimpleBodyAnalysis = ExecutionStructureAnalysis() @@ -239,10 +239,7 @@ class Summarization(val sourceFile: File?, val invokeDescriptions: List { val clustersToReturn: MutableList = mutableListOf() - val methodTestSet = when (descriptionSource) { - MethodDescriptionSource.FUZZER -> prepareTestSetWithFuzzedExecutions(testSet) - MethodDescriptionSource.SYMBOLIC -> prepareTestSetForByteCodeAnalysis(testSet) - } + val methodTestSet = prepareMethodTestSet(testSet, descriptionSource) if (methodTestSet.executions.isNotEmpty()) { methodTestSet.executions.forEach { utExecution -> @@ -263,7 +260,11 @@ class Summarization(val sourceFile: File?, val invokeDescriptions: List { val executableId = testSet.method val description = FuzzedMethodDescription(executableId).apply { + packageName = executableId.classId.packageName + className = executableId.classId.simpleName compilableName = if (!executableId.isConstructor) executableId.name else null + canonicalName = executableId.classId.canonicalName + isNested = executableId.classId.isNested } it.suggest( description, @@ -309,6 +310,13 @@ class Summarization(val sourceFile: File?, val invokeDescriptions: List prepareTestSetWithFuzzedExecutions(testSet) + MethodDescriptionSource.SYMBOLIC -> prepareTestSetForByteCodeAnalysis(testSet) + } + } + /** Filter and copies executions with non-empty paths. */ private fun prepareTestSetForByteCodeAnalysis(testSet: UtMethodTestSet): UtMethodTestSet { val executions = diff --git a/utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/MethodBasedNameSuggester.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/MethodBasedNameSuggester.kt index a1ba9a7254..e38f566657 100644 --- a/utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/MethodBasedNameSuggester.kt +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/MethodBasedNameSuggester.kt @@ -4,6 +4,7 @@ import org.utbot.framework.plugin.api.UtExecutionResult import org.utbot.fuzzer.FuzzedMethodDescription import org.utbot.fuzzer.FuzzedValue import org.utbot.summary.MethodDescriptionSource +import java.util.* class MethodBasedNameSuggester(private val source: MethodDescriptionSource = MethodDescriptionSource.FUZZER) : NameSuggester { override fun suggest( @@ -11,7 +12,8 @@ class MethodBasedNameSuggester(private val source: MethodDescriptionSource = Met values: List, result: UtExecutionResult? ): Sequence { - val compilableName = description.compilableName?.capitalize() ?: "Created" + val compilableName = description.compilableName?.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } + ?: "Created" // See [Summarization.generateSummariesForTests]. val suffix = if (source == MethodDescriptionSource.FUZZER) "ByFuzzer" else "" return sequenceOf(TestSuggestedInfo("test${compilableName}${suffix}")) diff --git a/utbot-summary/src/main/kotlin/org/utbot/summary/usvm/USummarization.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/usvm/USummarization.kt new file mode 100644 index 0000000000..ff2e4a2c05 --- /dev/null +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/usvm/USummarization.kt @@ -0,0 +1,77 @@ +package org.utbot.summary.usvm + +import org.utbot.framework.plugin.api.UtMethodTestSet +import mu.KotlinLogging +import org.utbot.common.measureTime +import org.utbot.common.info +import org.utbot.framework.SummariesGenerationType.* +import org.utbot.framework.UtSettings.enableDisplayNameGeneration +import org.utbot.framework.UtSettings.enableJavaDocGeneration +import org.utbot.framework.UtSettings.enableTestNamesGeneration +import org.utbot.framework.UtSettings.summaryGenerationType +import org.utbot.summary.InvokeDescription +import org.utbot.summary.MethodDescriptionSource +import org.utbot.summary.Summarization +import java.io.File + +private val logger = KotlinLogging.logger {} + +/** +USummarization is used to generate summaries for *usvm-sbft*. + +To generate summary, use the following settings: +- *SummariesGenerationType == LIGHT* +- *enableTestNamesGeneration = true* +- *enableDisplayNameGeneration = false* +- *enableJavaDocGeneration = true* + */ + +fun Collection.summarizeAll(sourceFile: File?): List = + logger.info().measureTime({ + "----------------------------------------------------------------------------------------\n" + + "-------------------Summarization started for ${this.size} test cases--------------------\n" + + "----------------------------------------------------------------------------------------" + }) { + this.map { + it.summarizeOne(sourceFile) + } + } + +private fun UtMethodTestSet.summarizeOne(sourceFile: File?): UtMethodTestSet = + logger.info().measureTime({ "Summarization for ${this.method}" }) { + + if (summaryGenerationType != LIGHT || !enableTestNamesGeneration || enableDisplayNameGeneration || !enableJavaDocGeneration) { + logger.info { + "Incorrect settings are used to generate Summaries for usvm-sbft" + } + return this + } + + USummarization(sourceFile, invokeDescriptions = emptyList()).fillSummaries(this) + return this + } + +class USummarization(sourceFile: File?, invokeDescriptions: List) : + Summarization(sourceFile, invokeDescriptions) { + + /* + * Used to prepare methodTestSet for further generation of summaries. + * In the case of generating tests using USVM, we only need to work with Symbolic tests. + */ + override fun prepareMethodTestSet( + testSet: UtMethodTestSet, + descriptionSource: MethodDescriptionSource + ): UtMethodTestSet { + return when (descriptionSource) { + MethodDescriptionSource.FUZZER -> UtMethodTestSet( + method = testSet.method, + executions = emptyList(), + jimpleBody = testSet.jimpleBody, + errors = testSet.errors, + clustersInfo = testSet.clustersInfo + ) + + MethodDescriptionSource.SYMBOLIC -> testSet + } + } +} From a3a1af5c678454acbca3c17506f88c9533862cf8 Mon Sep 17 00:00:00 2001 From: Kirill Shishin Date: Mon, 13 Nov 2023 14:15:02 +0300 Subject: [PATCH 2/2] Add summary setting to the setOption method and do small refactoring --- .../src/main/kotlin/org/utbot/contest/Contest.kt | 3 +++ .../src/main/kotlin/org/utbot/contest/usvm/ContestUsvm.kt | 2 +- .../main/kotlin/org/utbot/summary/usvm/USummarization.kt | 8 ++++---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt index 3a20f61596..94d9b4da7c 100644 --- a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt +++ b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt @@ -161,6 +161,9 @@ fun setOptions() { // We need to use assemble model generator to increase readability UtSettings.useAssembleModelGenerator = true UtSettings.summaryGenerationType = SummariesGenerationType.LIGHT + UtSettings.enableTestNamesGeneration = true + UtSettings.enableDisplayNameGeneration = false + UtSettings.enableJavaDocGeneration = true UtSettings.preferredCexOption = false UtSettings.warmupConcreteExecution = true UtSettings.testMinimizationStrategyType = TestSelectionStrategyType.COVERAGE_STRATEGY diff --git a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/ContestUsvm.kt b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/ContestUsvm.kt index 5d01559386..be20a2c366 100644 --- a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/ContestUsvm.kt +++ b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/ContestUsvm.kt @@ -265,7 +265,7 @@ fun runUsvmGeneration( val testSets = testsByMethod.map { (method, executions) -> UtMethodTestSet(method, minimizeExecutions(executions), jimpleBody = null) - }.summarizeAll(sourceFile = null) + }.summarizeAll() logger.info().measureTime({ "Flushing tests for [${cut.simpleName}] on disk" }) { writeTestClass(cut, codeGenerator.generateAsString(testSets)) diff --git a/utbot-summary/src/main/kotlin/org/utbot/summary/usvm/USummarization.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/usvm/USummarization.kt index ff2e4a2c05..d4aab53e33 100644 --- a/utbot-summary/src/main/kotlin/org/utbot/summary/usvm/USummarization.kt +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/usvm/USummarization.kt @@ -26,18 +26,18 @@ To generate summary, use the following settings: - *enableJavaDocGeneration = true* */ -fun Collection.summarizeAll(sourceFile: File?): List = +fun Collection.summarizeAll(): List = logger.info().measureTime({ "----------------------------------------------------------------------------------------\n" + "-------------------Summarization started for ${this.size} test cases--------------------\n" + "----------------------------------------------------------------------------------------" }) { this.map { - it.summarizeOne(sourceFile) + it.summarizeOne() } } -private fun UtMethodTestSet.summarizeOne(sourceFile: File?): UtMethodTestSet = +private fun UtMethodTestSet.summarizeOne(): UtMethodTestSet = logger.info().measureTime({ "Summarization for ${this.method}" }) { if (summaryGenerationType != LIGHT || !enableTestNamesGeneration || enableDisplayNameGeneration || !enableJavaDocGeneration) { @@ -47,7 +47,7 @@ private fun UtMethodTestSet.summarizeOne(sourceFile: File?): UtMethodTestSet = return this } - USummarization(sourceFile, invokeDescriptions = emptyList()).fillSummaries(this) + USummarization(sourceFile = null, invokeDescriptions = emptyList()).fillSummaries(this) return this }