Skip to content

Commit 4f0e613

Browse files
committed
fix(test): remove redundant comments in MavenTest
1 parent 582ed05 commit 4f0e613

File tree

1 file changed

+117
-131
lines changed

1 file changed

+117
-131
lines changed

src/test/java/MavenTest.java

Lines changed: 117 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import java.util.concurrent.Future;
2020
import java.util.concurrent.TimeUnit;
2121
import java.util.concurrent.TimeoutException;
22-
import java.util.regex.Pattern; // Import Pattern
22+
import java.util.regex.Pattern;
2323
import java.util.stream.Collectors;
2424
import org.junit.jupiter.api.Assertions;
2525
import org.junit.jupiter.api.DynamicTest;
@@ -47,14 +47,9 @@ private static List<String> discoverProblemNames() {
4747
return Collections.emptyList();
4848
}
4949

50-
// Handle JAR paths correctly. If it's in a JAR, resource.toURI() will be "jar:file:/..."
51-
// We need to resolve the actual file system path if running from an unzipped structure,
52-
// or return an empty list if it's purely in a JAR and cannot be listed as a directory.
5350
if ("jar".equals(resource.getProtocol())) {
5451
System.err.println(
55-
"Cannot discover problems dynamically from within a JAR file. Please ensure 'src/main/java' is accessible on the file system during testing.");
56-
// In a real scenario, you might have a pre-defined list for JAR runs,
57-
// or expect tests to be run against expanded directories.
52+
"Cannot discover problems dynamically from within a JAR file. Please ensure 'src/main/java' is accessible on the file system during testing.");
5853
return Collections.emptyList();
5954
}
6055

@@ -70,14 +65,12 @@ private static List<String> discoverProblemNames() {
7065
return Collections.emptyList();
7166
}
7267

73-
// List directories within the uvaSolutionsPath that start with 'p'
7468
File uvaDir = uvaSolutionsPath.toFile();
7569
File[] problemDirs = uvaDir.listFiles(new FilenameFilter() {
7670
@Override
7771
public boolean accept(File current, String name) {
78-
// Ensure it's a directory AND matches the "p" + digits pattern
7972
return new File(current, name).isDirectory()
80-
&& PROBLEM_DIR_PATTERN.matcher(name).matches();
73+
&& PROBLEM_DIR_PATTERN.matcher(name).matches();
8174
}
8275
});
8376

@@ -87,9 +80,9 @@ public boolean accept(File current, String name) {
8780
}
8881

8982
List<String> problems = Arrays.stream(problemDirs)
90-
.map(File::getName)
91-
.sorted() // Optional: Sort for consistent order
92-
.collect(Collectors.toList());
83+
.map(File::getName)
84+
.sorted()
85+
.collect(Collectors.toList());
9386

