Skip to content

Commit e73b889

Browse files
author
BaierD
committed
Add more timeout/shutdown tests:
- test context interrupt with subsequent prover usage - test prover interrupt with subsequent feature usage (ignored because unfinished)
1 parent b048f56 commit e73b889

File tree

1 file changed

+172
-9
lines changed

1 file changed

+172
-9
lines changed

src/org/sosy_lab/java_smt/test/TimeoutTest.java

Lines changed: 172 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@
1111
import static com.google.common.truth.Truth.assertThat;
1212
import static com.google.common.truth.TruthJUnit.assume;
1313
import static org.junit.Assert.assertThrows;
14+
import static org.sosy_lab.java_smt.SolverContextFactory.Solvers.BOOLECTOR;
1415

16+
import com.google.common.collect.ImmutableList;
1517
import java.util.ArrayList;
1618
import java.util.List;
1719
import java.util.Random;
1820
import java.util.function.Supplier;
1921
import org.junit.Before;
22+
import org.junit.Ignore;
2023
import org.junit.Test;
2124
import org.junit.runner.RunWith;
2225
import org.junit.runners.Parameterized;
@@ -25,6 +28,7 @@
2528
import org.sosy_lab.java_smt.SolverContextFactory.Solvers;
2629
import org.sosy_lab.java_smt.api.BasicProverEnvironment;
2730
import org.sosy_lab.java_smt.api.BooleanFormula;
31+
import org.sosy_lab.java_smt.api.SolverContext.ProverOptions;
2832
import org.sosy_lab.java_smt.api.SolverException;
2933
import org.sosy_lab.java_smt.api.Tactic;
3034
import org.sosy_lab.java_smt.solvers.opensmt.Logics;
@@ -140,21 +144,14 @@ public void testProverInterruptWithSubsequentNewProverUsageInt()
140144
public void testContextInterruptWithSubsequentNewProverUsageBv()
141145
throws InterruptedException, SolverException {
142146
requireBitvectors();
143-
requireIsolatedProverShutdown();
144147

145148
testBasicContextTimeoutBv(() -> context.newProverEnvironment());
146149
assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue();
147150

148151
HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr);
149152
try (BasicProverEnvironment<?> pe = context.newProverEnvironment()) {
150-
pe.push(gen.generate(8));
153+
assertThrows(InterruptedException.class, () -> pe.push(gen.generate(8)));
151154
assertThrows(InterruptedException.class, pe::isUnsat);
152-
153-
} catch (InterruptedException expected) {
154-
// We don't really know where an exception is coming from currently.
155-
// TODO: define where and how exceptions are thrown if we build a new prover but shutdown
156-
// has been requested.
157-
assertThat(expected).isNotNull();
158155
}
159156
}
160157

@@ -163,7 +160,6 @@ public void testContextInterruptWithSubsequentNewProverUsageBv()
163160
public void testContextInterruptWithSubsequentNewProverUsageInt()
164161
throws InterruptedException, SolverException {
165162
requireIntegers();
166-
requireIsolatedProverShutdown();
167163

168164
testBasicContextTimeoutInt(() -> context.newProverEnvironment());
169165
assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue();
@@ -181,6 +177,122 @@ public void testContextInterruptWithSubsequentNewProverUsageInt()
181177
}
182178
}
183179

