-
Notifications
You must be signed in to change notification settings - Fork 82
Expand file tree
/
Copy pathBreakTest.java
More file actions
117 lines (104 loc) · 4.75 KB
/
BreakTest.java
File metadata and controls
117 lines (104 loc) · 4.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package org.rascalmpl.compiler;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import org.rascalmpl.debug.IRascalMonitor;
import org.rascalmpl.shell.RascalShell;
import org.rascalmpl.shell.ShellEvaluatorFactory;
import org.rascalmpl.test.infrastructure.RascalJUnitTestRunner;
import org.rascalmpl.uri.URIResolverRegistry;
import io.usethesource.vallang.ISourceLocation;
public class BreakTest {
private static final String BREAKING_MODULE = "lang::rascalcore::check::tests::ChangeScenarioTests";
private static final String BREAKING_TEST = "fixedErrorsDisappear2";
private static final int PARALLEL_RUNS = 8; // set to 1 to avoid any multi-threading interactions, but it might take 20 rounds or something
private static final int TRIES = 1000 / PARALLEL_RUNS;
public static void main(String[] args) throws IOException, InterruptedException {
RascalShell.setupJavaProcessForREPL();
var term = RascalShell.connectToTerminal();
var monitor = IRascalMonitor.buildConsoleMonitor(term);
var error = monitor instanceof PrintWriter ? (PrintWriter) monitor : new PrintWriter(System.err, false);
try {
AtomicBoolean failed = new AtomicBoolean(false);
AtomicInteger done = new AtomicInteger(0);
for (int t = 0; t < PARALLEL_RUNS; t++) {
var name = "Thread " + (t + 1);
var tr = new Thread(() -> {
try {
if (crashTest(monitor, error, name, failed)) {
failed.set(true);
System.err.println("We got a failure, exiting now!");
Thread.sleep(1000);
System.exit(1);
}
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
done.incrementAndGet();
}
});
tr.start();
}
while (done.get() < PARALLEL_RUNS && !failed.get()) {
Thread.sleep(100);
}
} finally {
error.close();
}
}
static boolean crashTest(IRascalMonitor monitor, PrintWriter errorPrinter, String name, AtomicBoolean failed) {
var output = new StringWriter();
var iFailed = new AtomicBoolean(false);
try (var err = new PrintWriter(output, true); var out= new PrintWriter(output, false)) {
var projectRoot = RascalJUnitTestRunner.inferProjectRootFromClass(BreakTest.class);
var evaluator = ShellEvaluatorFactory.getDefaultEvaluatorForLocation(projectRoot, Reader.nullReader(), err, out, monitor, "$test-"+name+"$");
evaluator.getConfiguration().setErrors(true);
// make sure we're writing to the outputs
evaluator.overwritePrintWriter(out, err);
evaluator.doImport(monitor, BREAKING_MODULE);
try {
monitor.job(name, TRIES, (jobname, step) -> {
try {
for (int i = 0; i < TRIES; i++) {
if (failed.get()) {
return false;
}
monitor.jobStep(jobname, "Running: try " + (i + 1));
evaluator.call(BREAKING_TEST);
}
} catch (Throwable e ) {
failed.set(true);
iFailed.set(true);
err.println("❌ test fail ");
err.println(e);
}
return null;
});
} finally {
// clean up memory
var memoryModule = evaluator.getHeap().getModule("lang::rascalcore::check::TestShared");
var testRoot = memoryModule.getFrameVariable("testRoot");
try {
URIResolverRegistry.getInstance().remove((ISourceLocation)testRoot.getValue(), true);
}
catch (Throwable e) {
err.println("Failure to cleanup the cache");
}
}
}
if (iFailed.get()) {
errorPrinter.println("❌❌❌ Test run failed: " + name);
errorPrinter.println("Job output:");
errorPrinter.println(output.toString());
return true;
}
return false;
}
}