1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin.surefire.booterclient.output;
20
21 import java.util.concurrent.ConcurrentHashMap;
22 import java.util.concurrent.ConcurrentMap;
23
24 import org.apache.maven.surefire.api.booter.ForkedProcessEventType;
25 import org.apache.maven.surefire.api.event.AbstractConsoleEvent;
26 import org.apache.maven.surefire.api.event.AbstractStandardStreamEvent;
27 import org.apache.maven.surefire.api.event.AbstractTestControlEvent;
28 import org.apache.maven.surefire.api.event.ConsoleErrorEvent;
29 import org.apache.maven.surefire.api.event.Event;
30 import org.apache.maven.surefire.api.event.JvmExitErrorEvent;
31 import org.apache.maven.surefire.api.event.SystemPropertyEvent;
32 import org.apache.maven.surefire.api.report.ReportEntry;
33 import org.apache.maven.surefire.api.report.RunMode;
34
35 import static java.util.Objects.requireNonNull;
36 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_BYE;
37 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_CONSOLE_DEBUG;
38 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_CONSOLE_INFO;
39 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_CONSOLE_WARNING;
40 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_NEXT_TEST;
41 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDERR;
42 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDERR_NEW_LINE;
43 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDOUT;
44 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDOUT_NEW_LINE;
45 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STOP_ON_NEXT_TEST;
46 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TESTSET_COMPLETED;
47 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TESTSET_STARTING;
48 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_ASSUMPTIONFAILURE;
49 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_ERROR;
50 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_FAILED;
51 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_SKIPPED;
52 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_STARTING;
53 import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_SUCCEEDED;
54
55
56
57
58
59
60
61 public final class ForkedProcessEventNotifier {
62 private volatile ForkedProcessPropertyEventListener propertyEventListener;
63 private volatile ForkedProcessStackTraceEventListener consoleErrorEventListener;
64 private volatile ForkedProcessExitErrorListener exitErrorEventListener;
65
66 private final ConcurrentMap<ForkedProcessEventType, ForkedProcessReportEventListener<?>> reportEventListeners =
67 new ConcurrentHashMap<>();
68
69 private final ConcurrentMap<ForkedProcessEventType, ForkedProcessStandardOutErrEventListener>
70 stdOutErrEventListeners = new ConcurrentHashMap<>();
71
72 private final ConcurrentMap<ForkedProcessEventType, ForkedProcessStringEventListener> consoleEventListeners =
73 new ConcurrentHashMap<>();
74
75 private final ConcurrentMap<ForkedProcessEventType, ForkedProcessEventListener> controlEventListeners =
76 new ConcurrentHashMap<>();
77
78 public void setSystemPropertiesListener(ForkedProcessPropertyEventListener listener) {
79 propertyEventListener = requireNonNull(listener);
80 }
81
82 public <T extends ReportEntry> void setTestSetStartingListener(ForkedProcessReportEventListener<T> listener) {
83 reportEventListeners.put(BOOTERCODE_TESTSET_STARTING, requireNonNull(listener));
84 }
85
86 public void setTestSetCompletedListener(ForkedProcessReportEventListener<?> listener) {
87 reportEventListeners.put(BOOTERCODE_TESTSET_COMPLETED, requireNonNull(listener));
88 }
89
90 public void setTestStartingListener(ForkedProcessReportEventListener<?> listener) {
91 reportEventListeners.put(BOOTERCODE_TEST_STARTING, requireNonNull(listener));
92 }
93
94 public void setTestSucceededListener(ForkedProcessReportEventListener<?> listener) {
95 reportEventListeners.put(BOOTERCODE_TEST_SUCCEEDED, requireNonNull(listener));
96 }
97
98 public void setTestFailedListener(ForkedProcessReportEventListener<?> listener) {
99 reportEventListeners.put(BOOTERCODE_TEST_FAILED, requireNonNull(listener));
100 }
101
102 public void setTestSkippedListener(ForkedProcessReportEventListener<?> listener) {
103 reportEventListeners.put(BOOTERCODE_TEST_SKIPPED, requireNonNull(listener));
104 }
105
106 public void setTestErrorListener(ForkedProcessReportEventListener<?> listener) {
107 reportEventListeners.put(BOOTERCODE_TEST_ERROR, requireNonNull(listener));
108 }
109
110 public void setTestAssumptionFailureListener(ForkedProcessReportEventListener<?> listener) {
111 reportEventListeners.put(BOOTERCODE_TEST_ASSUMPTIONFAILURE, requireNonNull(listener));
112 }
113
114 public void setStdOutListener(ForkedProcessStandardOutErrEventListener listener) {
115 stdOutErrEventListeners.put(BOOTERCODE_STDOUT, requireNonNull(listener));
116 stdOutErrEventListeners.put(BOOTERCODE_STDOUT_NEW_LINE, requireNonNull(listener));
117 }
118
119 public void setStdErrListener(ForkedProcessStandardOutErrEventListener listener) {
120 stdOutErrEventListeners.put(BOOTERCODE_STDERR, requireNonNull(listener));
121 stdOutErrEventListeners.put(BOOTERCODE_STDERR_NEW_LINE, requireNonNull(listener));
122 }
123
124 public void setConsoleInfoListener(ForkedProcessStringEventListener listener) {
125 consoleEventListeners.put(BOOTERCODE_CONSOLE_INFO, requireNonNull(listener));
126 }
127
128 public void setConsoleErrorListener(ForkedProcessStackTraceEventListener listener) {
129 consoleErrorEventListener = requireNonNull(listener);
130 }
131
132 public void setConsoleDebugListener(ForkedProcessStringEventListener listener) {
133 consoleEventListeners.put(BOOTERCODE_CONSOLE_DEBUG, requireNonNull(listener));
134 }
135
136 public void setConsoleWarningListener(ForkedProcessStringEventListener listener) {
137 consoleEventListeners.put(BOOTERCODE_CONSOLE_WARNING, requireNonNull(listener));
138 }
139
140 public void setByeListener(ForkedProcessEventListener listener) {
141 controlEventListeners.put(BOOTERCODE_BYE, requireNonNull(listener));
142 }
143
144 public void setStopOnNextTestListener(ForkedProcessEventListener listener) {
145 controlEventListeners.put(BOOTERCODE_STOP_ON_NEXT_TEST, requireNonNull(listener));
146 }
147
148 public void setAcquireNextTestListener(ForkedProcessEventListener listener) {
149 controlEventListeners.put(BOOTERCODE_NEXT_TEST, requireNonNull(listener));
150 }
151
152 public void setExitErrorEventListener(ForkedProcessExitErrorListener listener) {
153 exitErrorEventListener = requireNonNull(listener);
154 }
155
156 public void notifyEvent(Event event) {
157 ForkedProcessEventType eventType = event.getEventType();
158 if (event.isControlCategory()) {
159 ForkedProcessEventListener listener = controlEventListeners.get(eventType);
160 if (listener != null) {
161 listener.handle();
162 }
163 } else if (event.isConsoleErrorCategory()) {
164 if (consoleErrorEventListener != null) {
165 consoleErrorEventListener.handle(((ConsoleErrorEvent) event).getStackTraceWriter());
166 }
167 } else if (event.isConsoleCategory()) {
168 ForkedProcessStringEventListener listener = consoleEventListeners.get(eventType);
169 if (listener != null) {
170 listener.handle(((AbstractConsoleEvent) event).getMessage());
171 }
172 } else if (event.isStandardStreamCategory()) {
173 boolean newLine = eventType == BOOTERCODE_STDOUT_NEW_LINE || eventType == BOOTERCODE_STDERR_NEW_LINE;
174 AbstractStandardStreamEvent standardStreamEvent = (AbstractStandardStreamEvent) event;
175 ForkedProcessStandardOutErrEventListener listener = stdOutErrEventListeners.get(eventType);
176 if (listener != null) {
177 listener.handle(
178 standardStreamEvent.getMessage(),
179 newLine,
180 standardStreamEvent.getRunMode(),
181 standardStreamEvent.getTestRunId());
182 }
183 } else if (event.isSysPropCategory()) {
184 SystemPropertyEvent systemPropertyEvent = (SystemPropertyEvent) event;
185 RunMode runMode = systemPropertyEvent.getRunMode();
186 Long testRunId = systemPropertyEvent.getTestRunId();
187 String key = systemPropertyEvent.getKey();
188 String value = systemPropertyEvent.getValue();
189 if (propertyEventListener != null) {
190 propertyEventListener.handle(key, value, runMode, testRunId);
191 }
192 } else if (event.isTestCategory()) {
193 ForkedProcessReportEventListener listener = reportEventListeners.get(eventType);
194 AbstractTestControlEvent testControlEvent = (AbstractTestControlEvent) event;
195 ReportEntry reportEntry = testControlEvent.getReportEntry();
196 if (listener != null) {
197 listener.handle(reportEntry);
198 }
199 } else if (event.isJvmExitError()) {
200 JvmExitErrorEvent jvmExitErrorEvent = (JvmExitErrorEvent) event;
201 if (exitErrorEventListener != null) {
202 exitErrorEventListener.handle(jvmExitErrorEvent.getStackTraceWriter());
203 }
204 } else {
205 throw new IllegalArgumentException("Unknown event type " + eventType);
206 }
207 }
208 }