@@ -176,91 +176,90 @@ public TestResult runTests(ImTranslator translator, ImProg imProg, Optional<Func
176176
177177 WLogger .info ("Ran compiletime functions" );
178178
179+ // Use try-with-resources for automatic cleanup
180+ try (ScheduledExecutorService testScheduler = Executors .newSingleThreadScheduledExecutor ()) {
179181
180- for (ImFunction f : imProg .getFunctions ()) {
181- if (f .hasFlag (FunctionFlagEnum .IS_TEST )) {
182- Element trace = f .attrTrace ();
183-
184- if (cu .isPresent () && !Utils .elementContained (Optional .of (trace ), cu .get ())) {
185- continue ;
186- }
187- if (funcToTest .isPresent () && trace != funcToTest .get ()) {
188- continue ;
189- }
182+ for (ImFunction f : imProg .getFunctions ()) {
183+ if (f .hasFlag (FunctionFlagEnum .IS_TEST )) {
184+ Element trace = f .attrTrace ();
190185
186+ if (cu .isPresent () && !Utils .elementContained (Optional .of (trace ), cu .get ())) {
187+ continue ;
188+ }
189+ if (funcToTest .isPresent () && trace != funcToTest .get ()) {
190+ continue ;
191+ }
191192
192- String message = "Running <" + f .attrTrace ().attrNearestPackage ().tryGetNameDef ().getName () + ":"
193+ String message = "Running <" + f .attrTrace ().attrNearestPackage ().tryGetNameDef ().getName () + ":"
193194 + f .attrTrace ().attrErrorPos ().getLine () + " - " + f .getName () + ">.." ;
194- println (message );
195- WLogger .info (message );
196- try {
197- @ Nullable ILInterpreter finalInterpreter = interpreter ;
198- Callable <Void > run = () -> {
199- finalInterpreter .runVoidFunc (f , null );
200- // each test must finish it's own timers (otherwise, we would get strange results)
201- finalInterpreter .completeTimers ();
202- return null ;
203- };
204- RunnableFuture <Void > future = new FutureTask <>(run );
205- if (service != null && !service .isShutdown ()) {
206- service .shutdownNow ();
207- }
208- service = Executors .newSingleThreadScheduledExecutor ();
209- service .execute (future );
195+ println (message );
196+ WLogger .info (message );
197+
210198 try {
211- future .get (timeoutSeconds , TimeUnit .SECONDS ); // Wait 20 seconds for test to complete
212- } catch (TimeoutException ex ) {
213- future .cancel (true );
214- throw new TestTimeOutException ();
215- } catch (ExecutionException e ) {
216- throw e .getCause ();
217- }
218- service .shutdown ();
219- service .awaitTermination (10 , TimeUnit .SECONDS );
220- service = Executors .newSingleThreadScheduledExecutor ();
221- if (gui .getErrorCount () > 0 ) {
222- StringBuilder sb = new StringBuilder ();
223- for (CompileError error : gui .getErrorList ()) {
224- sb .append (error ).append ("\n " );
225- println (error .getMessage ());
199+ @ Nullable ILInterpreter finalInterpreter = interpreter ;
200+ Callable <Void > run = () -> {
201+ finalInterpreter .runVoidFunc (f , null );
202+ // each test must finish its own timers (otherwise, we would get strange results)
203+ finalInterpreter .completeTimers ();
204+ return null ;
205+ };
206+
207+ Future <Void > future = testScheduler .submit (run );
208+
209+ try {
210+ future .get (timeoutSeconds , TimeUnit .SECONDS );
211+ } catch (TimeoutException ex ) {
212+ future .cancel (true );
213+ throw new TestTimeOutException ();
214+ } catch (ExecutionException e ) {
215+ throw e .getCause ();
226216 }
227- gui .clearErrors ();
228- TestFailure failure = new TestFailure (f , interpreter .getStackFrames (), sb .toString ());
229- failTests .add (failure );
230- } else {
217+
218+ if (gui .getErrorCount () > 0 ) {
219+ StringBuilder sb = new StringBuilder ();
220+ for (CompileError error : gui .getErrorList ()) {
221+ sb .append (error ).append ("\n " );
222+ println (error .getMessage ());
223+ }
224+ gui .clearErrors ();
225+ TestFailure failure = new TestFailure (f , interpreter .getStackFrames (), sb .toString ());
226+ failTests .add (failure );
227+ } else {
228+ successTests .add (f );
229+ println ("\t OK!" );
230+ }
231+ } catch (TestSuccessException e ) {
231232 successTests .add (f );
232233 println ("\t OK!" );
234+ } catch (TestFailException e ) {
235+ TestFailure failure = new TestFailure (f , interpreter .getStackFrames (), e .getMessage ());
236+ failTests .add (failure );
237+ println ("\t FAILED assertion:" );
238+ println ("\t " + failure .getMessageWithStackFrame ());
239+ } catch (TestTimeOutException e ) {
240+ failTests .add (new TestFailure (f , interpreter .getStackFrames (), e .getMessage ()));
241+ println ("\t FAILED - TIMEOUT (This test did not complete in " + timeoutSeconds + " seconds, it might contain an endless loop)" );
242+ println (interpreter .getStackFrames ().toString ());
243+ } catch (InterpreterException e ) {
244+ TestFailure failure = new TestFailure (f , interpreter .getStackFrames (), e .getMessage ());
245+ failTests .add (failure );
246+ println ("\t " + failure .getMessageWithStackFrame ());
247+ } catch (Throwable e ) {
248+ failTests .add (new TestFailure (f , interpreter .getStackFrames (), e .toString ()));
249+ println ("\t FAILED with exception: " + e .getClass () + " " + e .getLocalizedMessage ());
250+ println (interpreter .getStackFrames ().toString ());
251+ println ("Here are some compiler internals, that might help Wurst developers to debug this issue:" );
252+ StringWriter sw = new StringWriter ();
253+ PrintWriter pw = new PrintWriter (sw );
254+ e .printStackTrace (pw );
255+ String sStackTrace = sw .toString ();
256+ println ("\t " + e .getLocalizedMessage ());
257+ println ("\t " + sStackTrace );
233258 }
234- } catch (TestSuccessException e ) {
235- successTests .add (f );
236- println ("\t OK!" );
237- } catch (TestFailException e ) {
238- TestFailure failure = new TestFailure (f , interpreter .getStackFrames (), e .getMessage ());
239- failTests .add (failure );
240- println ("\t FAILED assertion:" );
241- println ("\t " + failure .getMessageWithStackFrame ());
242- } catch (TestTimeOutException e ) {
243- failTests .add (new TestFailure (f , interpreter .getStackFrames (), e .getMessage ()));
244- println ("\t FAILED - TIMEOUT (This test did not complete in " + timeoutSeconds + " seconds, it might contain an endless loop)" );
245- println (interpreter .getStackFrames ().toString ());
246- } catch (InterpreterException e ) {
247- TestFailure failure = new TestFailure (f , interpreter .getStackFrames (), e .getMessage ());
248- failTests .add (failure );
249- println ("\t " + failure .getMessageWithStackFrame ());
250- } catch (Throwable e ) {
251- failTests .add (new TestFailure (f , interpreter .getStackFrames (), e .toString ()));
252- println ("\t FAILED with exception: " + e .getClass () + " " + e .getLocalizedMessage ());
253- println (interpreter .getStackFrames ().toString ());
254- println ("Here are some compiler internals, that might help Wurst developers to debug this issue:" );
255- StringWriter sw = new StringWriter ();
256- PrintWriter pw = new PrintWriter (sw );
257- e .printStackTrace (pw );
258- String sStackTrace = sw .toString ();
259- println ("\t " + e .getLocalizedMessage ());
260- println ("\t " + sStackTrace );
261259 }
262260 }
263- }
261+ } // Scheduler is automatically shut down here
262+
264263 println ("Tests succeeded: " + successTests .size () + "/" + (successTests .size () + failTests .size ()));
265264 if (failTests .size () == 0 ) {
266265 println (">> All tests have passed successfully!" );
0 commit comments