Skip to content

Commit 2872d1b

Browse files
committed
Bound thread stress test in CI
1 parent 196526a commit 2872d1b

1 file changed

Lines changed: 38 additions & 34 deletions

File tree

src/test/java/com/sri/yices/TestThreads.java

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@
55

66
import static org.junit.Assume.assumeTrue;
77

8+
import java.util.concurrent.CountDownLatch;
9+
import java.util.concurrent.TimeUnit;
10+
import java.util.concurrent.atomic.AtomicReference;
11+
812
public class TestThreads {
913

10-
public static final int THREAD_COUNT = 200;
14+
public static final int THREAD_COUNT = Integer.getInteger("com.sri.yices.testThreads.count", 32);
15+
public static final long THREAD_TIMEOUT_SECONDS = Long.getLong("com.sri.yices.testThreads.timeoutSeconds", 60L);
1116

1217
public static final String COUNTER_PREFIX = "c@";
1318
public static final String CHOICE_PREFIX = "i@";
1419

15-
private static final Object lock = new Object();
16-
private static int waiting = 0;
17-
1820
@Test
1921
public void testVersion() {
2022
assumeTrue(TestAssumptions.IS_YICES_INSTALLED);
@@ -43,16 +45,9 @@ private int makeConstraint(int index, int increment, int selector){
4345
return Terms.and(selector, Terms.eq(t1, Terms.add(t2, Terms.intConst(increment))));
4446
}
4547

46-
private void threadMain(int index, Status[] answers){
47-
48-
synchronized(lock){
49-
waiting++;
50-
try {
51-
lock.wait();
52-
} catch(InterruptedException e){
53-
System.err.println(e.getMessage());
54-
}
55-
}
48+
private void threadMain(int index, Status[] answers, CountDownLatch readyGate, CountDownLatch startGate) throws InterruptedException {
49+
readyGate.countDown();
50+
Assert.assertTrue("timed out waiting to start worker threads", startGate.await(THREAD_TIMEOUT_SECONDS, TimeUnit.SECONDS));
5651

5752
try (Config cfg = new Config()) {
5853
cfg.set("solver-type", "dpllt");
@@ -82,54 +77,63 @@ private void threadMain(int index, Status[] answers){
8277
}
8378
}
8479

85-
private Thread makeThread(final int index, final Status[] answers){
80+
private Thread makeThread(final int index, final Status[] answers, final CountDownLatch readyGate,
81+
final CountDownLatch startGate, final AtomicReference<Throwable> failure){
8682
Runnable runnable = new Runnable(){
8783
public void run(){
88-
threadMain(index, answers);
84+
try {
85+
threadMain(index, answers, readyGate, startGate);
86+
} catch (Throwable error) {
87+
failure.compareAndSet(null, error);
88+
}
8989
}
9090
};
91-
return new Thread(runnable);
91+
Thread thread = new Thread(runnable, "yices-test-thread-" + index);
92+
thread.setDaemon(true);
93+
return thread;
9294
}
9395

9496

95-
@Test
97+
@Test(timeout = 120000)
9698
public void testThreads() {
9799
assumeTrue(TestAssumptions.IS_YICES_INSTALLED);
98100
assumeTrue(Yices.isThreadSafe());
99101

100102
Thread[] threads = new Thread[THREAD_COUNT];
101103
Status[] answers = new Status[THREAD_COUNT];
104+
CountDownLatch readyGate = new CountDownLatch(THREAD_COUNT);
105+
CountDownLatch startGate = new CountDownLatch(1);
106+
AtomicReference<Throwable> failure = new AtomicReference<Throwable>();
102107

103108
for(int i = 0; i < THREAD_COUNT; i++){
104-
threads[i] = makeThread(i, answers);
109+
threads[i] = makeThread(i, answers, readyGate, startGate, failure);
105110
}
106111

107112
for(int i = 0; i < THREAD_COUNT; i++){
108113
threads[i].start();
109114
}
110115

111-
Thread self = Thread.currentThread();
112-
113-
while(true){
114-
synchronized(lock){
115-
if (waiting == THREAD_COUNT){
116-
lock.notifyAll();
117-
break;
118-
}
119-
}
120-
}
121-
122-
123116
try {
117+
Assert.assertTrue("timed out waiting for worker threads to become ready",
118+
readyGate.await(THREAD_TIMEOUT_SECONDS, TimeUnit.SECONDS));
119+
startGate.countDown();
124120
for(int i = 0; i < THREAD_COUNT; i++){
125-
threads[i].join();
121+
threads[i].join(TimeUnit.SECONDS.toMillis(THREAD_TIMEOUT_SECONDS));
122+
Assert.assertFalse("worker thread did not finish: " + threads[i].getName(), threads[i].isAlive());
126123
}
127124
} catch (InterruptedException error){
128-
System.out.println(error.getMessage());
125+
Thread.currentThread().interrupt();
126+
Assert.fail(error.getMessage());
127+
}
128+
129+
if (failure.get() != null) {
130+
AssertionError error = new AssertionError("worker thread failed");
131+
error.initCause(failure.get());
132+
throw error;
129133
}
130134

131135
for (int i = 0; i < THREAD_COUNT; i++){
132-
Assert.assertEquals(answers[i], Status.SAT);
136+
Assert.assertEquals(Status.SAT, answers[i]);
133137
}
134138

135139

0 commit comments

Comments
 (0)