1 package org.apache.maven.plugin.surefire.booterclient;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.surefire.booter.BooterConstants;
23 import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
24 import org.apache.maven.surefire.booter.PropertiesWrapper;
25 import org.apache.maven.surefire.booter.ProviderConfiguration;
26 import org.apache.maven.surefire.booter.StartupConfiguration;
27 import org.apache.maven.surefire.booter.SystemPropertyManager;
28 import org.apache.maven.surefire.report.ReporterConfiguration;
29 import org.apache.maven.surefire.testset.DirectoryScannerParameters;
30 import org.apache.maven.surefire.testset.TestArtifactInfo;
31 import org.apache.maven.surefire.testset.TestRequest;
32 import org.apache.maven.surefire.util.NestedRuntimeException;
33 import org.codehaus.plexus.util.StringUtils;
34
35 import java.io.ByteArrayOutputStream;
36 import java.io.File;
37 import java.io.IOException;
38 import java.util.ArrayList;
39 import java.util.List;
40 import java.util.Properties;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public class BooterSerializer
59 {
60 private final ForkConfiguration forkConfiguration;
61
62 private final PropertiesWrapper properties;
63
64 public BooterSerializer( ForkConfiguration forkConfiguration, Properties properties )
65 {
66 this.forkConfiguration = forkConfiguration;
67 this.properties = new PropertiesWrapper( properties );
68 }
69
70
71 public File serialize( ProviderConfiguration booterConfiguration, StartupConfiguration providerConfiguration,
72 Object testSet )
73 throws IOException
74 {
75 List params = new ArrayList();
76 params.add(
77 new Object[]{ BooterConstants.DIRSCANNER_OPTIONS, booterConfiguration.getDirScannerParamsArray() } );
78 addPropertiesForTypeHolder( params, properties.getProperties(), BooterConstants.DIRSCANNER_PROPERTY_PREFIX );
79
80 providerConfiguration.getClasspathConfiguration().setForkProperties( properties);
81
82 TestArtifactInfo testNg = booterConfiguration.getTestArtifact();
83 if ( testNg != null )
84 {
85 properties.setProperty( BooterConstants.TESTARTIFACT_VERSION, testNg.getVersion() );
86 properties.setProperty( BooterConstants.TESTARTIFACT_CLASSIFIER, testNg.getClassifier() );
87 }
88
89 properties.setProperty( BooterConstants.FORKTESTSET, getTypeEncoded( testSet ) );
90 TestRequest testSuiteDefinition = booterConfiguration.getTestSuiteDefinition();
91 if ( testSuiteDefinition != null )
92 {
93 properties.setProperty( BooterConstants.SOURCE_DIRECTORY, testSuiteDefinition.getTestSourceDirectory() );
94 properties.addList( testSuiteDefinition.getSuiteXmlFiles(), BooterConstants.TEST_SUITE_XML_FILES );
95 properties.setProperty( BooterConstants.REQUESTEDTEST, testSuiteDefinition.getRequestedTest() );
96 properties.setProperty( BooterConstants.REQUESTEDTESTMETHOD, testSuiteDefinition.getRequestedTestMethod() );
97 }
98
99 DirectoryScannerParameters directoryScannerParameters = booterConfiguration.getDirScannerParams();
100 if ( directoryScannerParameters != null )
101 {
102 properties.setProperty( BooterConstants.FAILIFNOTESTS,
103 String.valueOf( directoryScannerParameters.isFailIfNoTests() ) );
104 properties.addList( directoryScannerParameters.getIncludes(), BooterConstants.INCLUDES_PROPERTY_PREFIX );
105 properties.addList( directoryScannerParameters.getExcludes(), BooterConstants.EXCLUDES_PROPERTY_PREFIX );
106 properties.setProperty( BooterConstants.TEST_CLASSES_DIRECTORY,
107 directoryScannerParameters.getTestClassesDirectory() );
108 properties.setProperty( BooterConstants.RUN_ORDER, directoryScannerParameters.getRunOrder() );
109 }
110
111 ReporterConfiguration reporterConfiguration = booterConfiguration.getReporterConfiguration();
112 addList( reporterConfiguration.getReports(), properties.getProperties(),
113 BooterConstants.REPORT_PROPERTY_PREFIX );
114
115 Boolean rep = reporterConfiguration.isTrimStackTrace();
116 properties.setProperty( BooterConstants.ISTRIMSTACKTRACE, rep );
117 properties.setProperty( BooterConstants.REPORTSDIRECTORY, reporterConfiguration.getReportsDirectory() );
118 properties.setProperty( BooterConstants.FORKTIMEOUT, reporterConfiguration.getForkTimeout() );
119 ClassLoaderConfiguration classLoaderConfiguration = providerConfiguration.getClassLoaderConfiguration();
120 properties.setProperty( BooterConstants.USESYSTEMCLASSLOADER,
121 String.valueOf( classLoaderConfiguration.isUseSystemClassLoader() ) );
122 properties.setProperty( BooterConstants.USEMANIFESTONLYJAR,
123 String.valueOf( classLoaderConfiguration.isUseManifestOnlyJar() ) );
124 properties.setProperty( BooterConstants.FAILIFNOTESTS,
125 String.valueOf( booterConfiguration.isFailIfNoTests() ) );
126 properties.setProperty( BooterConstants.PROVIDER_CONFIGURATION, providerConfiguration.getProviderClassName() );
127
128 return SystemPropertyManager.writePropertiesFile( properties.getProperties(),
129 forkConfiguration.getTempDirectory(), "surefire",
130 forkConfiguration.isDebug() );
131 }
132
133
134 private String getTypeEncoded( Object value )
135 {
136 if ( value == null )
137 {
138 return null;
139 }
140 String valueToUse;
141 if ( value instanceof Class )
142 {
143 valueToUse = ( (Class) value ).getName();
144 }
145 else
146 {
147 valueToUse = value.toString();
148 }
149 return value.getClass().getName() + "|" + valueToUse;
150 }
151
152 private void addPropertiesForTypeHolder( List typeHolderList, Properties properties, String propertyPrefix )
153 {
154 for ( int i = 0; i < typeHolderList.size(); i++ )
155 {
156 Object[] report = (Object[]) typeHolderList.get( i );
157
158 String className = (String) report[0];
159 Object[] params = (Object[]) report[1];
160
161 properties.setProperty( propertyPrefix + i, className );
162
163 if ( params != null )
164 {
165 String paramProperty = getValues( params );
166 String typeProperty = getTypes( params );
167 properties.setProperty( propertyPrefix + i + BooterConstants.PARAMS_SUFIX, paramProperty );
168 properties.setProperty( propertyPrefix + i + BooterConstants.TYPES_SUFIX, typeProperty );
169 }
170 }
171 }
172
173 private String getValues( Object[] params )
174 {
175 StringBuffer result = new StringBuffer();
176 if ( params != null && params.length > 0 )
177 {
178 result.append( convert( params[0] ) );
179 for ( int j = 1; j < params.length; j++ )
180 {
181 result.append( "|" );
182 if ( params[j] != null )
183 {
184 result.append( convert( params[j] ) );
185 }
186 }
187 }
188 return result.toString();
189 }
190
191 private String getTypes( Object[] params )
192 {
193 StringBuffer result = new StringBuffer();
194 if ( params != null && params.length > 0 )
195 {
196 result.append( params[0].getClass().getName() );
197 for ( int j = 1; j < params.length; j++ )
198 {
199 result.append( "|" );
200 if ( params[j] != null )
201 {
202 result.append( params[j].getClass().getName() );
203 }
204 }
205 }
206 return result.toString();
207 }
208
209 private static String convert( Object param )
210 {
211 if ( param instanceof File[] )
212 {
213 File[] files = (File[]) param;
214 return "[" + StringUtils.join( files, "," ) + "]";
215 }
216 else if ( param instanceof Properties )
217 {
218 ByteArrayOutputStream baos = new ByteArrayOutputStream();
219 try
220 {
221 ( (Properties) param ).store( baos, "" );
222 return new String( baos.toByteArray(), "8859_1" );
223 }
224 catch ( Exception e )
225 {
226 throw new NestedRuntimeException( "bug in property conversion", e );
227 }
228 }
229 else
230 {
231 return param.toString();
232 }
233 }
234
235 private void addList( List items, Properties properties, String propertyPrefix )
236 {
237 for ( int i = 0; i < items.size(); i++ )
238 {
239 Object item = items.get( i );
240 if ( item == null )
241 {
242 throw new NullPointerException( propertyPrefix + i + " has null value" );
243 }
244 properties.setProperty( propertyPrefix + i, item.toString() );
245 }
246 }
247
248 }