@@ -8,6 +8,7 @@ import org.utbot.fuzzing.BaseFeedback
88import org.utbot.fuzzing.Control
99import org.utbot.fuzzing.utils.Trie
1010import org.utbot.go.api.*
11+ import org.utbot.go.imports.GoImportsResolver
1112import org.utbot.go.logic.EachExecutionTimeoutsMillisConfig
1213import org.utbot.go.util.executeCommandByNewProcessOrFailWithoutWaiting
1314import org.utbot.go.worker.GoWorker
@@ -16,14 +17,13 @@ import org.utbot.go.worker.convertRawExecutionResultToExecutionResult
1617import java.io.File
1718import java.io.InputStreamReader
1819import java.net.ServerSocket
19- import java.net.SocketException
2020import java.net.SocketTimeoutException
2121import java.util.concurrent.TimeUnit
2222
2323val logger = KotlinLogging .logger {}
2424
2525class GoEngine (
26- private val methodUnderTest : GoUtFunction ,
26+ private val functionUnderTest : GoUtFunction ,
2727 private val sourceFile : GoUtFile ,
2828 private val goExecutableAbsolutePath : String ,
2929 private val eachExecutionTimeoutsMillisConfig : EachExecutionTimeoutsMillisConfig ,
@@ -36,63 +36,81 @@ class GoEngine(
3636 val attemptsLimit = Int .MAX_VALUE
3737 ServerSocket (0 ).use { serverSocket ->
3838 var fileToExecute: File ? = null
39+ var fileWithModifiedFunction: File ? = null
3940 try {
41+ // creating files for worker
42+ val types = functionUnderTest.parameters.map { it.type }
43+ val imports = GoImportsResolver .resolveImportsBasedOnTypes(
44+ types,
45+ functionUnderTest.sourcePackage,
46+ GoWorkerCodeGenerationHelper .alwaysRequiredImports
47+ )
4048 fileToExecute = GoWorkerCodeGenerationHelper .createFileToExecute(
4149 sourceFile,
42- methodUnderTest ,
50+ functionUnderTest ,
4351 eachExecutionTimeoutsMillisConfig,
44- serverSocket.localPort
52+ serverSocket.localPort,
53+ imports
54+ )
55+ fileWithModifiedFunction = GoWorkerCodeGenerationHelper .createFileWithModifiedFunction(
56+ sourceFile, functionUnderTest
4557 )
58+
59+ // starting worker process
4660 val testFunctionName = GoWorkerCodeGenerationHelper .workerTestFunctionName
4761 val command = listOf (
4862 goExecutableAbsolutePath, " test" , " -run" , testFunctionName
4963 )
5064 val sourceFileDir = File (sourceFile.absoluteDirectoryPath)
5165 val processStartTime = System .currentTimeMillis()
5266 val process = executeCommandByNewProcessOrFailWithoutWaiting(command, sourceFileDir)
53- val workerSocket = try {
54- serverSocket.soTimeout = timeoutMillis.toInt()
55- serverSocket.accept()
56- } catch (e: SocketTimeoutException ) {
57- val processHasExited = process.waitFor(timeoutMillis, TimeUnit .MILLISECONDS )
58- if (processHasExited) {
59- val processOutput = InputStreamReader (process.inputStream).readText()
60- throw TimeoutException (" Timeout exceeded: Worker not connected. Process output: $processOutput " )
61- } else {
62- process.destroy()
63- }
64- throw TimeoutException (" Timeout exceeded: Worker not connected" )
65- }
66- logger.debug { " Worker connected - completed in ${System .currentTimeMillis() - processStartTime} ms" }
67+
6768 try {
68- val worker = GoWorker (workerSocket)
69- if (methodUnderTest.parameters.isEmpty()) {
70- worker.sendFuzzedParametersValues(listOf ())
69+ // connecting to worker
70+ logger.debug { " Trying to connect to worker" }
71+ val workerSocket = try {
72+ serverSocket.soTimeout = timeoutMillis.toInt()
73+ serverSocket.accept()
74+ } catch (e: SocketTimeoutException ) {
75+ val processHasExited = process.waitFor(timeoutMillis, TimeUnit .MILLISECONDS )
76+ if (processHasExited) {
77+ val processOutput = InputStreamReader (process.inputStream).readText()
78+ throw TimeoutException (" Timeout exceeded: Worker not connected. Process output: $processOutput " )
79+ } else {
80+ process.destroy()
81+ }
82+ throw TimeoutException (" Timeout exceeded: Worker not connected" )
83+ }
84+ val worker = GoWorker (workerSocket, functionUnderTest)
85+ logger.debug { " Worker connected - completed in ${System .currentTimeMillis() - processStartTime} ms" }
86+
87+ // fuzzing
88+ if (functionUnderTest.parameters.isEmpty()) {
89+ worker.sendFuzzedParametersValues(emptyList(), emptyMap())
7190 val rawExecutionResult = worker.receiveRawExecutionResult()
7291 val executionResult = convertRawExecutionResultToExecutionResult(
73- methodUnderTest.getPackageName(),
7492 rawExecutionResult,
75- methodUnderTest .resultTypes,
76- eachExecutionTimeoutsMillisConfig[methodUnderTest ],
93+ functionUnderTest .resultTypes,
94+ eachExecutionTimeoutsMillisConfig[functionUnderTest ],
7795 )
78- val fuzzedFunction = GoUtFuzzedFunction (methodUnderTest, listOf ())
96+ val fuzzedFunction = GoUtFuzzedFunction (functionUnderTest, emptyList ())
7997 emit(fuzzedFunction to executionResult)
8098 } else {
81- runGoFuzzing(methodUnderTest) { description, values ->
99+ val aliases = imports.filter { it.alias != null }.associate { it.goPackage to it.alias }
100+ runGoFuzzing(functionUnderTest) { description, values ->
82101 if (timeoutExceededOrIsCanceled()) {
83102 return @runGoFuzzing BaseFeedback (result = Trie .emptyNode(), control = Control .STOP )
84103 }
85- val fuzzedFunction = GoUtFuzzedFunction (methodUnderTest , values)
86- worker.sendFuzzedParametersValues(values)
104+ val fuzzedFunction = GoUtFuzzedFunction (functionUnderTest , values)
105+ worker.sendFuzzedParametersValues(values, aliases )
87106 val rawExecutionResult = worker.receiveRawExecutionResult()
88107 val executionResult = convertRawExecutionResultToExecutionResult(
89- methodUnderTest.getPackageName(),
90108 rawExecutionResult,
91- methodUnderTest .resultTypes,
92- eachExecutionTimeoutsMillisConfig[methodUnderTest ],
109+ functionUnderTest .resultTypes,
110+ eachExecutionTimeoutsMillisConfig[functionUnderTest ],
93111 )
94112 if (executionResult.trace.isEmpty()) {
95- logger.error { " Coverage is empty for [${methodUnderTest .name} ] with $values }" }
113+ logger.error { " Coverage is empty for [${functionUnderTest .name} ] with $values }" }
96114 if (executionResult is GoUtPanicFailure ) {
97115 logger.error { " Execution completed with panic: ${executionResult.panicValue} " }
98116 }
@@ -102,8 +120,7 @@ class GoEngine(
102120 if (trieNode.count > 1 ) {
103121 if (++ attempts >= attemptsLimit) {
104122 return @runGoFuzzing BaseFeedback (
105- result = Trie .emptyNode(),
106- control = Control .STOP
123+ result = Trie .emptyNode(), control = Control .STOP
107124 )
108125 }
109126 return @runGoFuzzing BaseFeedback (result = trieNode, control = Control .CONTINUE )
@@ -122,13 +139,13 @@ class GoEngine(
122139 val processOutput = InputStreamReader (process.inputStream).readText()
123140 throw RuntimeException (
124141 StringBuilder ()
125- .append(" Execution of ${" function [${methodUnderTest .name} ] from $sourceFile " } in child process failed with non-zero exit code = $exitCode : " )
126- .append( " \n $processOutput " )
127- .toString()
142+ .append(" Execution of ${" function [${functionUnderTest .name} ] from $sourceFile " } in child process failed with non-zero exit code = $exitCode : " )
143+ .appendLine( )
144+ .append(processOutput). toString()
128145 )
129146 }
130147 }
131- } catch (e: SocketException ) {
148+ } catch (e: Exception ) {
132149 val processHasExited = process.waitFor(timeoutMillis, TimeUnit .MILLISECONDS )
133150 if (! processHasExited) {
134151 process.destroy()
@@ -139,14 +156,15 @@ class GoEngine(
139156 val processOutput = InputStreamReader (process.inputStream).readText()
140157 throw RuntimeException (
141158 StringBuilder ()
142- .append(" Execution of ${" function [${methodUnderTest .name} ] from $sourceFile " } in child process failed with non-zero exit code = $exitCode : " )
143- .append( " \n $processOutput " )
144- .toString()
159+ .append(" Execution of ${" function [${functionUnderTest .name} ] from $sourceFile " } in child process failed with non-zero exit code = $exitCode : " )
160+ .appendLine( )
161+ .append(processOutput). toString()
145162 )
146163 }
147164 }
148165 } finally {
149166 fileToExecute?.delete()
167+ fileWithModifiedFunction?.delete()
150168 }
151169 }
152170 }
0 commit comments