|
12 | 12 | import java.util.Collection;
|
13 | 13 | import java.util.Collections;
|
14 | 14 | import java.util.List;
|
15 |
| -import java.util.concurrent.Callable; |
16 |
| -import java.util.concurrent.ExecutionException; |
17 |
| -import java.util.concurrent.ExecutorService; |
18 |
| -import java.util.concurrent.Executors; |
19 |
| -import java.util.concurrent.Future; |
20 | 15 | import java.util.concurrent.TimeUnit;
|
21 | 16 | import java.util.regex.Pattern;
|
22 | 17 | import java.util.stream.Collectors;
|
|
26 | 21 |
|
27 | 22 | public class MavenTest {
|
28 | 23 |
|
29 |
| - // Define the number of threads for the ExecutorService |
30 |
| - private static final int MAX_THREADS = 10; |
31 | 24 | // Define the timeout for each test
|
32 | 25 | private static final Duration TEST_TIMEOUT = Duration.ofSeconds(30);
|
33 | 26 |
|
@@ -107,143 +100,80 @@ public boolean accept(File current, String name) {
|
107 | 100 |
|
108 | 101 | @TestFactory
|
109 | 102 | Collection<DynamicTest> runMavenExecTests() {
|
110 |
| - final ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS); |
| 103 | + return PROBLEMS.stream() |
| 104 | + .map(problem -> DynamicTest.dynamicTest("Test problem: " + problem, () -> { |
| 105 | + String command = String.format("mvn exec:exec -Dproblem=%s", problem); |
| 106 | + System.out.println("Executing command for " + problem + ": " + command); |
111 | 107 |
|
112 |
| - List<Future<TestResult>> futures = PROBLEMS.stream() |
113 |
| - .map(problem -> { |
114 |
| - Callable<TestResult> task = () -> { |
115 |
| - Thread.currentThread().setName("Problem-Runner-" + problem); |
116 |
| - String command = String.format("mvn exec:exec -Dproblem=%s", problem); |
117 |
| - System.out.println(Thread.currentThread().getName() + ": Executing command for " + problem |
118 |
| - + ": " + command); |
119 |
| - |
120 |
| - Process process; |
121 |
| - try { |
122 |
| - process = Runtime.getRuntime().exec(command); |
123 |
| - } catch (Exception e) { |
124 |
| - return new TestResult( |
125 |
| - problem, false, "", "Failed to execute command: " + e.getMessage(), e); |
126 |
| - } |
127 |
| - |
128 |
| - StringBuilder output = new StringBuilder(); |
129 |
| - StringBuilder errorOutput = new StringBuilder(); |
130 |
| - |
131 |
| - Thread outputGobbler = new Thread(() -> { |
132 |
| - try (BufferedReader reader = |
133 |
| - new BufferedReader(new InputStreamReader(process.getInputStream()))) { |
134 |
| - String line; |
135 |
| - while ((line = reader.readLine()) != null) { |
136 |
| - output.append(line).append("\n"); |
137 |
| - } |
138 |
| - } catch (Exception e) { |
139 |
| - System.err.println(Thread.currentThread().getName() + ": Error reading output for " |
140 |
| - + problem + ": " + e.getMessage()); |
141 |
| - } |
142 |
| - }); |
143 |
| - |
144 |
| - Thread errorGobbler = new Thread(() -> { |
145 |
| - try (BufferedReader errorReader = |
146 |
| - new BufferedReader(new InputStreamReader(process.getErrorStream()))) { |
147 |
| - String line; |
148 |
| - while ((line = errorReader.readLine()) != null) { |
149 |
| - errorOutput.append(line).append("\n"); |
150 |
| - } |
151 |
| - } catch (Exception e) { |
152 |
| - System.err.println(Thread.currentThread().getName() |
153 |
| - + ": Error reading error output for " + problem + ": " + e.getMessage()); |
154 |
| - } |
155 |
| - }); |
| 108 | + Process process; |
| 109 | + try { |
| 110 | + process = Runtime.getRuntime().exec(command); |
| 111 | + } catch (Exception e) { |
| 112 | + Assertions.fail("Failed to execute command for " + problem + ": " + e.getMessage(), e); |
| 113 | + return; |
| 114 | + } |
156 | 115 |
|
157 |
| - outputGobbler.start(); |
158 |
| - errorGobbler.start(); |
| 116 | + StringBuilder output = new StringBuilder(); |
| 117 | + StringBuilder errorOutput = new StringBuilder(); |
159 | 118 |
|
160 |
| - boolean completed; |
161 |
| - try { |
162 |
| - completed = process.waitFor(TEST_TIMEOUT.toSeconds(), TimeUnit.SECONDS); |
163 |
| - outputGobbler.join(100); |
164 |
| - errorGobbler.join(100); |
165 |
| - } catch (InterruptedException e) { |
166 |
| - process.destroyForcibly(); |
167 |
| - outputGobbler.join(100); |
168 |
| - errorGobbler.join(100); |
169 |
| - Thread.currentThread().interrupt(); |
170 |
| - return new TestResult(problem, false, output.toString(), "Test interrupted", e); |
171 |
| - } |
172 |
| - |
173 |
| - if (!completed) { |
174 |
| - process.destroy(); |
175 |
| - if (process.isAlive()) { |
176 |
| - process.destroyForcibly(); |
177 |
| - } |
178 |
| - outputGobbler.join(100); |
179 |
| - errorGobbler.join(100); |
180 |
| - return new TestResult( |
181 |
| - problem, |
182 |
| - false, |
183 |
| - output.toString(), |
184 |
| - "Process timed out after " + TEST_TIMEOUT.toSeconds() + " seconds", |
185 |
| - null); |
| 119 | + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { |
| 120 | + String line; |
| 121 | + while ((line = reader.readLine()) != null) { |
| 122 | + output.append(line).append("\n"); |
186 | 123 | }
|
| 124 | + } catch (Exception e) { |
| 125 | + System.err.println("Error reading output for " + problem + ": " + e.getMessage()); |
| 126 | + } |
187 | 127 |
|
188 |
| - int exitCode; |
189 |
| - try { |
190 |
| - exitCode = process.exitValue(); |
191 |
| - } catch (IllegalThreadStateException e) { |
192 |
| - process.destroyForcibly(); |
193 |
| - return new TestResult( |
194 |
| - problem, false, output.toString(), "Process did not terminate properly", e); |
| 128 | + try (BufferedReader errorReader = |
| 129 | + new BufferedReader(new InputStreamReader(process.getErrorStream()))) { |
| 130 | + String line; |
| 131 | + while ((line = errorReader.readLine()) != null) { |
| 132 | + errorOutput.append(line).append("\n"); |
195 | 133 | }
|
| 134 | + } catch (Exception e) { |
| 135 | + System.err.println("Error reading error output for " + problem + ": " + e.getMessage()); |
| 136 | + } |
196 | 137 |
|
197 |
| - boolean success = (exitCode == 0); |
198 |
| - return new TestResult(problem, success, output.toString(), errorOutput.toString(), null); |
199 |
| - }; |
200 |
| - return executor.submit(task); |
201 |
| - }) |
202 |
| - .collect(Collectors.toList()); |
203 |
| - |
204 |
| - Collection<DynamicTest> dynamicTests = futures.stream() |
205 |
| - .map(future -> DynamicTest.dynamicTest("Test problem: " + future.toString(), () -> { |
206 |
| - TestResult result = null; |
| 138 | + boolean completed; |
207 | 139 | try {
|
208 |
| - result = future.get(); |
| 140 | + completed = process.waitFor(TEST_TIMEOUT.toSeconds(), TimeUnit.SECONDS); |
| 141 | + } catch (InterruptedException e) { |
| 142 | + process.destroyForcibly(); |
| 143 | + Thread.currentThread().interrupt(); |
| 144 | + Assertions.fail("Test for problem " + problem + " was interrupted.", e); |
| 145 | + return; |
| 146 | + } |
209 | 147 |
|
210 |
| - System.out.println("Test " + result.problemName + " completed. Output:\n" + result.output); |
211 |
| - if (!result.errorOutput.isEmpty()) { |
212 |
| - System.err.println("Test " + result.problemName + " error output:\n" + result.errorOutput); |
| 148 | + if (!completed) { |
| 149 | + process.destroy(); |
| 150 | + if (process.isAlive()) { |
| 151 | + process.destroyForcibly(); |
213 | 152 | }
|
| 153 | + Assertions.fail( |
| 154 | + "Process timed out for " + problem + " after " + TEST_TIMEOUT.toSeconds() + " seconds"); |
| 155 | + return; |
| 156 | + } |
214 | 157 |
|
215 |
| - Assertions.assertTrue( |
216 |
| - result.success, |
217 |
| - "Maven command failed for problem: " + result.problemName + "\nError output:\n" |
218 |
| - + result.errorOutput); |
| 158 | + int exitCode; |
| 159 | + try { |
| 160 | + exitCode = process.exitValue(); |
| 161 | + } catch (IllegalThreadStateException e) { |
| 162 | + process.destroyForcibly(); |
| 163 | + Assertions.fail("Process did not terminate properly for " + problem, e); |
| 164 | + return; |
| 165 | + } |
219 | 166 |
|
220 |
| - } catch (InterruptedException e) { |
221 |
| - Thread.currentThread().interrupt(); |
222 |
| - Assertions.fail( |
223 |
| - "Test for problem " + (result != null ? result.problemName : "unknown") |
224 |
| - + " was interrupted.", |
225 |
| - e); |
226 |
| - } catch (ExecutionException e) { |
227 |
| - Throwable cause = e.getCause(); |
228 |
| - Assertions.fail( |
229 |
| - "An error occurred during execution for problem " |
230 |
| - + (result != null ? result.problemName : "unknown") + ": " + cause.getMessage(), |
231 |
| - cause); |
| 167 | + System.out.println("Test " + problem + " completed. Output:\n" + output); |
| 168 | + if (!errorOutput.isEmpty()) { |
| 169 | + System.err.println("Test " + problem + " error output:\n" + errorOutput); |
232 | 170 | }
|
| 171 | + |
| 172 | + Assertions.assertTrue( |
| 173 | + exitCode == 0, |
| 174 | + "Maven command failed for problem: " + problem + "\nError output:\n" + errorOutput); |
233 | 175 | }))
|
234 | 176 | .collect(Collectors.toList());
|
235 |
| - |
236 |
| - executor.shutdown(); |
237 |
| - try { |
238 |
| - if (!executor.awaitTermination(60, TimeUnit.SECONDS)) { |
239 |
| - executor.shutdownNow(); |
240 |
| - } |
241 |
| - } catch (InterruptedException e) { |
242 |
| - executor.shutdownNow(); |
243 |
| - Thread.currentThread().interrupt(); |
244 |
| - } |
245 |
| - |
246 |
| - return dynamicTests; |
247 | 177 | }
|
248 | 178 |
|
249 | 179 | private static class TestResult {
|
|
0 commit comments