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 org.apache.maven.plugin.surefire.SurefireProperties;
23  import org.apache.maven.surefire.booter.AbstractPathConfiguration;
24  import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
25  import org.apache.maven.surefire.booter.KeyValueSource;
26  import org.apache.maven.surefire.booter.ProviderConfiguration;
27  import org.apache.maven.surefire.booter.StartupConfiguration;
28  import org.apache.maven.surefire.cli.CommandLineOption;
29  import org.apache.maven.surefire.report.ReporterConfiguration;
30  import org.apache.maven.surefire.testset.DirectoryScannerParameters;
31  import org.apache.maven.surefire.testset.RunOrderParameters;
32  import org.apache.maven.surefire.testset.TestArtifactInfo;
33  import org.apache.maven.surefire.testset.TestListResolver;
34  import org.apache.maven.surefire.testset.TestRequest;
35  import org.apache.maven.surefire.util.RunOrder;
36  
37  import java.io.File;
38  import java.io.IOException;
39  import java.util.List;
40  
41  import static org.apache.maven.surefire.booter.AbstractPathConfiguration.CHILD_DELEGATION;
42  import static org.apache.maven.surefire.booter.AbstractPathConfiguration.CLASSPATH;
43  import static org.apache.maven.surefire.booter.AbstractPathConfiguration.ENABLE_ASSERTIONS;
44  import static org.apache.maven.surefire.booter.AbstractPathConfiguration.SUREFIRE_CLASSPATH;
45  import static org.apache.maven.surefire.booter.BooterConstants.EXCLUDES_PROPERTY_PREFIX;
46  import static org.apache.maven.surefire.booter.BooterConstants.FAIL_FAST_COUNT;
47  import static org.apache.maven.surefire.booter.BooterConstants.FAILIFNOTESTS;
48  import static org.apache.maven.surefire.booter.BooterConstants.FORKTESTSET;
49  import static org.apache.maven.surefire.booter.BooterConstants.FORKTESTSET_PREFER_TESTS_FROM_IN_STREAM;
50  import static org.apache.maven.surefire.booter.BooterConstants.INCLUDES_PROPERTY_PREFIX;
51  import static org.apache.maven.surefire.booter.BooterConstants.ISTRIMSTACKTRACE;
52  import static org.apache.maven.surefire.booter.BooterConstants.MAIN_CLI_OPTIONS;
53  import static org.apache.maven.surefire.booter.BooterConstants.PLUGIN_PID;
54  import static org.apache.maven.surefire.booter.BooterConstants.PROVIDER_CONFIGURATION;
55  import static org.apache.maven.surefire.booter.BooterConstants.REPORTSDIRECTORY;
56  import static org.apache.maven.surefire.booter.BooterConstants.REQUESTEDTEST;
57  import static org.apache.maven.surefire.booter.BooterConstants.RERUN_FAILING_TESTS_COUNT;
58  import static org.apache.maven.surefire.booter.BooterConstants.RUN_ORDER;
59  import static org.apache.maven.surefire.booter.BooterConstants.RUN_STATISTICS_FILE;
60  import static org.apache.maven.surefire.booter.BooterConstants.SHUTDOWN;
61  import static org.apache.maven.surefire.booter.BooterConstants.SOURCE_DIRECTORY;
62  import static org.apache.maven.surefire.booter.BooterConstants.SPECIFIC_TEST_PROPERTY_PREFIX;
63  import static org.apache.maven.surefire.booter.BooterConstants.SYSTEM_EXIT_TIMEOUT;
64  import static org.apache.maven.surefire.booter.BooterConstants.TEST_CLASSES_DIRECTORY;
65  import static org.apache.maven.surefire.booter.BooterConstants.TEST_SUITE_XML_FILES;
66  import static org.apache.maven.surefire.booter.BooterConstants.TESTARTIFACT_CLASSIFIER;
67  import static org.apache.maven.surefire.booter.BooterConstants.TESTARTIFACT_VERSION;
68  import static org.apache.maven.surefire.booter.BooterConstants.USEMANIFESTONLYJAR;
69  import static org.apache.maven.surefire.booter.BooterConstants.USESYSTEMCLASSLOADER;
70  import static org.apache.maven.surefire.booter.SystemPropertyManager.writePropertiesFile;
71  
72  /**
73   * Knows how to serialize and deserialize the booter configuration.
74   * <br>
75   * The internal serialization format is through a properties file. The long-term goal of this
76   * class is not to expose this implementation information to its clients. This still leaks somewhat,
77   * and there are some cases where properties are being accessed as "Properties" instead of
78   * more representative domain objects.
79   * <br>
80   *
81   * @author Jason van Zyl
82   * @author Emmanuel Venisse
83   * @author Brett Porter
84   * @author Dan Fabulich
85   * @author Kristian Rosenvold
86   */
87  class BooterSerializer
88  {
89      private final ForkConfiguration forkConfiguration;
90  
91      BooterSerializer( ForkConfiguration forkConfiguration )
92      {
93          this.forkConfiguration = forkConfiguration;
94      }
95  
96      /**
97       * Does not modify sourceProperties
98       */
99      File serialize( KeyValueSource sourceProperties, ProviderConfiguration booterConfiguration,
100                     StartupConfiguration providerConfiguration, Object testSet, boolean readTestsFromInStream,
101                     Long pid )
102         throws IOException
103     {
104         SurefireProperties properties = new SurefireProperties( sourceProperties );
105 
106         properties.setProperty( PLUGIN_PID, pid );
107 
108         AbstractPathConfiguration cp = providerConfiguration.getClasspathConfiguration();
109         properties.setClasspath( CLASSPATH, cp.getTestClasspath() );
110         properties.setClasspath( SUREFIRE_CLASSPATH, cp.getProviderClasspath() );
111         properties.setProperty( ENABLE_ASSERTIONS, toString( cp.isEnableAssertions() ) );
112         properties.setProperty( CHILD_DELEGATION, toString( cp.isChildDelegation() ) );
113 
114         TestArtifactInfo testNg = booterConfiguration.getTestArtifact();
115         if ( testNg != null )
116         {
117             properties.setProperty( TESTARTIFACT_VERSION, testNg.getVersion() );
118             properties.setNullableProperty( TESTARTIFACT_CLASSIFIER, testNg.getClassifier() );
119         }
120 
121         properties.setProperty( FORKTESTSET_PREFER_TESTS_FROM_IN_STREAM, readTestsFromInStream );
122         properties.setNullableProperty( FORKTESTSET, getTypeEncoded( testSet ) );
123 
124         TestRequest testSuiteDefinition = booterConfiguration.getTestSuiteDefinition();
125         if ( testSuiteDefinition != null )
126         {
127             properties.setProperty( SOURCE_DIRECTORY, testSuiteDefinition.getTestSourceDirectory() );
128             properties.addList( testSuiteDefinition.getSuiteXmlFiles(), TEST_SUITE_XML_FILES );
129             TestListResolver testFilter = testSuiteDefinition.getTestListResolver();
130             properties.setProperty( REQUESTEDTEST, testFilter == null ? "" : testFilter.getPluginParameterTest() );
131             int rerunFailingTestsCount = testSuiteDefinition.getRerunFailingTestsCount();
132             properties.setNullableProperty( RERUN_FAILING_TESTS_COUNT, toString( rerunFailingTestsCount ) );
133         }
134 
135         DirectoryScannerParameters directoryScannerParameters = booterConfiguration.getDirScannerParams();
136         if ( directoryScannerParameters != null )
137         {
138             properties.setProperty( FAILIFNOTESTS, toString( directoryScannerParameters.isFailIfNoTests() ) );
139             properties.addList( directoryScannerParameters.getIncludes(), INCLUDES_PROPERTY_PREFIX );
140             properties.addList( directoryScannerParameters.getExcludes(), EXCLUDES_PROPERTY_PREFIX );
141             properties.addList( directoryScannerParameters.getSpecificTests(), SPECIFIC_TEST_PROPERTY_PREFIX );
142             properties.setProperty( TEST_CLASSES_DIRECTORY, directoryScannerParameters.getTestClassesDirectory() );
143         }
144 
145         final RunOrderParameters runOrderParameters = booterConfiguration.getRunOrderParameters();
146         if ( runOrderParameters != null )
147         {
148             properties.setProperty( RUN_ORDER, RunOrder.asString( runOrderParameters.getRunOrder() ) );
149             properties.setProperty( RUN_STATISTICS_FILE, runOrderParameters.getRunStatisticsFile() );
150         }
151 
152         ReporterConfiguration reporterConfiguration = booterConfiguration.getReporterConfiguration();
153         boolean rep = reporterConfiguration.isTrimStackTrace();
154         properties.setProperty( ISTRIMSTACKTRACE, rep );
155         properties.setProperty( REPORTSDIRECTORY, reporterConfiguration.getReportsDirectory() );
156         ClassLoaderConfiguration classLoaderConfig = providerConfiguration.getClassLoaderConfiguration();
157         properties.setProperty( USESYSTEMCLASSLOADER, toString( classLoaderConfig.isUseSystemClassLoader() ) );
158         properties.setProperty( USEMANIFESTONLYJAR, toString( classLoaderConfig.isUseManifestOnlyJar() ) );
159         properties.setProperty( FAILIFNOTESTS, toString( booterConfiguration.isFailIfNoTests() ) );
160         properties.setProperty( PROVIDER_CONFIGURATION, providerConfiguration.getProviderClassName() );
161         properties.setProperty( FAIL_FAST_COUNT, toString( booterConfiguration.getSkipAfterFailureCount() ) );
162         properties.setProperty( SHUTDOWN, booterConfiguration.getShutdown().name() );
163         List<CommandLineOption> mainCliOptions = booterConfiguration.getMainCliOptions();
164         if ( mainCliOptions != null )
165         {
166             properties.addList( mainCliOptions, MAIN_CLI_OPTIONS );
167         }
168         properties.setNullableProperty( SYSTEM_EXIT_TIMEOUT, toString( booterConfiguration.getSystemExitTimeout() ) );
169 
170         File surefireTmpDir = forkConfiguration.getTempDirectory();
171         boolean debug = forkConfiguration.isDebug();
172         return writePropertiesFile( properties, surefireTmpDir, "surefire", debug );
173     }
174 
175     private static String getTypeEncoded( Object value )
176     {
177         if ( value == null )
178         {
179             return null;
180         }
181         String valueToUse = value instanceof Class ? ( (Class<?>) value ).getName() : value.toString();
182         return value.getClass().getName() + "|" + valueToUse;
183     }
184 
185     private static String toString( Object o )
186     {
187         return String.valueOf( o );
188     }
189 }