@@ -25,19 +25,25 @@ import com.intellij.testIntegration.TestIntegrationUtils
25
25
import com.intellij.util.concurrency.AppExecutorUtil
26
26
import mu.KotlinLogging
27
27
import org.jetbrains.kotlin.idea.util.module
28
+ import org.utbot.analytics.EngineAnalyticsContext
29
+ import org.utbot.analytics.Predictors
30
+ import org.utbot.common.filterWhen
28
31
import org.utbot.engine.util.mockListeners.ForceMockListener
29
32
import org.utbot.framework.plugin.services.JdkInfoService
30
33
import org.utbot.framework.UtSettings
31
34
import org.utbot.framework.plugin.api.TestCaseGenerator
32
35
import org.utbot.framework.plugin.api.UtMethod
33
36
import org.utbot.framework.plugin.api.UtMethodTestSet
37
+ import org.utbot.framework.plugin.api.testFlow
34
38
import org.utbot.framework.plugin.api.util.UtContext
35
39
import org.utbot.framework.plugin.api.util.withStaticsSubstitutionRequired
36
40
import org.utbot.framework.plugin.api.util.withUtContext
37
41
import org.utbot.intellij.plugin.generator.CodeGenerationController.generateTests
38
42
import org.utbot.intellij.plugin.models.GenerateTestsModel
39
43
import org.utbot.intellij.plugin.ui.GenerateTestsDialogWindow
40
44
import 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
41
47
import org.utbot.intellij.plugin.util.IntelliJApiHelper
42
48
import org.utbot.intellij.plugin.util.PluginJdkInfoProvider
43
49
import org.utbot.intellij.plugin.util.signature
@@ -47,16 +53,14 @@ import java.net.URLClassLoader
47
53
import java.nio.file.Path
48
54
import java.nio.file.Paths
49
55
import java.util.concurrent.TimeUnit
50
- import org.utbot.common.filterWhen
51
56
import org.utbot.engine.util.mockListeners.ForceStaticMockListener
52
- import org.utbot.framework.plugin.api.testFlow
57
+ import org.utbot.framework.PathSelectorType
53
58
import org.utbot.framework.plugin.services.WorkingDirService
54
59
import org.utbot.intellij.plugin.settings.Settings
55
60
import org.utbot.intellij.plugin.ui.utils.isBuildWithGradle
56
61
import org.utbot.intellij.plugin.ui.utils.suitableTestSourceRoots
57
62
import org.utbot.intellij.plugin.util.PluginWorkingDirProvider
58
63
import org.utbot.intellij.plugin.util.isAbstract
59
- import org.utbot.intellij.plugin.ui.utils.testModules
60
64
import kotlin.reflect.KClass
61
65
import kotlin.reflect.full.functions
62
66
@@ -112,7 +116,8 @@ object UtTestsDialogProcessor {
112
116
.make(
113
117
// Compile only chosen classes and their dependencies before generation.
114
118
CompositeScope (
115
- model.srcClasses.map{ OneProjectItemCompileScope (project, it.containingFile.virtualFile) }.toTypedArray()
119
+ model.srcClasses.map { OneProjectItemCompileScope (project, it.containingFile.virtualFile) }
120
+ .toTypedArray()
116
121
)
117
122
) { aborted: Boolean , errors: Int , _: Int , _: CompileContext ->
118
123
if (! aborted && errors == 0 ) {
@@ -143,18 +148,23 @@ object UtTestsDialogProcessor {
143
148
var processedClasses = 0
144
149
val totalClasses = model.srcClasses.size
145
150
151
+ configureML()
152
+
146
153
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
+ )
152
159
153
160
for (srcClass in model.srcClasses) {
154
161
val methods = ReadAction .nonBlocking<List <UtMethod <* >>> {
155
162
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
+ )
158
168
.filterWhen(UtSettings .skipTestGenerationForSyntheticMethods) {
159
169
it.member !is SyntheticElement
160
170
}
@@ -172,14 +182,18 @@ object UtTestsDialogProcessor {
172
182
173
183
indicator.text = " Generate test cases for class $className "
174
184
if (totalClasses > 1 ) {
175
- indicator.fraction = indicator.fraction.coerceAtLeast(0.9 * processedClasses / totalClasses)
185
+ indicator.fraction =
186
+ indicator.fraction.coerceAtLeast(0.9 * processedClasses / totalClasses)
176
187
}
177
188
178
189
// set timeout for concrete execution and for generated tests
179
190
UtSettings .concreteExecutionTimeoutInChildProcess = model.hangingTestsTimeout.timeoutMs
180
191
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
+ }
183
197
.executeSynchronously()
184
198
185
199
withStaticsSubstitutionRequired(true ) {
@@ -197,17 +211,17 @@ object UtTestsDialogProcessor {
197
211
withUtContext(context) {
198
212
testCaseGenerator
199
213
.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
+ )
211
225
.map { it.summarize(searchDirectory) }
212
226
.filterNot { it.executions.isEmpty() && it.errors.isEmpty() }
213
227
}
@@ -237,7 +251,8 @@ object UtTestsDialogProcessor {
237
251
Messages .showInfoMessage(
238
252
model.project,
239
253
" No methods for test generation were found among selected items" ,
240
- " No methods found" )
254
+ " No methods found"
255
+ )
241
256
}
242
257
return
243
258
}
@@ -258,14 +273,47 @@ object UtTestsDialogProcessor {
258
273
}
259
274
}
260
275
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
+
261
306
private fun errorMessage (className : String? , timeout : Long ) = buildString {
262
307
appendLine(" UtBot failed to generate any test cases for class $className ." )
263
308
appendLine()
264
309
appendLine(" Try to alter test generation configuration, e.g. enable mocking and static mocking." )
265
310
appendLine(" Alternatively, you could try to increase current timeout $timeout sec for generating tests in generation dialog." )
266
311
}
267
312
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 <* >> {
269
317
val selectedSignatures = selectedMethods.map { it.signature() }
270
318
return clazz.functions
271
319
.sortedWith(compareBy { selectedSignatures.indexOf(it.signature()) })
0 commit comments