@@ -25,19 +25,25 @@ import com.intellij.testIntegration.TestIntegrationUtils
2525import com.intellij.util.concurrency.AppExecutorUtil
2626import mu.KotlinLogging
2727import org.jetbrains.kotlin.idea.util.module
28+ import org.utbot.analytics.EngineAnalyticsContext
29+ import org.utbot.analytics.Predictors
30+ import org.utbot.common.filterWhen
2831import org.utbot.engine.util.mockListeners.ForceMockListener
2932import org.utbot.framework.plugin.services.JdkInfoService
3033import org.utbot.framework.UtSettings
3134import org.utbot.framework.plugin.api.TestCaseGenerator
3235import org.utbot.framework.plugin.api.UtMethod
3336import org.utbot.framework.plugin.api.UtMethodTestSet
37+ import org.utbot.framework.plugin.api.testFlow
3438import org.utbot.framework.plugin.api.util.UtContext
3539import org.utbot.framework.plugin.api.util.withStaticsSubstitutionRequired
3640import org.utbot.framework.plugin.api.util.withUtContext
3741import org.utbot.intellij.plugin.generator.CodeGenerationController.generateTests
3842import org.utbot.intellij.plugin.models.GenerateTestsModel
3943import org.utbot.intellij.plugin.ui.GenerateTestsDialogWindow
4044import org.utbot.intellij.plugin.ui.utils.showErrorDialogLater
45+ import org.utbot.intellij.plugin.ui.utils.suitableTestSourceRoots
46+ import org.utbot.intellij.plugin.ui.utils.testModules
4147import org.utbot.intellij.plugin.util.IntelliJApiHelper
4248import org.utbot.intellij.plugin.util.PluginJdkInfoProvider
4349import org.utbot.intellij.plugin.util.signature
@@ -47,16 +53,14 @@ import java.net.URLClassLoader
4753import java.nio.file.Path
4854import java.nio.file.Paths
4955import java.util.concurrent.TimeUnit
50- import org.utbot.common.filterWhen
5156import org.utbot.engine.util.mockListeners.ForceStaticMockListener
52- import org.utbot.framework.plugin.api.testFlow
57+ import org.utbot.framework.PathSelectorType
5358import org.utbot.framework.plugin.services.WorkingDirService
5459import org.utbot.intellij.plugin.settings.Settings
5560import org.utbot.intellij.plugin.ui.utils.isBuildWithGradle
5661import org.utbot.intellij.plugin.ui.utils.suitableTestSourceRoots
5762import org.utbot.intellij.plugin.util.PluginWorkingDirProvider
5863import org.utbot.intellij.plugin.util.isAbstract
59- import org.utbot.intellij.plugin.ui.utils.testModules
6064import kotlin.reflect.KClass
6165import kotlin.reflect.full.functions
6266
@@ -112,7 +116,8 @@ object UtTestsDialogProcessor {
112116 .make(
113117 // Compile only chosen classes and their dependencies before generation.
114118 CompositeScope (
115- model.srcClasses.map{ OneProjectItemCompileScope (project, it.containingFile.virtualFile) }.toTypedArray()
119+ model.srcClasses.map { OneProjectItemCompileScope (project, it.containingFile.virtualFile) }
120+ .toTypedArray()
116121 )
117122 ) { aborted: Boolean , errors: Int , _: Int , _: CompileContext ->
118123 if (! aborted && errors == 0 ) {
@@ -143,18 +148,23 @@ object UtTestsDialogProcessor {
143148 var processedClasses = 0
144149 val totalClasses = model.srcClasses.size
145150
151+ configureML()
152+
146153 val testCaseGenerator = TestCaseGenerator (
147- Paths .get(buildDir),
148- classpath,
149- pluginJarsPath.joinToString(separator = File .pathSeparator),
150- isCanceled = { indicator.isCanceled }
151- )
154+ Paths .get(buildDir),
155+ classpath,
156+ pluginJarsPath.joinToString(separator = File .pathSeparator),
157+ isCanceled = { indicator.isCanceled }
158+ )
152159
153160 for (srcClass in model.srcClasses) {
154161 val methods = ReadAction .nonBlocking<List <UtMethod <* >>> {
155162 val clazz = classLoader.loadClass(srcClass.qualifiedName).kotlin
156- val srcMethods = model.selectedMethods?.toList() ? :
157- TestIntegrationUtils .extractClassMethods(srcClass, false )
163+ val srcMethods =
164+ model.selectedMethods?.toList() ? : TestIntegrationUtils .extractClassMethods(
165+ srcClass,
166+ false
167+ )
158168 .filterWhen(UtSettings .skipTestGenerationForSyntheticMethods) {
159169 it.member !is SyntheticElement
160170 }
@@ -172,14 +182,18 @@ object UtTestsDialogProcessor {
172182
173183 indicator.text = " Generate test cases for class $className "
174184 if (totalClasses > 1 ) {
175- indicator.fraction = indicator.fraction.coerceAtLeast(0.9 * processedClasses / totalClasses)
185+ indicator.fraction =
186+ indicator.fraction.coerceAtLeast(0.9 * processedClasses / totalClasses)
176187 }
177188
178189 // set timeout for concrete execution and for generated tests
179190 UtSettings .concreteExecutionTimeoutInChildProcess = model.hangingTestsTimeout.timeoutMs
180191
181- val searchDirectory = ReadAction
182- .nonBlocking<Path > { project.basePath?.let { Paths .get(it) } ? : Paths .get(srcClass.containingFile.virtualFile.parent.path) }
192+ val searchDirectory = ReadAction
193+ .nonBlocking<Path > {
194+ project.basePath?.let { Paths .get(it) }
195+ ? : Paths .get(srcClass.containingFile.virtualFile.parent.path)
196+ }
183197 .executeSynchronously()
184198
185199 withStaticsSubstitutionRequired(true ) {
@@ -197,17 +211,17 @@ object UtTestsDialogProcessor {
197211 withUtContext(context) {
198212 testCaseGenerator
199213 .generate(
200- methods,
201- model.mockStrategy,
202- model.chosenClassesToMockAlways,
203- model.timeout,
204- generate = testFlow {
205- generationTimeout = model.timeout
206- isSymbolicEngineEnabled = true
207- isFuzzingEnabled = UtSettings .useFuzzing
208- fuzzingValue = project.service<Settings >().fuzzingValue
209- }
210- )
214+ methods,
215+ model.mockStrategy,
216+ model.chosenClassesToMockAlways,
217+ model.timeout,
218+ generate = testFlow {
219+ generationTimeout = model.timeout
220+ isSymbolicEngineEnabled = true
221+ isFuzzingEnabled = UtSettings .useFuzzing
222+ fuzzingValue = project.service<Settings >().fuzzingValue
223+ }
224+ )
211225 .map { it.summarize(searchDirectory) }
212226 .filterNot { it.executions.isEmpty() && it.errors.isEmpty() }
213227 }
@@ -237,7 +251,8 @@ object UtTestsDialogProcessor {
237251 Messages .showInfoMessage(
238252 model.project,
239253 " No methods for test generation were found among selected items" ,
240- " No methods found" )
254+ " No methods found"
255+ )
241256 }
242257 return
243258 }
@@ -258,14 +273,47 @@ object UtTestsDialogProcessor {
258273 }
259274 }
260275
276+ /* *
277+ * Configures utbot-analytics models for the better path selection.
278+ *
279+ * NOTE: If analytics configuration for the NN Path Selector could not be loaded,
280+ * it switches to the [PathSelectorType.INHERITORS_SELECTOR].
281+ */
282+ private fun configureML () {
283+ logger.info { " PathSelectorType: ${UtSettings .pathSelectorType} " }
284+
285+ if (UtSettings .pathSelectorType == PathSelectorType .NN_REWARD_GUIDED_SELECTOR ) {
286+ val analyticsConfigurationClassPath = UtSettings .analyticsConfigurationClassPath
287+ try {
288+ Class .forName(analyticsConfigurationClassPath)
289+ Predictors .stateRewardPredictor = EngineAnalyticsContext .stateRewardPredictorFactory()
290+
291+ logger.info { " RewardModelPath: ${UtSettings .rewardModelPath} " }
292+ } catch (e: ClassNotFoundException ) {
293+ logger.error {
294+ " Configuration of the predictors from the utbot-analytics module described in the class: " +
295+ " $analyticsConfigurationClassPath is not found!"
296+ }
297+
298+ logger.info(e) {
299+ " Error while initialization of ${UtSettings .pathSelectorType} . Changing pathSelectorType on INHERITORS_SELECTOR"
300+ }
301+ UtSettings .pathSelectorType = PathSelectorType .INHERITORS_SELECTOR
302+ }
303+ }
304+ }
305+
261306 private fun errorMessage (className : String? , timeout : Long ) = buildString {
262307 appendLine(" UtBot failed to generate any test cases for class $className ." )
263308 appendLine()
264309 appendLine(" Try to alter test generation configuration, e.g. enable mocking and static mocking." )
265310 appendLine(" Alternatively, you could try to increase current timeout $timeout sec for generating tests in generation dialog." )
266311 }
267312
268- private fun findMethodsInClassMatchingSelected (clazz : KClass <* >, selectedMethods : List <MemberInfo >): List <UtMethod <* >> {
313+ private fun findMethodsInClassMatchingSelected (
314+ clazz : KClass <* >,
315+ selectedMethods : List <MemberInfo >
316+ ): List <UtMethod <* >> {
269317 val selectedSignatures = selectedMethods.map { it.signature() }
270318 return clazz.functions
271319 .sortedWith(compareBy { selectedSignatures.indexOf(it.signature()) })
0 commit comments