View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.surefire.booter;
20  
21  import javax.annotation.Nonnull;
22  
23  import java.io.File;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.util.Collection;
27  import java.util.List;
28  
29  import org.apache.maven.surefire.api.booter.Shutdown;
30  import org.apache.maven.surefire.api.report.ReporterConfiguration;
31  import org.apache.maven.surefire.api.testset.DirectoryScannerParameters;
32  import org.apache.maven.surefire.api.testset.RunOrderParameters;
33  import org.apache.maven.surefire.api.testset.TestArtifactInfo;
34  import org.apache.maven.surefire.api.testset.TestListResolver;
35  import org.apache.maven.surefire.api.testset.TestRequest;
36  
37  import static org.apache.maven.surefire.api.cli.CommandLineOption.*;
38  import static org.apache.maven.surefire.booter.BooterConstants.*;
39  
40  /**
41   * Knows how to serialize and deserialize the booter configuration.
42   * <br>
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   * <br>
48   *
49   * @author Jason van Zyl
50   * @author Emmanuel Venisse
51   * @author Kristian Rosenvold
52   */
53  public class BooterDeserializer {
54      private final PropertiesWrapper properties;
55  
56      public BooterDeserializer(InputStream inputStream) throws IOException {
57          properties = SystemPropertyManager.loadProperties(inputStream);
58      }
59  
60      public int getForkNumber() {
61          return properties.getIntProperty(FORK_NUMBER);
62      }
63  
64      /**
65       * Describes the current connection channel used by the client in the forked JVM
66       * in order to connect to the plugin process.
67       *
68       * @return connection string (must not be null)
69       */
70      @Nonnull
71      public String getConnectionString() {
72          return properties.getProperty(FORK_NODE_CONNECTION_STRING);
73      }
74  
75      /**
76       * @return PID of Maven process where plugin is executed; or null if PID could not be determined.
77       */
78      public String getPluginPid() {
79          return properties.getProperty(PLUGIN_PID);
80      }
81  
82      public ProviderConfiguration deserialize() {
83          final File reportsDirectory = new File(properties.getProperty(REPORTSDIRECTORY));
84          final String testNgVersion = properties.getProperty(TESTARTIFACT_VERSION);
85          final String testArtifactClassifier = properties.getProperty(TESTARTIFACT_CLASSIFIER);
86  
87          final TypeEncodedValue typeEncodedTestForFork = properties.getTypeEncodedValue(FORKTESTSET);
88          final boolean preferTestsFromInStream = properties.getBooleanProperty(FORKTESTSET_PREFER_TESTS_FROM_IN_STREAM);
89  
90          final String requestedTest = properties.getProperty(REQUESTEDTEST);
91          final File sourceDirectory = properties.getFileProperty(SOURCE_DIRECTORY);
92  
93          final List<String> excludes = properties.getStringList(EXCLUDES_PROPERTY_PREFIX);
94          final List<String> includes = properties.getStringList(INCLUDES_PROPERTY_PREFIX);
95          final List<String> specificTests = properties.getStringList(SPECIFIC_TEST_PROPERTY_PREFIX);
96  
97          final List<String> testSuiteXmlFiles = properties.getStringList(TEST_SUITE_XML_FILES);
98          final File testClassesDirectory = properties.getFileProperty(TEST_CLASSES_DIRECTORY);
99          final String runOrder = properties.getProperty(RUN_ORDER);
100         final Long runOrderRandomSeed = properties.getLongProperty(RUN_ORDER_RANDOM_SEED);
101         final String runStatisticsFile = properties.getProperty(RUN_STATISTICS_FILE);
102 
103         final int rerunFailingTestsCount = properties.getIntProperty(RERUN_FAILING_TESTS_COUNT);
104 
105         DirectoryScannerParameters dirScannerParams =
106                 new DirectoryScannerParameters(testClassesDirectory, includes, excludes, specificTests, runOrder);
107 
108         RunOrderParameters runOrderParameters = new RunOrderParameters(
109                 runOrder, runStatisticsFile == null ? null : new File(runStatisticsFile), runOrderRandomSeed);
110 
111         TestArtifactInfo testNg = new TestArtifactInfo(testNgVersion, testArtifactClassifier);
112         TestRequest testSuiteDefinition = new TestRequest(
113                 testSuiteXmlFiles, sourceDirectory, new TestListResolver(requestedTest), rerunFailingTestsCount);
114 
115         ReporterConfiguration reporterConfiguration =
116                 new ReporterConfiguration(reportsDirectory, properties.getBooleanProperty(ISTRIMSTACKTRACE));
117 
118         Collection<String> cli = properties.getStringList(MAIN_CLI_OPTIONS);
119 
120         int failFastCount = properties.getIntProperty(FAIL_FAST_COUNT);
121 
122         Shutdown shutdown = Shutdown.valueOf(properties.getProperty(SHUTDOWN));
123 
124         String systemExitTimeoutAsString = properties.getProperty(SYSTEM_EXIT_TIMEOUT);
125         Integer systemExitTimeout =
126                 systemExitTimeoutAsString == null ? null : Integer.valueOf(systemExitTimeoutAsString);
127 
128         return new ProviderConfiguration(
129                 dirScannerParams,
130                 runOrderParameters,
131                 reporterConfiguration,
132                 testNg,
133                 testSuiteDefinition,
134                 properties.getProperties(),
135                 typeEncodedTestForFork,
136                 preferTestsFromInStream,
137                 fromStrings(cli),
138                 failFastCount,
139                 shutdown,
140                 systemExitTimeout);
141     }
142 
143     public StartupConfiguration getStartupConfiguration() {
144         boolean useSystemClassLoader = properties.getBooleanProperty(USESYSTEMCLASSLOADER);
145         boolean useManifestOnlyJar = properties.getBooleanProperty(USEMANIFESTONLYJAR);
146         String providerConfiguration = properties.getProperty(PROVIDER_CONFIGURATION);
147 
148         ClassLoaderConfiguration classLoaderConfiguration =
149                 new ClassLoaderConfiguration(useSystemClassLoader, useManifestOnlyJar);
150 
151         ClasspathConfiguration classpathConfiguration = new ClasspathConfiguration(properties);
152 
153         String processChecker = properties.getProperty(PROCESS_CHECKER);
154         ProcessCheckerType processCheckerType = ProcessCheckerType.toEnum(processChecker);
155 
156         return StartupConfiguration.inForkedVm(
157                 providerConfiguration, classpathConfiguration,
158                 classLoaderConfiguration, processCheckerType);
159     }
160 }