9487
System.out.println("Discovered problems: " + problems);
9588
return problems;
@@ -100,155 +93,149 @@ public boolean accept(File current, String name) {
10093

10194
@TestFactory
10295
Collection<DynamicTest> runMavenExecTests() {
103-
// Create a fixed-size thread pool
10496
final ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS);
10597

106-
// A list to hold the Futures of each submitted task
10798
List<Future<TestResult>> futures = PROBLEMS.stream()
108-
.map(problem -> {
109-
// Create a Callable for each problem
110-
Callable<TestResult> task = () -> {
111-
Thread.currentThread().setName("Problem-Runner-" + problem); // Name thread for better logging
112-
String command = String.format("mvn exec:exec -Dproblem=%s", problem);
113-
System.out.println(Thread.currentThread().getName() + ": Executing command for " + problem
114-
+ ": " + command);
115-
116-
Process process;
117-
try {
118-
process = Runtime.getRuntime().exec(command);
119-
} catch (Exception e) {
120-
// If process execution itself fails
121-
return new TestResult(
122-
problem, false, "", "Failed to execute command: " + e.getMessage(), e);
123-
}
99+
.map(problem -> {
100+
Callable<TestResult> task = () -> {
101+
Thread.currentThread().setName("Problem-Runner-" + problem);
102+
String command = String.format("mvn exec:exec -Dproblem=%s", problem);
103+
System.out.println(Thread.currentThread().getName() + ": Executing command for " + problem
104+
+ ": " + command);
105+
106+
Process process;
107+
try {
108+
process = Runtime.getRuntime().exec(command);
109+
} catch (Exception e) {
110+
return new TestResult(
111+
problem, false, "", "Failed to execute command: " + e.getMessage(), e);
112+
}
113+
114+
StringBuilder output = new StringBuilder();
115+
StringBuilder errorOutput = new StringBuilder();
124116

125-
StringBuilder output = new StringBuilder();
126-
StringBuilder errorOutput = new StringBuilder();
127-
128-
// Use separate threads to consume streams to prevent deadlock
129-
Thread outputGobbler = new Thread(() -> {
130-
try (BufferedReader reader =
131-
new BufferedReader(new InputStreamReader(process.getInputStream()))) {
132-
String line;
133-
while ((line = reader.readLine()) != null) {
134-
output.append(line).append("\n");
135-
}
136-
} catch (Exception e) {
137-
System.err.println(Thread.currentThread().getName() + ": Error reading output for "
138-
+ problem + ": " + e.getMessage());
117+
Thread outputGobbler = new Thread(() -> {
118+
try (BufferedReader reader =
119+
new BufferedReader(new InputStreamReader(process.getInputStream()))) {
120+
String line;
121+
while ((line = reader.readLine()) != null) {
122+
output.append(line).append("\n");
139123
}
140-
});
141-
142-
Thread errorGobbler = new Thread(() -> {
143-
try (BufferedReader errorReader =
144-
new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
145-
String line;
146-
while ((line = errorReader.readLine()) != null) {
147-
errorOutput.append(line).append("\n");
148-
}
149-
} catch (Exception e) {
150-
System.err.println(Thread.currentThread().getName()
151-
+ ": Error reading error output for " + problem + ": " + e.getMessage());
124+
} catch (Exception e) {
125+
System.err.println(Thread.currentThread().getName() + ": Error reading output for "
126+
+ problem + ": " + e.getMessage());
127+
}
128+
});
129+
130+
Thread errorGobbler = new Thread(() -> {
131+
try (BufferedReader errorReader =
132+
new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
133+
String line;
134+
while ((line = errorReader.readLine()) != null) {
135+
errorOutput.append(line).append("\n");
152136
}
153-
});
154-
155-
outputGobbler.start();
156-
errorGobbler.start();
157-
158-
int exitCode;
159-
try {
160-
exitCode = process.waitFor();
161-
outputGobbler.join(); // Ensure all output is consumed
162-
errorGobbler.join(); // Ensure all error output is consumed
163-
} catch (InterruptedException e) {
164-
process.destroyForcibly(); // Ensure subprocess is terminated if interrupted
165-
outputGobbler.join(100); // Give gobblers a moment, but don't hang
166-
errorGobbler.join(100);
167-
Thread.currentThread().interrupt(); // Restore interrupted status
168-
return new TestResult(
169-
problem, false, output.toString(), "Test interrupted (likely timed out)", e);
170137
} catch (Exception e) {
171-
return new TestResult(
172-
problem,
173-
false,
174-
output.toString(),
175-
"Error waiting for process: " + e.getMessage(),
176-
e);
138+
System.err.println(Thread.currentThread().getName()
139+
+ ": Error reading error output for " + problem + ": " + e.getMessage());
177140
}
141+
});
178142

179-
boolean success = (exitCode == 0);
180-
return new TestResult(problem, success, output.toString(), errorOutput.toString(), null);
181-
};
182-
return executor.submit(task); // Submit the task to the executor
183-
})
184-
.collect(Collectors.toList());
143+
outputGobbler.start();
144+
errorGobbler.start();
185145

186-
// Create DynamicTests to check the results of the submitted tasks
187-
Collection<DynamicTest> dynamicTests = futures.stream()
188-
.map(future -> DynamicTest.dynamicTest("Test problem: " + future.toString(), () -> {
189-
TestResult result = null;
146+
boolean completed;
190147
try {
191-
// Wait for each task to complete with the defined timeout
192-
result = future.get(TEST_TIMEOUT.toSeconds(), TimeUnit.SECONDS);
148+
completed = process.waitFor(TEST_TIMEOUT.toSeconds(), TimeUnit.SECONDS);
149+
outputGobbler.join(100);
150+
errorGobbler.join(100);
151+
} catch (InterruptedException e) {
152+
process.destroyForcibly();
153+
outputGobbler.join(100);
154+
errorGobbler.join(100);
155+
Thread.currentThread().interrupt();
156+
return new TestResult(
157+
problem, false, output.toString(), "Test interrupted", e);
158+
}
193159

194-
System.out.println("Test " + result.problemName + " completed. Output:\n" + result.output);
195-
if (!result.errorOutput.isEmpty()) {
196-
System.err.println("Test " + result.problemName + " error output:\n" + result.errorOutput);
160+
if (!completed) {
161+
process.destroy();
162+
if (process.isAlive()) {
163+
process.destroyForcibly();
197164
}
165+
outputGobbler.join(100);
166+
errorGobbler.join(100);
167+
return new TestResult(
168+
problem, false, output.toString(), "Process timed out after " + TEST_TIMEOUT.toSeconds() + " seconds", null);
169+
}
198170

199-
Assertions.assertTrue(
200-
result.success,
201-
"Maven command failed for problem: " + result.problemName + "\nError output:\n"
202-
+ result.errorOutput);
203-
204-
} catch (TimeoutException e) {
205-
// This handles the case where the Callable itself exceeds the timeout
206-
future.cancel(true); // Attempt to interrupt the running task
207-
Assertions.fail(
208-
"Test for problem " + (result != null ? result.problemName : "unknown")
209-
+ " timed out after " + TEST_TIMEOUT.toSeconds() + " seconds.",
210-
e);
211-
} catch (InterruptedException e) {
212-
Thread.currentThread().interrupt(); // Restore interrupt status
213-
Assertions.fail(
214-
"Test for problem " + (result != null ? result.problemName : "unknown")
215-
+ " was interrupted.",
216-
e);
217-
} catch (ExecutionException e) {
218-
// The actual exception thrown by the Callable is wrapped here
219-
Throwable cause = e.getCause();
220-
Assertions.fail(
221-
"An error occurred during execution for problem "
222-
+ (result != null ? result.problemName : "unknown") + ": " + cause.getMessage(),
223-
cause);
171+
int exitCode;
172+
try {
173+
exitCode = process.exitValue();
174+
} catch (IllegalThreadStateException e) {
175+
process.destroyForcibly();
176+
return new TestResult(
177+
problem, false, output.toString(), "Process did not terminate properly", e);
224178
}
225-
}))
226-
.collect(Collectors.toList());
227179

228-
// Crucial: Shut down the executor after all tests have been processed
180+
boolean success = (exitCode == 0);
181+
return new TestResult(problem, success, output.toString(), errorOutput.toString(), null);
182+
};
183+
return executor.submit(task);
184+
})
185+
.collect(Collectors.toList());
186+
187+
Collection<DynamicTest> dynamicTests = futures.stream()
188+
.map(future -> DynamicTest.dynamicTest("Test problem: " + future.toString(), () -> {
189+
TestResult result = null;
190+
try {
191+
result = future.get();
192+
193+
System.out.println("Test " + result.problemName + " completed. Output:\n" + result.output);
194+
if (!result.errorOutput.isEmpty()) {
195+
System.err.println("Test " + result.problemName + " error output:\n" + result.errorOutput);
196+
}
197+
198+
Assertions.assertTrue(
199+
result.success,
200+
"Maven command failed for problem: " + result.problemName + "\nError output:\n"
201+
+ result.errorOutput);
202+
203+
} catch (InterruptedException e) {
204+
Thread.currentThread().interrupt();
205+
Assertions.fail(
206+
"Test for problem " + (result != null ? result.problemName : "unknown")
207+
+ " was interrupted.",
208+
e);
209+
} catch (ExecutionException e) {
210+
Throwable cause = e.getCause();
211+
Assertions.fail(
212+
"An error occurred during execution for problem "
213+
+ (result != null ? result.problemName : "unknown") + ": " + cause.getMessage(),
214+
cause);
215+
}
216+
}))
217+
.collect(Collectors.toList());
218+
229219
executor.shutdown();
230220
try {
231-
// Wait for existing tasks to terminate
232221
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
233-
executor.shutdownNow(); // Forcefully terminate if not done in time
222+
executor.shutdownNow();
234223
}
235224
} catch (InterruptedException e) {
236225
executor.shutdownNow();
237-
Thread.currentThread().interrupt(); // Restore interrupt status
226+
Thread.currentThread().interrupt();
238227
}
239228

240229
return dynamicTests;
241230
}
242231

243-
// A simple record/class to encapsulate test results
244232
private static class TestResult {
245233
String problemName;
246234
boolean success;
247235
String output;
248236
String errorOutput;
249-
Throwable exception; // To store any exception from the callable
237+
Throwable exception;
250238

251-
// Primary constructor
252239
public TestResult(String problemName, boolean success, String output, String errorOutput, Throwable exception) {
253240
this.problemName = problemName;
254241
this.success = success;
@@ -259,8 +246,7 @@ public TestResult(String problemName, boolean success, String output, String err
259246

260247
@Override
261248
public String toString() {
262-
// Used by DynamicTest.dynamicTest() to name the test
263249
return problemName;
264250
}
265251
}
266-
}
252+
}

0 commit comments

Comments
 (0)