|
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