Skip to content

Commit ba0bbbb

Browse files
committed
Fix process handling
1 parent 8676e14 commit ba0bbbb

File tree

5 files changed

+464
-503
lines changed

5 files changed

+464
-503
lines changed

org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenBuildConnectionProcess.java

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919
import java.util.Map;
2020
import java.util.concurrent.ConcurrentHashMap;
2121
import java.util.concurrent.CopyOnWriteArrayList;
22+
import java.util.concurrent.atomic.AtomicBoolean;
2223

23-
import org.eclipse.core.runtime.Status;
24-
import org.eclipse.debug.core.DebugException;
24+
import org.eclipse.debug.core.DebugEvent;
25+
import org.eclipse.debug.core.DebugPlugin;
2526
import org.eclipse.debug.core.ILaunch;
2627
import org.eclipse.debug.core.model.IProcess;
2728
import org.eclipse.debug.core.model.IStreamsProxy;
@@ -49,32 +50,41 @@ public class MavenBuildConnectionProcess implements IProcess {
4950

5051
private List<MavenBuildListener> buildListeners = new CopyOnWriteArrayList<>();
5152

53+
private AtomicBoolean terminated = new AtomicBoolean();
54+
5255
public MavenBuildConnectionProcess(ILaunch launch) {
5356
this.launch = launch;
5457
launch.addProcess(this);
5558
attributes.put(IProcess.ATTR_PROCESS_TYPE, "m2e-build-endpoint");
59+
fireEvent(new DebugEvent(this, DebugEvent.CREATE));
5660
}
5761

5862
public <T> T getAdapter(Class<T> adapter) {
5963
return null;
6064
}
6165

6266
public boolean canTerminate() {
63-
return true;
67+
return !isTerminated();
6468
}
6569

6670
public boolean isTerminated() {
67-
return connection == null || connection.isReadCompleted();
71+
return terminated.get() || connection == null;
6872
}
6973

70-
public void terminate() throws DebugException {
71-
if(connection != null) {
72-
try {
73-
connection.close();
74-
} catch(IOException ex) {
75-
throw new DebugException(Status.error("Terminate failed", ex));
74+
public void terminate() {
75+
if(terminated.compareAndSet(false, true)) {
76+
if(connection != null) {
77+
try {
78+
connection.close();
79+
} catch(IOException ex) {
80+
}
81+
connection = null;
82+
}
83+
for(MavenBuildListener mavenBuildListener : buildListeners) {
84+
mavenBuildListener.close();
7685
}
77-
connection = null;
86+
buildListeners.clear();
87+
fireEvent(new DebugEvent(this, DebugEvent.TERMINATE));
7888
}
7989
}
8090

@@ -93,6 +103,7 @@ public IStreamsProxy getStreamsProxy() {
93103
@Override
94104
public void setAttribute(String key, String value) {
95105
attributes.put(key, value);
106+
fireEvent(new DebugEvent(this, DebugEvent.CHANGE));
96107
}
97108

98109
@Override
@@ -144,11 +155,7 @@ public void onTestEvent(MavenTestEvent mavenTestEvent) {
144155
}
145156

146157
public void close() {
147-
for(MavenBuildListener mavenBuildListener : buildListeners) {
148-
mavenBuildListener.close();
149-
}
150-
buildListeners.clear();
151-
launch.removeProcess(MavenBuildConnectionProcess.this);
158+
MavenBuildConnectionProcess.this.terminate();
152159
}
153160
});
154161
}
@@ -157,4 +164,11 @@ String getMavenVMArguments() throws IOException {
157164
return connection.getMavenVMArguments();
158165
}
159166

167+
private void fireEvent(DebugEvent event) {
168+
DebugPlugin manager = DebugPlugin.getDefault();
169+
if(manager != null) {
170+
manager.fireDebugEventSet(new DebugEvent[] {event});
171+
}
172+
}
173+
160174
}

org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenBuildProjectDataConnection.java

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.util.Optional;
2020

2121
import org.eclipse.core.runtime.CoreException;
22-
import org.eclipse.debug.core.DebugException;
2322
import org.eclipse.debug.core.DebugPlugin;
2423
import org.eclipse.debug.core.ILaunch;
2524
import org.eclipse.debug.core.ILaunchesListener2;
@@ -36,35 +35,32 @@ public class MavenBuildProjectDataConnection {
3635
static {
3736
DebugPlugin.getDefault().getLaunchManager().addLaunchListener(new ILaunchesListener2() {
3837
public void launchesRemoved(ILaunch[] launches) {
39-
Arrays.stream(launches).flatMap(launch -> getConnection(launch).stream()).forEach(con -> {
40-
try {
41-
con.terminate();
42-
} catch(DebugException ex) {
43-
//ignore
44-
}
45-
});
38+
cleanupConnections(launches);
4639
}
4740

4841
public void launchesTerminated(ILaunch[] launches) {
49-
launchesRemoved(launches);
42+
cleanupConnections(launches);
5043
}
5144

5245
public void launchesAdded(ILaunch[] launches) { // ignore
5346
}
5447

5548
public void launchesChanged(ILaunch[] launches) { // ignore
5649
}
50+
51+
private void cleanupConnections(ILaunch[] launches) {
52+
Arrays.stream(launches).flatMap(launch -> getConnection(launch).stream()).forEach(con -> {
53+
con.terminate();
54+
});
55+
}
5756
});
5857
}
5958

6059
static void openListenerConnection(ILaunch launch, VMArguments arguments) {
6160
try {
6261
if(MavenLaunchUtils.getMavenRuntime(launch.getLaunchConfiguration()) instanceof MavenEmbeddedRuntime) {
6362
getConnection(launch).ifPresent(existing -> {
64-
try {
65-
existing.terminate();
66-
} catch(DebugException ex) {
67-
}
63+
existing.terminate();
6864
throw new IllegalStateException(
6965
"Maven bridge already created for launch of" + launch.getLaunchConfiguration().getName());
7066
});

org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/testing/MavenTestRunnerClient.java

Lines changed: 29 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,14 @@
2727
import org.xml.sax.SAXException;
2828

2929
import org.eclipse.debug.core.ILaunch;
30-
import org.eclipse.unittest.internal.junitXmlReport.TestRunHandler;
3130
import org.eclipse.unittest.launcher.ITestRunnerClient;
32-
import org.eclipse.unittest.model.ITestCaseElement;
33-
import org.eclipse.unittest.model.ITestElement;
34-
import org.eclipse.unittest.model.ITestElement.FailureTrace;
35-
import org.eclipse.unittest.model.ITestElement.Result;
3631
import org.eclipse.unittest.model.ITestRunSession;
3732
import org.eclipse.unittest.model.ITestSuiteElement;
3833

3934
import org.apache.maven.execution.ExecutionEvent.Type;
4035

4136
import org.eclipse.m2e.internal.launch.MavenBuildProjectDataConnection;
37+
import org.eclipse.m2e.internal.launch.testing.copied.TestRunHandler;
4238
import org.eclipse.m2e.internal.maven.listener.MavenBuildListener;
4339
import org.eclipse.m2e.internal.maven.listener.MavenProjectBuildData;
4440
import org.eclipse.m2e.internal.maven.listener.MavenTestEvent;
@@ -63,6 +59,7 @@ public MavenTestRunnerClient(ITestRunSession session) {
6359
}
6460

6561
public void startMonitoring() {
62+
System.out.println("---- start monitoring ---");
6663
MavenBuildProjectDataConnection.getConnection(session.getLaunch())
6764
.ifPresent(con -> con.addMavenBuildListener(this));
6865

@@ -78,6 +75,7 @@ public void stopTest() {
7875
}
7976

8077
public void stopMonitoring() {
78+
System.out.println("---- stop Monitoring ----\r\n");
8179
MavenBuildProjectDataConnection.getConnection(session.getLaunch())
8280
.ifPresent(con -> con.removeMavenBuildListener(this));
8381
}
@@ -93,74 +91,58 @@ public void projectStarted(MavenProjectBuildData data) {
9391
this.projectData.set(data);
9492
}
9593

94+
boolean started;
95+
9696
public void onTestEvent(MavenTestEvent mavenTestEvent) {
97+
System.out.println("MavenTestRunnerClient.onTestEvent()");
9798
if(mavenTestEvent.getType() == Type.MojoSucceeded || mavenTestEvent.getType() == Type.MojoFailed) {
99+
MavenProjectBuildData buildData = projectData.get();
100+
// Display.getDefault().execute(() -> {
101+
98102
//in any case look for the tests...
99103
Path reportDirectory = mavenTestEvent.getReportDirectory();
100104
if(Files.isDirectory(reportDirectory)) {
101105
SAXParser parser = getParser();
102106
if(parser == null) {
103107
return;
104108
}
109+
ensureStarted();
110+
ITestSuiteElement projectSuite = getProjectSuite(buildData);
105111
try (Stream<Path> list = Files.list(reportDirectory)) {
106112
Iterator<Path> iterator = list.iterator();
107113
while(iterator.hasNext()) {
108114
Path path = iterator.next();
109115
System.out.println("Scan result file " + path);
110-
ITestRunSession importedSession = parseFile(path, parser);
111-
if(importedSession != null) {
112-
ITestSuiteElement project = getProjectSuite();
113-
ITestSuiteElement file = session.newTestSuite(path.toString(), path.getFileName().toString(), null,
114-
project, path.getFileName().toString(), null);
115-
for(ITestElement element : importedSession.getChildren()) {
116-
importTestElement(element, file);
117-
}
118-
}
116+
parseFile(path, parser, projectSuite);
119117
}
120118
} catch(IOException ex) {
121119
}
122120
}
121+
// });
123122
}
124123
}
125124

126-
/**
127-
* @param element
128-
* @param file
129-
*/
130-
private void importTestElement(ITestElement element, ITestSuiteElement parent) {
131-
if(element instanceof ITestCaseElement testcase) {
132-
ITestCaseElement importedTestCase = session.newTestCase(parent.getId() + "." + testcase.getId(),
133-
testcase.getTestName(), parent, testcase.getDisplayName(), testcase.getData());
134-
session.notifyTestStarted(importedTestCase);
135-
FailureTrace failureTrace = testcase.getFailureTrace();
136-
if(failureTrace == null) {
137-
session.notifyTestEnded(importedTestCase, testcase.isIgnored());
138-
} else {
139-
session.notifyTestFailed(importedTestCase, Result.ERROR/*TODO how do we know?*/, false /*TODO how do we know?*/,
140-
failureTrace);
141-
}
142-
} else if(element instanceof ITestSuiteElement suite) {
143-
ITestSuiteElement importedTestSuite = session.newTestSuite(parent.getId() + "." + suite.getId(),
144-
suite.getTestName(), null, parent, suite.getDisplayName(), suite.getData());
145-
session.notifyTestStarted(importedTestSuite);
146-
for(ITestElement child : suite.getChildren()) {
147-
importTestElement(child, importedTestSuite);
148-
}
149-
session.notifyTestEnded(importedTestSuite, false);
125+
private synchronized void ensureStarted() {
126+
if(!started) {
127+
session.notifyTestSessionStarted(null);
128+
started = true;
150129
}
151130
}
152131

153132
/**
154133
* @return
155134
*/
156-
private ITestSuiteElement getProjectSuite() {
157-
return projectElementMap.computeIfAbsent(projectData.get(), data -> {
135+
private ITestSuiteElement getProjectSuite(MavenProjectBuildData buildData) {
136+
return projectElementMap.computeIfAbsent(buildData, data -> {
158137
Path basedir = data.projectBasedir;
159-
return session.newTestSuite(basedir.toString(), basedir.getFileName().toString(), null, null,
160-
data.groupId + ":" + data.artifactId, null);
138+
ITestSuiteElement suite = session.newTestSuite(System.currentTimeMillis() + basedir.toString(),
139+
basedir.getFileName().toString(), null, null, data.groupId + ":" + data.artifactId, null);
140+
session.notifyTestStarted(suite);
141+
return suite;
161142
});
162143
}
163144

145+
@SuppressWarnings("restriction")
164146
private SAXParser getParser() {
165147
try {
166148
return org.eclipse.core.internal.runtime.XmlProcessorFactory.createSAXParserWithErrorOnDOCTYPE();
@@ -170,20 +152,19 @@ private SAXParser getParser() {
170152
return null;
171153
}
172154

173-
private ITestRunSession parseFile(Path path, SAXParser parser) {
174-
//TODO Currently NOT working as this is internal API that is not exported!
175-
final TestRunHandler handler = new TestRunHandler();
155+
private void parseFile(Path path, SAXParser parser, ITestSuiteElement parent) {
156+
final TestRunHandler handler = new TestRunHandler(session, parent);
176157
try {
177158
parser.parse(Files.newInputStream(path), handler);
178-
return handler.getTestRunSession();
179159
} catch(SAXException | IOException ex) {
180160
//can't read then...
181-
return null;
182161
}
183162
}
184163

185164
public void close() {
186-
// nothing to do yet...
165+
if(started) {
166+
session.notifyTestSessionCompleted(null);
167+
}
187168
}
188169

189170
}

0 commit comments

Comments
 (0)