Skip to content

Commit ab27cab

Browse files
committed
Fixed review issues
1 parent e5ac4c4 commit ab27cab

File tree

13 files changed

+51
-80
lines changed

13 files changed

+51
-80
lines changed

utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/visible/UtStreamConsumingException.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package org.utbot.framework.plugin.api.visible
33
/**
44
* An artificial exception that stores an exception that would be thrown in case of consuming stream by invoking terminal operations.
55
* [innerException] stores this possible exception (null if [UtStreamConsumingException] was constructed by the engine).
6+
*
7+
* NOTE: this class should be visible in almost all parts of the tool - Soot, engine, concrete execution and code generation,
8+
* that's the reason why this class is placed in this module and this package is called `visible`.
69
*/
710
data class UtStreamConsumingException(private val innerException: Exception?) : RuntimeException() {
811
/**

utbot-framework-test/src/test/kotlin/org/utbot/examples/threads/ExecutorServiceExamplesTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import org.utbot.testing.ignoreExecutionsNumber
88
import org.utbot.testing.isException
99

1010
// IMPORTANT: most of the these tests test only the symbolic engine
11-
// and should not be used for testing conrete or code generation since they are possibly flaky in the real execution
11+
// and should not be used for testing conrete or code generation since they are possibly flaky in the concrete execution
12+
// (see https://github.com/UnitTestBot/UTBotJava/issues/1610)
1213
class ExecutorServiceExamplesTest : UtValueTestCaseChecker(testClass = ExecutorServiceExamples::class) {
1314
@Test
1415
fun testExceptionInExecute() {

utbot-framework-test/src/test/kotlin/org/utbot/examples/threads/FutureExamplesTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import org.utbot.testing.isException
99
import java.util.concurrent.ExecutionException
1010

1111
// IMPORTANT: most of the these tests test only the symbolic engine
12-
// and should not be used for testing conrete or code generation since they are possibly flaky in the real execution
12+
// and should not be used for testing conrete or code generation since they are possibly flaky in the concrete execution
13+
// (see https://github.com/UnitTestBot/UTBotJava/issues/1610)
1314
class FutureExamplesTest : UtValueTestCaseChecker(testClass = FutureExamples::class) {
1415
@Test
1516
fun testThrowingRunnable() {

utbot-framework-test/src/test/kotlin/org/utbot/examples/threads/ThreadExamplesTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import org.utbot.testing.ignoreExecutionsNumber
88
import org.utbot.testing.isException
99

1010
// IMPORTANT: most of the these tests test only the symbolic engine
11-
// and should not be used for testing conrete or code generation since they are possibly flaky in the real execution
11+
// and should not be used for testing conrete or code generation since they are possibly flaky in the concrete execution
12+
// (see https://github.com/UnitTestBot/UTBotJava/issues/1610)
1213
class ThreadExamplesTest : UtValueTestCaseChecker(testClass = ThreadExamples::class) {
1314
@Test
1415
fun testExceptionInStart() {

utbot-framework/src/main/java/org/utbot/engine/overrides/threads/UtCompletableFuture.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import java.util.concurrent.Delayed;
88
import java.util.concurrent.ExecutionException;
99
import java.util.concurrent.Executor;
10-
import java.util.concurrent.Future;
1110
import java.util.concurrent.ScheduledFuture;
1211
import java.util.concurrent.TimeUnit;
1312
import java.util.concurrent.TimeoutException;
@@ -17,31 +16,23 @@
1716
import java.util.function.Function;
1817

1918
import static java.util.concurrent.TimeUnit.NANOSECONDS;
20-
import static org.utbot.engine.overrides.UtOverrideMock.alreadyVisited;
21-
import static org.utbot.engine.overrides.UtOverrideMock.visit;
2219

23-
public class UtCompletableFuture<T> implements Future<T>, ScheduledFuture<T>, CompletionStage<T> {
20+
public class UtCompletableFuture<T> implements ScheduledFuture<T>, CompletionStage<T> {
2421
T result;
2522

2623
Throwable exception;
2724

2825
public UtCompletableFuture(T result) {
29-
visit(this);
3026
this.result = result;
3127
}
3228

33-
public UtCompletableFuture() {
34-
visit(this);
35-
}
29+
public UtCompletableFuture() {}
3630

3731
public UtCompletableFuture(Throwable exception) {
38-
visit(this);
3932
this.exception = exception;
4033
}
4134

4235
public UtCompletableFuture(UtCompletableFuture<T> future) {
43-
visit(this);
44-
4536
result = future.result;
4637
exception = future.exception;
4738
}
@@ -51,12 +42,7 @@ public void eqGenericType(T ignoredValue) {
5142
}
5243

5344
public void preconditionCheck() {
54-
if (alreadyVisited(this)) {
55-
return;
56-
}
5745
eqGenericType(result);
58-
59-
visit(this);
6046
}
6147

6248
@Override

utbot-framework/src/main/java/org/utbot/engine/overrides/threads/UtExecutorService.java

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,60 +7,36 @@
77
import java.util.List;
88
import java.util.concurrent.Callable;
99
import java.util.concurrent.ExecutionException;
10-
import java.util.concurrent.ExecutorService;
1110
import java.util.concurrent.Future;
1211
import java.util.concurrent.ScheduledExecutorService;
1312
import java.util.concurrent.ScheduledFuture;
1413
import java.util.concurrent.TimeUnit;
1514

16-
import static org.utbot.engine.overrides.UtOverrideMock.alreadyVisited;
17-
import static org.utbot.engine.overrides.UtOverrideMock.visit;
18-
19-
public class UtExecutorService implements ExecutorService, ScheduledExecutorService {
15+
public class UtExecutorService implements ScheduledExecutorService {
2016
private boolean isShutdown;
2117
private boolean isTerminated;
2218

23-
public UtExecutorService() {
24-
visit(this);
25-
}
26-
27-
private void preconditionCheck() {
28-
if (alreadyVisited(this)) {
29-
return;
30-
}
31-
32-
visit(this);
33-
}
34-
3519
@Override
3620
public void shutdown() {
37-
preconditionCheck();
38-
3921
isShutdown = true;
4022
isTerminated = true;
4123
}
4224

4325
@NotNull
4426
@Override
4527
public List<Runnable> shutdownNow() {
46-
preconditionCheck();
47-
4828
shutdown();
4929
// Since all tasks are processed immediately, there are no waiting tasks
5030
return new ArrayList<>();
5131
}
5232

5333
@Override
5434
public boolean isShutdown() {
55-
preconditionCheck();
56-
5735
return isShutdown;
5836
}
5937

6038
@Override
6139
public boolean isTerminated() {
62-
preconditionCheck();
63-
6440
return isTerminated;
6541
}
6642

@@ -73,8 +49,6 @@ public boolean awaitTermination(long timeout, @NotNull TimeUnit unit) {
7349
@NotNull
7450
@Override
7551
public <T> Future<T> submit(@NotNull Callable<T> task) {
76-
preconditionCheck();
77-
7852
try {
7953
T result = task.call();
8054
return new UtCompletableFuture<>(result);
@@ -86,8 +60,6 @@ public <T> Future<T> submit(@NotNull Callable<T> task) {
8660
@NotNull
8761
@Override
8862
public <T> Future<T> submit(@NotNull Runnable task, T result) {
89-
preconditionCheck();
90-
9163
try {
9264
task.run();
9365
return new UtCompletableFuture<>(result);
@@ -105,8 +77,6 @@ public Future<?> submit(@NotNull Runnable task) {
10577
@NotNull
10678
@Override
10779
public <T> List<Future<T>> invokeAll(@NotNull Collection<? extends Callable<T>> tasks) {
108-
preconditionCheck();
109-
11080
List<Future<T>> results = new ArrayList<>();
11181
for (Callable<T> task : tasks) {
11282
results.add(submit(task));
@@ -124,8 +94,6 @@ public <T> List<Future<T>> invokeAll(@NotNull Collection<? extends Callable<T>>
12494
@NotNull
12595
@Override
12696
public <T> T invokeAny(@NotNull Collection<? extends Callable<T>> tasks) throws ExecutionException {
127-
preconditionCheck();
128-
12997
for (Callable<T> task : tasks) {
13098
try {
13199
return task.call();
@@ -145,16 +113,12 @@ public <T> T invokeAny(@NotNull Collection<? extends Callable<T>> tasks, long ti
145113

146114
@Override
147115
public void execute(@NotNull Runnable command) {
148-
preconditionCheck();
149-
150116
command.run();
151117
}
152118

153119
@NotNull
154120
@Override
155121
public ScheduledFuture<?> schedule(@NotNull Runnable command, long delay, @NotNull TimeUnit unit) {
156-
preconditionCheck();
157-
158122
try {
159123
command.run();
160124
return new UtCompletableFuture<>();
@@ -166,8 +130,6 @@ public ScheduledFuture<?> schedule(@NotNull Runnable command, long delay, @NotNu
166130
@NotNull
167131
@Override
168132
public <V> ScheduledFuture<V> schedule(@NotNull Callable<V> callable, long delay, @NotNull TimeUnit unit) {
169-
preconditionCheck();
170-
171133
try {
172134
V result = callable.call();
173135
return new UtCompletableFuture<>(result);
@@ -179,8 +141,6 @@ public <V> ScheduledFuture<V> schedule(@NotNull Callable<V> callable, long delay
179141
@NotNull
180142
@Override
181143
public ScheduledFuture<?> scheduleAtFixedRate(@NotNull Runnable command, long initialDelay, long period, @NotNull TimeUnit unit) {
182-
preconditionCheck();
183-
184144
if (period <= 0) {
185145
throw new IllegalArgumentException();
186146
}
@@ -191,8 +151,6 @@ public ScheduledFuture<?> scheduleAtFixedRate(@NotNull Runnable command, long in
191151
@NotNull
192152
@Override
193153
public ScheduledFuture<?> scheduleWithFixedDelay(@NotNull Runnable command, long initialDelay, long delay, @NotNull TimeUnit unit) {
194-
preconditionCheck();
195-
196154
if (delay <= 0) {
197155
throw new IllegalArgumentException();
198156
}

utbot-framework/src/main/java/org/utbot/engine/overrides/threads/UtThreadGroup.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public final void setMaxPriority(int pri) {
101101
return;
102102
}
103103

104-
for (int i = 0 ; i < ngroups ; i++) {
104+
for (int i = 0; i < ngroups; i++) {
105105
groups[i].setMaxPriority(pri);
106106
}
107107
}
@@ -199,11 +199,11 @@ public final void stop() {
199199
public final void interrupt() {
200200
preconditionCheck();
201201

202-
for (int i = 0 ; i < nthreads ; i++) {
202+
for (int i = 0; i < nthreads; i++) {
203203
threads[i].interrupt();
204204
}
205205

206-
for (int i = 0 ; i < ngroups ; i++) {
206+
for (int i = 0; i < ngroups; i++) {
207207
groups[i].interrupt();
208208
}
209209
}
@@ -232,12 +232,12 @@ public final void destroy() {
232232
nthreads = 0;
233233
threads = null;
234234
}
235-
for (int i = 0 ; i < ngroups ; i += 1) {
235+
for (int i = 0; i < ngroups; i += 1) {
236236
groups[i].destroy();
237237
}
238238
}
239239

240-
private void add(ThreadGroup g){
240+
private void add(ThreadGroup g) {
241241
preconditionCheck();
242242

243243
if (destroyed) {
@@ -261,7 +261,7 @@ private void remove(ThreadGroup g) {
261261
return;
262262
}
263263

264-
for (int i = 0 ; i < ngroups ; i++) {
264+
for (int i = 0; i < ngroups; i++) {
265265
if (groups[i] == g) {
266266
ngroups -= 1;
267267
System.arraycopy(groups, i + 1, groups, i, ngroups - i);

utbot-framework/src/main/kotlin/org/utbot/engine/Hierarchy.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ class Hierarchy(private val typeRegistry: TypeRegistry) {
3333
val realFieldDeclaringType = typeRegistry.findRealType(field.declaringClass.type) as RefType
3434

3535
// java.lang.Thread class has package-private fields, that can be used outside the class.
36-
// Since wrapper UtThread does not inherit java.lang.Thread, we cannot use this inheritance condition only
37-
val realTypeHasFieldByName = realType.sootClass.getFieldByNameUnsafe(field.name) != null
36+
// Since wrapper UtThread does not inherit java.lang.Thread, we cannot use this inheritance condition only.
37+
// The possible presence of hidden field is not important here - we just need
38+
// to know whether we have at least one such field.
39+
val realTypeHasFieldByName = realType.sootClass.getFieldUnsafe(field.subSignature) != null
3840
val realTypeIsInheritor = realFieldDeclaringType.sootClass in ancestors(realType.sootClass.id)
3941

4042
if (!realTypeIsInheritor && !realTypeHasFieldByName) {

utbot-framework/src/main/kotlin/org/utbot/engine/Memory.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ import soot.Type
6565
*
6666
* Note: [staticInitial] contains mapping from [FieldId] to the memory state at the moment of the field initialization.
6767
*
68-
* [fieldValues] stores symbolic values for specified fields of the specified object instances.
68+
* [fieldValues] stores symbolic values for specified fields of the concrete object instances.
69+
* We need to associate field of a concrete instance with the created symbolic value to not lose an information about its type.
70+
* For example, if field's declared type is Runnable but at the current state it is a specific lambda,
71+
* we have to save this lambda as a type of this field to be able to retrieve it in the future.
6972
*
7073
* @see memoryForNestedMethod
7174
* @see FieldStates

utbot-framework/src/main/kotlin/org/utbot/engine/ObjectWrappers.kt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,17 @@ val classToWrapper: MutableMap<TypeToBeWrapped, WrapperType> =
7575
putSootClass(java.lang.Thread::class, utThreadClass)
7676
putSootClass(java.lang.ThreadGroup::class, utThreadGroupClass)
7777

78+
// executors, futures and latches
79+
putSootClass(ExecutorService::class, utExecutorServiceClass)
80+
putSootClass(ThreadPoolExecutor::class, utExecutorServiceClass)
81+
putSootClass(ForkJoinPool::class, utExecutorServiceClass)
82+
putSootClass(ScheduledThreadPoolExecutor::class, utExecutorServiceClass)
83+
putSootClass(CountDownLatch::class, utCountDownLatchClass)
84+
putSootClass(CompletableFuture::class, utCompletableFutureClass)
85+
putSootClass(CompletionStage::class, utCompletableFutureClass)
86+
// A hack to be able to create UtCompletableFuture in its methods as a wrapper
87+
putSootClass(UtCompletableFuture::class, utCompletableFutureClass)
88+
7889
putSootClass(RangeModifiableUnlimitedArray::class, RangeModifiableUnlimitedArrayWrapper::class)
7990
putSootClass(AssociativeArray::class, AssociativeArrayWrapper::class)
8091

@@ -228,9 +239,13 @@ private val wrappers = mapOf(
228239
wrap(SecurityManager::class) { type, addr -> objectValue(type, addr, SecurityManagerWrapper()) },
229240
).also {
230241
// check every `wrapped` class has a corresponding value in [classToWrapper]
231-
it.keys.all { key ->
242+
val missedWrappers = it.keys.filterNot { key ->
232243
Scene.v().getSootClass(key.name).type in classToWrapper.keys
233244
}
245+
246+
require(missedWrappers.isEmpty()) {
247+
"Missed wrappers for classes [${missedWrappers.joinToString(", ")}]"
248+
}
234249
}
235250

236251
private fun wrap(kClass: KClass<*>, implementation: (RefType, UtAddrExpression) -> ObjectValue) =

0 commit comments

Comments
 (0)