View Javadoc
1   package org.apache.maven.plugin.surefire.booterclient;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  
25  import org.apache.maven.plugin.surefire.SurefireProperties;
26  import org.apache.maven.surefire.booter.BooterConstants;
27  import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
28  import org.apache.maven.surefire.booter.ClasspathConfiguration;
29  import org.apache.maven.surefire.booter.KeyValueSource;
30  import org.apache.maven.surefire.booter.ProviderConfiguration;
31  import org.apache.maven.surefire.booter.StartupConfiguration;
32  import org.apache.maven.surefire.booter.SystemPropertyManager;
33  import org.apache.maven.surefire.report.ReporterConfiguration;
34  import org.apache.maven.surefire.testset.DirectoryScannerParameters;
35  import org.apache.maven.surefire.testset.RunOrderParameters;
36  import org.apache.maven.surefire.testset.TestArtifactInfo;
37  import org.apache.maven.surefire.testset.TestRequest;
38  import org.apache.maven.surefire.util.RunOrder;
39  
40  /**
41   * Knows how to serialize and deserialize the booter configuration.
42   * <p/>
43   * The internal serialization format is through a properties file. The long-term goal of this
44   * class is not to expose this implementation information to its clients. This still leaks somewhat,
45   * and there are some cases where properties are being accessed as "Properties" instead of
46   * more representative domain objects.
47   * <p/>
48   *
49   * @author Jason van Zyl
50   * @author Emmanuel Venisse
51   * @author Brett Porter
52   * @author Dan Fabulich
53   * @author Kristian Rosenvold
54   */
55  class BooterSerializer
56  {
57      private final ForkConfiguration forkConfiguration;
58  
59      public BooterSerializer( ForkConfiguration forkConfiguration )
60      {
61          this.forkConfiguration = forkConfiguration;
62      }
63  
64  
65      /*
66      DOes not modify sourceProperties
67       */
68      public File serialize( KeyValueSource sourceProperties, ProviderConfiguration booterConfiguration,
69                             StartupConfiguration providerConfiguration, Object testSet, boolean readTestsFromInStream )
70          throws IOException
71      {
72  
73          SurefireProperties properties = new SurefireProperties( sourceProperties );
74  
75          ClasspathConfiguration cp = providerConfiguration.getClasspathConfiguration();
76          properties.setClasspath( ClasspathConfiguration.CLASSPATH, cp.getTestClasspath() );
77          properties.setClasspath( ClasspathConfiguration.SUREFIRE_CLASSPATH, cp.getProviderClasspath() );
78          properties.setProperty( ClasspathConfiguration.ENABLE_ASSERTIONS, String.valueOf( cp.isEnableAssertions() ) );
79          properties.setProperty( ClasspathConfiguration.CHILD_DELEGATION, String.valueOf( cp.isChildDelegation() ) );
80  
81          TestArtifactInfo testNg = booterConfiguration.getTestArtifact();
82          if ( testNg != null )
83          {
84              properties.setProperty( BooterConstants.TESTARTIFACT_VERSION, testNg.getVersion() );
85              properties.setNullableProperty( BooterConstants.TESTARTIFACT_CLASSIFIER, testNg.getClassifier() );
86          }
87  
88          properties.setProperty( BooterConstants.FORKTESTSET_PREFER_TESTS_FROM_IN_STREAM, readTestsFromInStream );
89          properties.setNullableProperty( BooterConstants.FORKTESTSET, getTypeEncoded( testSet ) );
90  
91          TestRequest testSuiteDefinition = booterConfiguration.getTestSuiteDefinition();
92          if ( testSuiteDefinition != null )
93          {
94              properties.setProperty( BooterConstants.SOURCE_DIRECTORY, testSuiteDefinition.getTestSourceDirectory() );
95              properties.addList( testSuiteDefinition.getSuiteXmlFiles(), BooterConstants.TEST_SUITE_XML_FILES );
96              properties.setNullableProperty( BooterConstants.REQUESTEDTEST, testSuiteDefinition.getRequestedTest() );
97              properties.setNullableProperty( BooterConstants.REQUESTEDTESTMETHOD,
98                                              testSuiteDefinition.getRequestedTestMethod() );
99              properties.setNullableProperty( BooterConstants.RERUN_FAILING_TESTS_COUNT,
100                                             String.valueOf( testSuiteDefinition.getRerunFailingTestsCount() ) );
101         }
102 
103         DirectoryScannerParameters directoryScannerParameters = booterConfiguration.getDirScannerParams();
104         if ( directoryScannerParameters != null )
105         {
106             properties.setProperty( BooterConstants.FAILIFNOTESTS,
107                                     String.valueOf( directoryScannerParameters.isFailIfNoTests() ) );
108             properties.addList( directoryScannerParameters.getIncludes(), BooterConstants.INCLUDES_PROPERTY_PREFIX );
109             properties.addList( directoryScannerParameters.getExcludes(), BooterConstants.EXCLUDES_PROPERTY_PREFIX );
110             properties.addList( directoryScannerParameters.getSpecificTests(),
111                                 BooterConstants.SPECIFIC_TEST_PROPERTY_PREFIX );
112 
113             properties.setProperty( BooterConstants.TEST_CLASSES_DIRECTORY,
114                                     directoryScannerParameters.getTestClassesDirectory() );
115         }
116 
117         final RunOrderParameters runOrderParameters = booterConfiguration.getRunOrderParameters();
118         if ( runOrderParameters != null )
119         {
120             properties.setProperty( BooterConstants.RUN_ORDER, RunOrder.asString( runOrderParameters.getRunOrder() ) );
121             properties.setProperty( BooterConstants.RUN_STATISTICS_FILE, runOrderParameters.getRunStatisticsFile() );
122         }
123 
124         ReporterConfiguration reporterConfiguration = booterConfiguration.getReporterConfiguration();
125 
126         Boolean rep = reporterConfiguration.isTrimStackTrace();
127         properties.setProperty( BooterConstants.ISTRIMSTACKTRACE, rep );
128         properties.setProperty( BooterConstants.REPORTSDIRECTORY, reporterConfiguration.getReportsDirectory() );
129         ClassLoaderConfiguration classLoaderConfiguration = providerConfiguration.getClassLoaderConfiguration();
130         properties.setProperty( BooterConstants.USESYSTEMCLASSLOADER,
131                                 String.valueOf( classLoaderConfiguration.isUseSystemClassLoader() ) );
132         properties.setProperty( BooterConstants.USEMANIFESTONLYJAR,
133                                 String.valueOf( classLoaderConfiguration.isUseManifestOnlyJar() ) );
134         properties.setProperty( BooterConstants.FAILIFNOTESTS,
135                                 String.valueOf( booterConfiguration.isFailIfNoTests() ) );
136         properties.setProperty( BooterConstants.PROVIDER_CONFIGURATION, providerConfiguration.getProviderClassName() );
137 
138         return SystemPropertyManager.writePropertiesFile( properties,
139                                                           forkConfiguration.getTempDirectory(), "surefire",
140                                                           forkConfiguration.isDebug() );
141     }
142 
143 
144     private String getTypeEncoded( Object value )
145     {
146         if ( value == null )
147         {
148             return null;
149         }
150         String valueToUse;
151         if ( value instanceof Class )
152         {
153             valueToUse = ( (Class<?>) value ).getName();
154         }
155         else
156         {
157             valueToUse = value.toString();
158         }
159         return value.getClass().getName() + "|" + valueToUse;
160     }
161 
162 }