1
1
#include " KleeRunner.h"
2
2
3
3
#include " Paths.h"
4
+ #include " TimeExecStatistics.h"
4
5
#include " exceptions/FileNotPresentedInArtifactException.h"
5
6
#include " exceptions/FileNotPresentedInCommandsException.h"
6
7
#include " tasks/RunKleeTask.h"
7
8
#include " utils/ExecUtils.h"
8
9
#include " utils/FileSystemUtils.h"
9
10
#include " utils/KleeUtils.h"
10
11
#include " utils/LogUtils.h"
11
- #include " TimeExecStatistics.h"
12
12
13
13
#include " loguru.h"
14
14
15
+ #include < fstream>
15
16
#include < utility>
16
17
17
18
using namespace tests ;
@@ -119,56 +120,10 @@ namespace {
119
120
}
120
121
}
121
122
122
- void KleeRunner::processBatchWithoutInteractive (MethodKtests &ktestChunk,
123
- const TestMethod &testMethod,
124
- Tests &tests) {
125
- if (!tests.isFilePresentedInArtifact ) {
126
- return ;
127
- }
128
- if (testMethod.sourceFilePath != tests.sourceFilePath ) {
129
- std::string message = StringUtils::stringFormat (
130
- " While generating tests for source file: %s tried to generate tests for method %s "
131
- " from another source file: %s. This can cause invalid generation.\n " ,
132
- tests.sourceFilePath , testMethod.methodName , testMethod.sourceFilePath );
133
- LOG_S (WARNING) << message;
134
- }
135
-
136
- std::string entryPoint = KleeUtils::entryPointFunction (tests, testMethod.methodName , true );
137
- std::string entryPointFlag = StringUtils::stringFormat (" --entry-point=%s" , entryPoint);
138
- auto kleeOut = getKleeMethodOutFile (testMethod);
139
- fs::create_directories (kleeOut.parent_path ());
140
- std::string outputDir = " --output-dir=" + kleeOut.string ();
141
- std::vector<std::string> argvData = { " klee" ,
142
- entryPointFlag,
143
- " --libc=klee" ,
144
- " --posix-runtime" ,
145
- " --fp-runtime" ,
146
- " --only-output-states-covering-new" ,
147
- " --allocate-determ" ,
148
- " --external-calls=all" ,
149
- " --timer-interval=1000ms" ,
150
- " --bcov-check-interval=6s" ,
151
- " -istats-write-interval=5s" ,
152
- " --disable-verify" ,
153
- " --check-div-zero=false" ,
154
- " --check-overshift=false" ,
155
- " --skip-not-lazy-and-symbolic-pointers" ,
156
- outputDir };
157
- if (settingsContext.useDeterministicSearcher ) {
158
- argvData.emplace_back (" --search=dfs" );
159
- }
160
- argvData.push_back (testMethod.bitcodeFilePath );
161
- argvData.emplace_back (" --sym-stdin" );
162
- argvData.emplace_back (std::to_string (types::Type::symStdinSize));
163
- std::vector<char *> cargv, cenvp;
164
- std::vector<std::string> tmp;
165
- ExecUtils::toCArgumentsPtr (argvData, tmp, cargv, cenvp, false );
166
- LOG_S (DEBUG) << " Klee command :: " + StringUtils::joinWith (argvData, " " );
167
- MEASURE_FUNCTION_EXECUTION_TIME
168
- RunKleeTask task (cargv.size (), cargv.data (), settingsContext.timeoutPerFunction );
169
- ExecUtils::ExecutionResult result __attribute__ ((unused)) = task.run ();
170
- ExecUtils::throwIfCancelled ();
171
-
123
+ static void processMethod (MethodKtests &ktestChunk,
124
+ tests::Tests &tests,
125
+ const fs::path &kleeOut,
126
+ const tests::TestMethod &method) {
172
127
if (fs::exists (kleeOut)) {
173
128
clearUnusedData (kleeOut);
174
129
bool hasTimeout = false ;
@@ -198,32 +153,89 @@ void KleeRunner::processBatchWithoutInteractive(MethodKtests &ktestChunk,
198
153
return UTBotKTestObject{ kTestObject };
199
154
});
200
155
201
- ktestChunk[testMethod ].emplace_back (objects, status);
156
+ ktestChunk[method ].emplace_back (objects, status);
202
157
}
203
158
}
204
159
}
205
160
if (hasTimeout) {
206
161
std::string message = StringUtils::stringFormat (
207
162
" Some tests for function '%s' were skipped, as execution of function is "
208
163
" out of timeout." ,
209
- testMethod .methodName );
164
+ method .methodName );
210
165
tests.commentBlocks .emplace_back (std::move (message));
211
166
}
212
167
if (hasError) {
213
168
std::string message = StringUtils::stringFormat (
214
169
" Some tests for function '%s' were skipped, as execution of function leads "
215
170
" KLEE to the internal error. See console log for more details." ,
216
- testMethod .methodName );
171
+ method .methodName );
217
172
tests.commentBlocks .emplace_back (std::move (message));
218
173
}
174
+
219
175
writeKleeStats (kleeOut);
176
+
177
+ if (!CollectionUtils::containsKey (ktestChunk, method) || ktestChunk.at (method).empty ()) {
178
+ tests.commentBlocks .emplace_back (StringUtils::stringFormat (
179
+ " Tests for %s were not generated. Maybe the function is too complex." ,
180
+ method.methodName ));
181
+ }
182
+ }
183
+ }
184
+
185
+ void KleeRunner::processBatchWithoutInteractive (MethodKtests &ktestChunk,
186
+ const TestMethod &testMethod,
187
+ Tests &tests) {
188
+ if (!tests.isFilePresentedInArtifact ) {
189
+ return ;
190
+ }
191
+ if (testMethod.sourceFilePath != tests.sourceFilePath ) {
192
+ std::string message = StringUtils::stringFormat (
193
+ " While generating tests for source file: %s tried to generate tests for method %s "
194
+ " from another source file: %s. This can cause invalid generation.\n " ,
195
+ tests.sourceFilePath , testMethod.methodName , testMethod.sourceFilePath );
196
+ LOG_S (WARNING) << message;
197
+ }
198
+
199
+ std::string entryPoint = KleeUtils::entryPointFunction (tests, testMethod.methodName , true );
200
+ std::string entryPointFlag = StringUtils::stringFormat (" --entry-point=%s" , entryPoint);
201
+ auto kleeOut = getKleeMethodOutFile (testMethod);
202
+ fs::create_directories (kleeOut.parent_path ());
203
+ std::string outputDir = " --output-dir=" + kleeOut.string ();
204
+ std::vector<std::string> argvData = { " klee" ,
205
+ entryPointFlag,
206
+ " --libc=klee" ,
207
+ " --posix-runtime" ,
208
+ " --fp-runtime" ,
209
+ " --only-output-states-covering-new" ,
210
+ " --allocate-determ" ,
211
+ " --external-calls=all" ,
212
+ " --timer-interval=1000ms" ,
213
+ " --bcov-check-interval=6s" ,
214
+ " -istats-write-interval=5s" ,
215
+ " --disable-verify" ,
216
+ " --check-div-zero=false" ,
217
+ " --check-overshift=false" ,
218
+ " --skip-not-lazy-and-symbolic-pointers" ,
219
+ outputDir };
220
+ if (settingsContext.useDeterministicSearcher ) {
221
+ argvData.emplace_back (" --search=dfs" );
220
222
}
223
+ argvData.push_back (testMethod.bitcodeFilePath );
224
+ argvData.emplace_back (" --sym-stdin" );
225
+ argvData.emplace_back (std::to_string (types::Type::symStdinSize));
221
226
222
- if (!CollectionUtils::containsKey (ktestChunk, testMethod) ||
223
- ktestChunk.at (testMethod).empty ()) {
224
- tests.commentBlocks .emplace_back (StringUtils::stringFormat (
225
- " Tests for %s were not generated. Maybe the function is too complex." ,
226
- testMethod.methodName ));
227
+ {
228
+ std::vector<char *> cargv, cenvp;
229
+ std::vector<std::string> tmp;
230
+ ExecUtils::toCArgumentsPtr (argvData, tmp, cargv, cenvp, false );
231
+ LOG_S (DEBUG) << " Klee command :: " + StringUtils::joinWith (argvData, " " );
232
+ MEASURE_FUNCTION_EXECUTION_TIME
233
+
234
+ RunKleeTask task (cargv.size (), cargv.data (), settingsContext.timeoutPerFunction );
235
+ ExecUtils::ExecutionResult result __attribute__ ((unused)) = task.run ();
236
+ ExecUtils::throwIfCancelled ();
237
+
238
+ processMethod (ktestChunk, tests, kleeOut, testMethod);
227
239
}
228
240
}
229
241
@@ -238,7 +250,7 @@ void KleeRunner::processBatchWithInteractive(const std::vector<tests::TestMethod
238
250
if (method.sourceFilePath != tests.sourceFilePath ) {
239
251
std::string message = StringUtils::stringFormat (
240
252
" While generating tests for source file: %s tried to generate tests for method %s "
241
- " from another source file: %s. This can cause invalid generation.\n " ,
253
+ " from another source file: %s. This can cause invalid generation.\n " ,
242
254
tests.sourceFilePath , method.methodName , method.sourceFilePath );
243
255
LOG_S (WARNING) << message;
244
256
}
@@ -287,86 +299,31 @@ void KleeRunner::processBatchWithInteractive(const std::vector<tests::TestMethod
287
299
argvData.push_back (testMethod.bitcodeFilePath );
288
300
argvData.emplace_back (" --sym-stdin" );
289
301
argvData.emplace_back (std::to_string (types::Type::symStdinSize));
290
- std::vector<char *> cargv, cenvp;
291
- std::vector<std::string> tmp;
292
- ExecUtils::toCArgumentsPtr (argvData, tmp, cargv, cenvp, false );
293
302
294
- LOG_S (DEBUG) << " Klee command :: " + StringUtils::joinWith (argvData, " " );
295
- MEASURE_FUNCTION_EXECUTION_TIME
296
- if (settingsContext.timeoutPerFunction .has_value ()) {
297
- RunKleeTask task (cargv.size (), cargv.data (), settingsContext.timeoutPerFunction .value () * testMethods.size ());
298
- ExecUtils::ExecutionResult result __attribute__ ((unused)) = task.run ();
299
- } else {
300
- RunKleeTask task (cargv.size (), cargv.data (), settingsContext.timeoutPerFunction );
301
- ExecUtils::ExecutionResult result __attribute__ ((unused)) = task.run ();
302
- }
303
+ {
304
+ std::vector<char *> cargv, cenvp;
305
+ std::vector<std::string> tmp;
306
+ ExecUtils::toCArgumentsPtr (argvData, tmp, cargv, cenvp, false );
303
307
304
- ExecUtils::throwIfCancelled ();
308
+ LOG_S (DEBUG) << " Klee command :: " + StringUtils::joinWith (argvData, " " );
309
+ MEASURE_FUNCTION_EXECUTION_TIME
305
310
306
- for (const auto &method : testMethods) {
307
- std::string kleeMethodName = KleeUtils::entryPointFunction (tests, method.methodName , true );
308
- fs::path newKleeOut = kleeOut / kleeMethodName;
309
- MethodKtests ktestChunk;
310
- if (fs::exists (newKleeOut)) {
311
- clearUnusedData (newKleeOut);
312
- bool hasTimeout = false ;
313
- bool hasError = false ;
314
- for (auto const &entry : fs::directory_iterator (newKleeOut)) {
315
- auto const &path = entry.path ();
316
- if (Paths::isKtestJson (path)) {
317
- if (Paths::hasEarly (path)) {
318
- hasTimeout = true ;
319
- } else if (Paths::hasInternalError (path)) {
320
- hasError = true ;
321
- } else {
322
- std::unique_ptr<TestCase, decltype (&TestCase_free)> ktestData{
323
- TC_fromFile (path.c_str ()), TestCase_free
324
- };
325
- if (ktestData == nullptr ) {
326
- LOG_S (WARNING) << " Unable to open .ktestjson file" ;
327
- continue ;
328
- }
329
- UTBotKTest::Status status = Paths::hasError (path)
330
- ? UTBotKTest::Status::FAILED
331
- : UTBotKTest::Status::SUCCESS;
332
- std::vector<ConcretizedObject> kTestObjects (
333
- ktestData->objects , ktestData->objects + ktestData->n_objects );
334
-
335
- std::vector<UTBotKTestObject> objects = CollectionUtils::transform (
336
- kTestObjects , [](const ConcretizedObject &kTestObject ) {
337
- return UTBotKTestObject{ kTestObject };
338
- });
339
-
340
- ktestChunk[method].emplace_back (objects, status);
341
- }
342
- }
343
- }
344
- if (hasTimeout) {
345
- std::string message = StringUtils::stringFormat (
346
- " Some tests for function '%s' were skipped, as execution of function is "
347
- " out of timeout." ,
348
- method.methodName );
349
- tests.commentBlocks .emplace_back (std::move (message));
350
- }
351
- if (hasError) {
352
- std::string message = StringUtils::stringFormat (
353
- " Some tests for function '%s' were skipped, as execution of function leads "
354
- " KLEE to the internal error. See console log for more details." ,
355
- method.methodName );
356
- tests.commentBlocks .emplace_back (std::move (message));
357
- }
358
- }
311
+ RunKleeTask task (cargv.size (),
312
+ cargv.data (),
313
+ settingsContext.timeoutPerFunction .has_value ()
314
+ ? settingsContext.timeoutPerFunction .value () * testMethods.size ()
315
+ : settingsContext.timeoutPerFunction );
316
+ ExecUtils::ExecutionResult result __attribute__ ((unused)) = task.run ();
359
317
360
- if (fs::exists (kleeOut)) {
361
- writeKleeStats (kleeOut);
362
- }
318
+ ExecUtils::throwIfCancelled ();
363
319
364
- if (!CollectionUtils::containsKey (ktestChunk, method) ||
365
- ktestChunk.at (method).empty ()) {
366
- tests.commentBlocks .emplace_back (StringUtils::stringFormat (
367
- " Tests for %s were not generated. Maybe the function is too complex." ,
368
- method.methodName ));
320
+ for (const auto &method : testMethods) {
321
+ std::string kleeMethodName =
322
+ KleeUtils::entryPointFunction (tests, method.methodName , true );
323
+ fs::path newKleeOut = kleeOut / kleeMethodName;
324
+ MethodKtests ktestChunk;
325
+ processMethod (ktestChunk, tests, newKleeOut, method);
326
+ ktests.push_back (ktestChunk);
369
327
}
370
- ktests.push_back (ktestChunk);
371
328
}
372
329
}
0 commit comments