| ------ |
| Developing Surefire |
| ------ |
| Kristian Rosenvold |
| ------ |
| 2011-03-07 |
| ------ |
| |
| ~~ Licensed to the Apache Software Foundation (ASF) under one |
| ~~ or more contributor license agreements. See the NOTICE file |
| ~~ distributed with this work for additional information |
| ~~ regarding copyright ownership. The ASF licenses this file |
| ~~ to you under the Apache License, Version 2.0 (the |
| ~~ "License"); you may not use this file except in compliance |
| ~~ with the License. You may obtain a copy of the License at |
| ~~ |
| ~~ http://www.apache.org/licenses/LICENSE-2.0 |
| ~~ |
| ~~ Unless required by applicable law or agreed to in writing, |
| ~~ software distributed under the License is distributed on an |
| ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| ~~ KIND, either express or implied. See the License for the |
| ~~ specific language governing permissions and limitations |
| ~~ under the License. |
| |
| ~~ NOTE: For help with the syntax of this file, see: |
| ~~ http://maven.apache.org/doxia/references/apt-format.html |
| |
| Developer Center |
| |
| When working with Surefire, it is necessary to understand a few things: |
| |
| * Multi-module Project |
| |
| The plugin is built as part of a multi-module plugin. You need to check out |
| the complete module and build from there: |
| |
| +---+ |
| git clone https://git-wip-us.apache.org/repos/asf/maven-surefire.git |
| +---+ |
| |
| * Making Test Cases for Demonstrating Problems |
| |
| When reporting an issue, it is immensely useful to create a small sample project |
| that demonstrates the problem. Surefire already contains a large number of such |
| projects, and they can be found at |
| {{surefire-integration-tests/src/test/resources/}}. |
| Typically you can check out one of the pre-existing projects and run it like this: |
| |
| +---+ |
| cd surefire-integration-tests/src/test/resources/failsafe-buildfail |
| mvn -Dsurefire.version=2.12 verify |
| +---+ |
| |
| * Attaching a Debugger |
| |
| Sometimes it's appropriate to attach a remote debugger to the Surefire fork to try to determine what |
| is <really> going on. If you checkout and build trunk, you'd usually do something like this: |
| |
| +---+ |
| mvn -Dmaven.surefire.debug=true install |
| +---+ |
| |
| Load the source in your IDE, set a breakpoint at the start of <<<ForkedBooter#main>>> and attach |
| a debugger to port 5005. |
| |
| * Tracing a Forked Execution |
| |
| The forked Surefire process uses standard input and output to communicate back to the source. Sometimes when tracking troubles |
| it can be helpful to look at just the output of the fork. |
| |
| This can be done by running: |
| |
| +---+ |
| mvn -e -X install | grep Forking |
| +---+ |
| |
| If you copy the command part of the output, you should be able to re-run the command by just pasting it on |
| the command line (you might have to do only the bits after <<<&&>>>). |
| |
| You can now paste this command on the command line and capture the output of the fork. This may help you |
| determine if the problem is in the forked end or the receiving end. |
| |
| When investigating a particular class, you probably want to <<<grep>>> the output for the class name. |
| Additionally the booter code (first field) can be seen at |
| {{https://git-wip-us.apache.org/repos/asf?p=maven-surefire.git;a=blob;f=surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java}} |
| |
| The second field in the output (after the booter code) is the logical channel number, where different threads in the fork |
| should come in different channels. |
| |
| * Test Cases |
| |
| All patches to Surefire must contain test coverage, either as an integration test |
| or a unit test. All new features (changed/added plugin options) must be covered by |
| an end-to-end integration test. |
| |
| There are |
| numerous other integration tests that all operate on small sample projects in |
| <<<surefire-integration-tests/src/test/resources>>>. |
| |
| Example integration tests are <<<Surefire141PluggableProvidersIT>>> and the corresponding |
| <<<surefire-integration-tests/src/test/resources/surefire-141-pluggableproviders>>>. |
| |
| * Essential Source Code Reading List |
| |
| Some methods/classes reveal more about the basic working of a piece of code than others. The following classes/methods |
| are a "reading list" for getting quickly acquainted with the code: |
| |
| +---+ |
| AbstractSurefireMojo#executeAllProviders |
| ForkStarter#fork |
| ForkedBooter#main |
| +---+ |
| |
| * JDK Versions |
| |
| The surefire booter is capable of booting all the way back to jdk1.7. Specifically |
| this means <<<surefire-api>>>, <<<surefire-booter>>>, <<<common-junit3>>>, <<<surefire-junit3>>> |
| and other modules are compiled with source/target 1.7. The plugin and several providers are 1.7. |
| The provider <<<surefire-junit-platform>>> is compiled with jdk1.8. |
| The project requires using <<<JAVA_HOME>>> jdk1.8 but the tests run with jdk1.7+ which is |
| configured by system property <<<jdk.home>>>, see <<<README.md>>>. |
| |
| * Provider Isolation |
| |
| Classes in the SUT (<Subject Under Test>) override any classes within the |
| Surefire providers. This means providers using any |
| third party dependencies (other than the test framework itself) should |
| shade these classes to a different package. |
| |
| * Common Provider Modules |
| |
| The <<<surefire-providers>>> module contains <<<common-junitXX>>> modules. These modules |
| depend on the <<<XX>>> version of JUnit and can access the JUnit APIs at the correct |
| JUnit version level. Unit tests can also be written that will run with the |
| correct JUnit version. At build time, all of the relevant parts of these "common" |
| modules are just shaded into the provider jar files. |
| |
| * Shadefire |
| |
| "Shadefire" is the first module to be run in the |
| Surefire build. This creates as shaded version of the JUnit provider, and this provider |
| is thereafter used to build Surefire itself (as of Surefire 2.8). This is |
| because the SUT overrides the provider, and the Shadefire provider has been |
| relocated to avoid this overriding when Surefire is building itself. |
| |
| * Deploying and Releasing Surefire |
| |
| Surefire depends on a previous version of itself, which |
| is too advanced for the Maven 2.2.x dependency resolution. Thus Maven 3.x is |
| required to build Surefire. |