1 package org.apache.maven.plugin.surefire.booterclient.output;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedReader;
23 import java.io.IOException;
24 import java.io.StringReader;
25 import java.io.StringWriter;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.Map;
29 import java.util.Properties;
30 import java.util.StringTokenizer;
31 import org.apache.maven.surefire.booter.ForkingRunListener;
32 import org.apache.maven.surefire.report.CategorizedReportEntry;
33 import org.apache.maven.surefire.report.ConsoleOutputReceiver;
34 import org.apache.maven.surefire.report.ConsoleLogger;
35 import org.apache.maven.surefire.report.ReportEntry;
36 import org.apache.maven.surefire.report.ReporterException;
37 import org.apache.maven.surefire.report.ReporterFactory;
38 import org.apache.maven.surefire.report.RunListener;
39 import org.apache.maven.surefire.report.SimpleReportEntry;
40 import org.apache.maven.surefire.report.StackTraceWriter;
41 import org.apache.maven.surefire.util.NestedRuntimeException;
42 import org.apache.maven.surefire.util.internal.StringUtils;
43 import org.codehaus.plexus.util.cli.StreamConsumer;
44
45
46
47
48
49
50 public class ForkClient
51 implements StreamConsumer
52 {
53 private final ReporterFactory providerReporterFactory;
54
55 private final Map testSetReporters = Collections.synchronizedMap( new HashMap() );
56
57 private final Properties testVmSystemProperties;
58
59 public ForkClient( ReporterFactory providerReporterFactory, Properties testVmSystemProperties )
60 {
61 this.providerReporterFactory = providerReporterFactory;
62 this.testVmSystemProperties = testVmSystemProperties;
63 }
64
65 public void consumeLine( String s )
66 {
67 try
68 {
69 if ( s.length() == 0 )
70 {
71 return;
72 }
73 final byte operationId = (byte) s.charAt( 0 );
74 int commma = s.indexOf( ",", 3 );
75 if ( commma < 0 )
76 {
77 System.out.println( s );
78 return;
79 }
80 final Integer channelNumber = new Integer( Integer.parseInt( s.substring( 2, commma ), 16 ) );
81 RunListener reporter = (RunListener) testSetReporters.get( channelNumber );
82 if ( reporter == null )
83 {
84 reporter = providerReporterFactory.createReporter();
85
86 testSetReporters.put( channelNumber, reporter );
87 }
88 int rest = s.indexOf( ",", commma );
89 final String remaining = s.substring( rest + 1 );
90
91 switch ( operationId )
92 {
93 case ForkingRunListener.BOOTERCODE_TESTSET_STARTING:
94 reporter.testSetStarting( createReportEntry( remaining ) );
95 break;
96 case ForkingRunListener.BOOTERCODE_TESTSET_COMPLETED:
97 reporter.testSetCompleted( createReportEntry( remaining ) );
98 break;
99 case ForkingRunListener.BOOTERCODE_TEST_STARTING:
100 reporter.testStarting( createReportEntry( remaining) );
101 break;
102 case ForkingRunListener.BOOTERCODE_TEST_SUCCEEDED:
103 reporter.testSucceeded( createReportEntry( remaining ) );
104 break;
105 case ForkingRunListener.BOOTERCODE_TEST_FAILED:
106 reporter.testFailed( createReportEntry( remaining ) );
107 break;
108 case ForkingRunListener.BOOTERCODE_TEST_SKIPPED:
109 reporter.testSkipped( createReportEntry( remaining ) );
110 break;
111 case ForkingRunListener.BOOTERCODE_TEST_ERROR:
112 reporter.testError( createReportEntry( remaining ) );
113 break;
114 case ForkingRunListener.BOOTERCODE_TEST_ASSUMPTIONFAILURE:
115 reporter.testAssumptionFailure( createReportEntry( remaining ) );
116 break;
117 case ForkingRunListener.BOOTERCODE_SYSPROPS:
118 int keyEnd = remaining.indexOf( "," );
119 StringWriter key = new StringWriter();
120 StringWriter value = new StringWriter();
121 StringUtils.unescapeJava( key, remaining.substring( 0, keyEnd ) );
122 StringUtils.unescapeJava( value, remaining.substring( keyEnd + 1 ) );
123
124 synchronized ( testVmSystemProperties )
125 {
126 testVmSystemProperties.put( key, value );
127 }
128 break;
129 case ForkingRunListener.BOOTERCODE_STDOUT:
130 byte[] bytes = new byte[remaining.length() * 2];
131 int len = StringUtils.unescapeJava( bytes, remaining );
132 ( (ConsoleOutputReceiver) reporter ).writeTestOutput( bytes, 0, len, true );
133 break;
134 case ForkingRunListener.BOOTERCODE_STDERR:
135 bytes = new byte[remaining.length() * 2];
136 len = StringUtils.unescapeJava( bytes, remaining );
137 ( (ConsoleOutputReceiver) reporter ).writeTestOutput( bytes, 0, len, false );
138 break;
139 case ForkingRunListener.BOOTERCODE_CONSOLE:
140 ( (ConsoleLogger) reporter ).info( createConsoleMessage( remaining ) );
141 break;
142 default:
143 System.out.println( s );
144 }
145 }
146 catch ( NumberFormatException e )
147 {
148 System.out.println( s );
149 }
150 catch ( ReporterException e )
151 {
152 throw new NestedRuntimeException( e );
153 }
154 }
155
156 public void consumeMultiLineContent( String s )
157 throws IOException
158 {
159 BufferedReader stringReader = new BufferedReader( new StringReader( s ) );
160 String s1;
161 while ( ( s1 = stringReader.readLine() ) != null )
162 {
163 consumeLine( s1 );
164 }
165 }
166
167 private String createConsoleMessage( String remaining )
168 {
169 return unescape( remaining );
170 }
171
172 private ReportEntry createReportEntry( String untokenized)
173 {
174 StringTokenizer tokens = new StringTokenizer(untokenized, ",");
175 try
176 {
177 String source = tokens.nextToken();
178 String name = tokens.nextToken();
179 String group = nullableCsv( tokens.nextToken() );
180 String elapsedStr = tokens.nextToken();
181 Integer elapsed = "null".equals( elapsedStr ) ? null : Integer.decode( elapsedStr );
182 final StackTraceWriter stackTraceWriter =
183 tokens.hasMoreTokens() ? deserializeStackStraceWriter( tokens ) : null;
184
185 return group != null
186 ? new CategorizedReportEntry( source, name, group, stackTraceWriter, elapsed )
187 : new SimpleReportEntry( source, name, stackTraceWriter, elapsed );
188 }
189 catch ( RuntimeException e )
190 {
191 throw new RuntimeException( untokenized, e );
192 }
193 }
194
195 private StackTraceWriter deserializeStackStraceWriter( StringTokenizer tokens )
196 {
197 StackTraceWriter stackTraceWriter;
198 String stackTraceMessage = nullableCsv( tokens.nextToken() );
199 String stackTrace = tokens.hasMoreTokens() ? nullableCsv( tokens.nextToken() ) : null;
200 stackTraceWriter =
201 stackTrace != null ? new DeserializedStacktraceWriter( stackTraceMessage, stackTrace ) : null;
202 return stackTraceWriter;
203 }
204
205 private String nullableCsv( String source )
206 {
207 if ( "null".equals( source ) )
208 {
209 return null;
210 }
211 return unescape( source );
212 }
213
214 private String unescape( String source )
215 {
216 StringWriter stringWriter = new StringWriter( source.length() );
217
218 StringUtils.unescapeJava( stringWriter, source );
219 return stringWriter.getBuffer().toString();
220 }
221
222
223
224
225
226
227
228 public RunListener getReporter( Integer channelNumber )
229 {
230 return (RunListener) testSetReporters.get( channelNumber );
231 }
232
233
234 public void close()
235 {
236
237
238
239
240
241 }
242 }