180+
// Test shutdown of context-wide shutdown manager. No prover should be usable afterward!
181+
// This test re-uses provers that already existed before the shutdown.
182+
@Test(timeout = TIMEOUT_MILLISECONDS)
183+
public void testContextInterruptWithSubsequentProverUsageBv() throws InterruptedException {
184+
requireBitvectors();
185+
assume()
186+
.withMessage("Boolector does not support multiple provers")
187+
.that(solverToUse())
188+
.isNotEqualTo(BOOLECTOR);
189+
190+
HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr);
191+
try (BasicProverEnvironment<?> pe1 = context.newProverEnvironment()) {
192+
try (BasicProverEnvironment<?> pe2 = context.newProverEnvironment()) {
193+
pe2.push(gen.generate(8));
194+
195+
testBasicContextTimeoutBv(() -> context.newProverEnvironment());
196+
assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue();
197+
try {
198+
assertThat(pe1.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue();
199+
assertThat(pe2.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue();
200+
} catch (UnsupportedOperationException mayBeThrown) {
201+
// Do nothing, we can't check for solvers that don't support this
202+
}
203+
204+
assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8)));
205+
assertThrows(InterruptedException.class, pe2::isUnsat);
206+
}
207+
}
208+
}
209+
210+
// Test shutdown of context-wide shutdown manager. No prover should be usable afterward!
211+
// This test re-uses provers that already existed before the shutdown.
212+
@Test(timeout = TIMEOUT_MILLISECONDS)
213+
public void testContextInterruptWithSubsequentProverUsageInt() throws InterruptedException {
214+
requireIntegers();
215+
216+
HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr);
217+
try (BasicProverEnvironment<?> pe1 = context.newProverEnvironment()) {
218+
try (BasicProverEnvironment<?> pe2 = context.newProverEnvironment()) {
219+
pe2.push(gen.generate(8));
220+
221+
testBasicContextTimeoutInt(() -> context.newProverEnvironment());
222+
assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue();
223+
try {
224+
assertThat(pe1.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue();
225+
assertThat(pe2.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue();
226+
} catch (UnsupportedOperationException mayBeThrown) {
227+
// Do nothing, we can't check for solvers that don't support this
228+
}
229+
230+
assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8)));
231+
assertThrows(InterruptedException.class, pe2::isUnsat);
232+
}
233+
}
234+
}
235+
236+
// Test shutdown of prover and subsequent feature usage.
237+
@Ignore
238+
@Test(timeout = TIMEOUT_MILLISECONDS)
239+
public void testProverInterruptWithSubsequentFeatureUsageBv() throws InterruptedException {
240+
requireBitvectors();
241+
requireIsolatedProverShutdown();
242+
243+
HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr);
244+
try (BasicProverEnvironment<?> pe1 = context.newProverEnvironment()) {
245+
try (BasicProverEnvironment<?> pe2 = context.newProverEnvironment()) {
246+
pe2.push(gen.generate(8));
247+
248+
testBasicProverTimeoutWithFeatureUsageBv(() -> context.newProverEnvironment());
249+
assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue();
250+
try {
251+
assertThat(pe1.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue();
252+
assertThat(pe2.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue();
253+
} catch (UnsupportedOperationException mayBeThrown) {
254+
// Do nothing, we can't check for solvers that don't support this
255+
}
256+
257+
assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8)));
258+
assertThrows(InterruptedException.class, pe2::isUnsat);
259+
}
260+
}
261+
}
262+
263+
// Test shutdown of prover and subsequent feature usage.
264+
@Ignore
265+
@Test(timeout = TIMEOUT_MILLISECONDS)
266+
public void testContextInterruptWithSubsequentFeatureUsageInt() throws InterruptedException {
267+
requireIntegers();
268+
requireIsolatedProverShutdown();
269+
270+
HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr);
271+
try (BasicProverEnvironment<?> pe1 = context.newProverEnvironment()) {
272+
try (BasicProverEnvironment<?> pe2 = context.newProverEnvironment()) {
273+
pe2.push(gen.generate(8));
274+
275+
testBasicProverTimeoutWithFeatureUsageInt(
276+
() ->
277+
context.newProverEnvironment(
278+
ProverOptions.GENERATE_UNSAT_CORE,
279+
ProverOptions.GENERATE_MODELS,
280+
ProverOptions.GENERATE_ALL_SAT,
281+
ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS));
282+
assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue();
283+
try {
284+
assertThat(pe1.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue();
285+
assertThat(pe2.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue();
286+
} catch (UnsupportedOperationException mayBeThrown) {
287+
// Do nothing, we can't check for solvers that don't support this
288+
}
289+
290+
assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8)));
291+
assertThrows(InterruptedException.class, pe2::isUnsat);
292+
}
293+
}
294+
}
295+
184296
@Test(timeout = TIMEOUT_MILLISECONDS)
185297
public void testInterpolationProverTimeout() throws InterruptedException {
186298
requireInterpolation();
@@ -227,6 +339,26 @@ private void testBasicProverTimeoutBv(Supplier<BasicProverEnvironment<?>> prover
227339
testBasicProverBasedTimeout(proverConstructor, gen.generate(200));
228340
}
229341

342+
/**
343+
* Shuts down the shutdown manager of the prover. Throws an exception for non-supporting solvers.
344+
* Will try to use all available features of the solver afterward. (Model, UnsatCore etc.)
345+
*/
346+
private void testBasicProverTimeoutWithFeatureUsageInt(
347+
Supplier<BasicProverEnvironment<?>> proverConstructor) throws InterruptedException {
348+
HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr);
349+
testProverBasedTimeoutWithFeatures(proverConstructor, gen.generate(200));
350+
}
351+
352+
/**
353+
* Shuts down the shutdown manager of the prover. Throws an exception for non-supporting solvers.
354+
* Will try to use all available features of the solver afterward. (Model, UnsatCore etc.)
355+
*/
356+
private void testBasicProverTimeoutWithFeatureUsageBv(
357+
Supplier<BasicProverEnvironment<?>> proverConstructor) throws InterruptedException {
358+
HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr);
359+
testProverBasedTimeoutWithFeatures(proverConstructor, gen.generate(200));
360+
}
361+
230362
@SuppressWarnings("CheckReturnValue")
231363
private void testBasicContextBasedTimeout(
232364
Supplier<BasicProverEnvironment<?>> proverConstructor, BooleanFormula instance)
@@ -269,4 +401,35 @@ private void testBasicProverBasedTimeout(
269401
assertThrows(InterruptedException.class, pe::isUnsat);
270402
}
271403
}
404+
405+
private void testProverBasedTimeoutWithFeatures(
406+
Supplier<BasicProverEnvironment<?>> proverConstructor, BooleanFormula instance)
407+
throws InterruptedException {
408+
409+
// TODO: maybe add a test that solves something correctly before interrupting?
410+
411+
try (BasicProverEnvironment<?> pe = proverConstructor.get()) {
412+
Thread t =
413+
new Thread(
414+
() -> {
415+
try {
416+
Thread.sleep(delay);
417+
pe.getShutdownManagerForProver().requestShutdown("Shutdown Request");
418+
} catch (InterruptedException exception) {
419+
throw new UnsupportedOperationException("Unexpected interrupt", exception);
420+
}
421+
});
422+
pe.push(instance);
423+
t.start();
424+
assertThrows(InterruptedException.class, pe::isUnsat);
425+
assertThrows(InterruptedException.class, pe::getModel);
426+
assertThrows(InterruptedException.class, pe::getUnsatCore);
427+
assertThrows(
428+
InterruptedException.class, () -> pe.isUnsatWithAssumptions(ImmutableList.of(instance)));
429+
assertThrows(InterruptedException.class, () -> pe.addConstraint(instance));
430+
assertThrows(InterruptedException.class, () -> pe.push(instance));
431+
assertThrows(InterruptedException.class, pe::push);
432+
assertThrows(InterruptedException.class, pe::pop);
433+
}
434+
}
272435
}

0 commit comments

Comments
 (0)