From 67ef711ce356194fbe57968403d87ff99107d6a2 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Tue, 8 Dec 2020 12:54:22 +0000 Subject: [PATCH 01/25] update readme for 1.6.1 --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index ba1d24ebd..d8e228bb4 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,14 @@ Read all about it at http://pitest.org ## Releases +### 1.6.1 + +* Automate release to maven central +* #774 Test strength statistic (thanks @alex859) +* #798 Enable jvm args to be passed from command line (thanks @yfrolov) +* #797 Add line coverage to console (thanks @qxo) +* #822 Mitigate NPE on accidental dependency (thanks @szpak) + ### 1.5.2 * #749 ANT support for the fullMutationMatrix option (thanks @ayaankazerouni) From 69d395667849b81ee3d267bb1c0c6721a6bd9e00 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Thu, 10 Dec 2020 16:43:03 +0000 Subject: [PATCH 02/25] publish snapshot on merge to master --- .github/workflows/snapshot.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/snapshot.yml diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml new file mode 100644 index 000000000..8b332ea03 --- /dev/null +++ b/.github/workflows/snapshot.yml @@ -0,0 +1,30 @@ +name: Deploy snapshot +on: + push: + branches: + - master +jobs: + snapshot: + runs-on: ubuntu-latest + steps: + - name: Checkout project + uses: actions/checkout@v2 + - name: Cache local Maven repository + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-maven- + - name: Setup Java JDK + uses: actions/setup-java@v1.4.3 + with: + java-version: 8 + server-id: ossrh + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + - name: Publish JARs + run: mvn -B deploy -DskipTests=true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} From 2f584595917983341412d267713e8e2dd3486e3d Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Thu, 10 Dec 2020 17:10:58 +0000 Subject: [PATCH 03/25] make report options object available to listeners --- .../mutationtest/ListenerArguments.java | 17 +++++++++-- .../tooling/MutationCoverage.java | 28 +++++++++---------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java b/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java index 8b4f0a44f..3ded8afc9 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java @@ -1,6 +1,7 @@ package org.pitest.mutationtest; import org.pitest.coverage.CoverageDatabase; +import org.pitest.mutationtest.config.ReportOptions; import org.pitest.mutationtest.engine.MutationEngine; import org.pitest.util.ResultOutputStrategy; @@ -16,16 +17,22 @@ public class ListenerArguments { private final SourceLocator locator; private final MutationEngine engine; private final boolean fullMutationMatrix; + private final ReportOptions data; - public ListenerArguments(final ResultOutputStrategy outputStrategy, - final CoverageDatabase coverage, final SourceLocator locator, - final MutationEngine engine, final long startTime, final boolean fullMutationMatrix) { + public ListenerArguments(ResultOutputStrategy outputStrategy, + CoverageDatabase coverage, + SourceLocator locator, + MutationEngine engine, + long startTime, + boolean fullMutationMatrix, + ReportOptions data) { this.outputStrategy = outputStrategy; this.coverage = coverage; this.locator = locator; this.startTime = startTime; this.engine = engine; this.fullMutationMatrix = fullMutationMatrix; + this.data = data; } public ResultOutputStrategy getOutputStrategy() { @@ -51,4 +58,8 @@ public MutationEngine getEngine() { public boolean isFullMutationMatrix() { return fullMutationMatrix; } + + public ReportOptions data() { + return data; + } } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java index 9c136c3db..8edd0ed9b 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java @@ -14,18 +14,6 @@ */ package org.pitest.mutationtest.tooling; -import java.io.File; -import java.io.IOException; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - import org.pitest.classinfo.ClassByteArraySource; import org.pitest.classinfo.ClassInfo; import org.pitest.classinfo.ClassName; @@ -66,6 +54,18 @@ import org.pitest.util.StringUtil; import org.pitest.util.Timings; +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + public class MutationCoverage { private static final int MB = 1024 * 1024; @@ -174,7 +174,7 @@ private void checkExcludedRunners() { } } -private int numberOfThreads() { + private int numberOfThreads() { return Math.max(1, this.data.getNumberOfThreads()); } @@ -187,7 +187,7 @@ private List createConfig(final long t0, final ListenerArguments args = new ListenerArguments( this.strategies.output(), coverageData, new SmartSourceLocator( - this.data.getSourceDirs()), engine, t0, this.data.isFullMutationMatrix()); + this.data.getSourceDirs()), engine, t0, this.data.isFullMutationMatrix(), data); final MutationResultListener mutationReportListener = this.strategies .listenerFactory().getListener(this.data.getFreeFormProperties(), args); From 26bf9f7a40a1b276ea03cc569fe4507f8376ed89 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Fri, 11 Dec 2020 12:32:16 +0000 Subject: [PATCH 04/25] Reduce travis matrix --- .travis.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5a38e0268..dae3e37dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,12 +16,9 @@ env: matrix: include: - jdk: openjdk8 - env: MAVEN=3.2.5 - - - jdk: openjdk9 env: MAVEN=3.5.4 - - jdk: openjdk10 + - jdk: openjdk9 env: MAVEN=3.5.4 - jdk: openjdk11 @@ -30,13 +27,10 @@ matrix: - jdk: openjdk12 env: MAVEN=3.5.4 - - jdk: openjdk13 - env: MAVEN=3.6.3 - - env: JDK=14 MAVEN=3.6.3 install: . ./install-jdk.sh --feature 14 - - env: JDK='OpenJ9 11' MAVEN=3.5.4 + - env: JDK='OpenJ9 11' MAVEN=3.6.3 install: . ./install-jdk.sh --url "https://api.adoptopenjdk.net/v2/binary/releases/openjdk11?openjdk_impl=openj9&os=linux&arch=x64&release=latest&type=jdk&heap_size=normal" script: From c6cadf6c5dba855b2cc647bfa4a5c468b9040703 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Fri, 11 Dec 2020 12:55:21 +0000 Subject: [PATCH 05/25] Replace travis ci Unfortunately travis has become unusably slow. This commit removes travis and puts basic ci in place via github actions. Testing against J9 is lost, as is testing against different maven versions. --- .github/workflows/ci.yml | 40 ++++++++++++++++++++++++++++++++++++++ .travis.yml | 42 ---------------------------------------- README.md | 1 + 3 files changed, 41 insertions(+), 42 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..857ffc71a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,40 @@ +name: CI +on: + push: + branches: + - 'master' + pull_request: + branches-ignore: + - 'release' +jobs: + supported-jdk: + name: ${{ matrix.title }} + continue-on-error: false + strategy: + fail-fast: false + matrix: + include: + - title: "JDK 8" + java: 8 + - title: "JDK 11" + java: 11 + - title: "JDK 15" + java: 15 + runs-on: ubuntu-latest + steps: + - name: 'Checkout from Git' + uses: actions/checkout@v2 + - name: 'Set up JDK ${{ matrix.java }}' + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + - name: 'Display JDK version' + run: java -version + - name: Cache local Maven repository + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-maven- + - name: 'Test' + run: mvn -B verify \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index dae3e37dd..000000000 --- a/.travis.yml +++ /dev/null @@ -1,42 +0,0 @@ -sudo: false - -language: java - -# Get latest install-jdk.sh script -before_install: - - wget https://github.com/sormuras/bach/raw/master/install-jdk.sh - -env: - global: - # taken first download mirror from http://maven.apache.org/ - - BASEURL=http://mirror.softaculous.com/apache/maven/maven-3/VERSION/binaries/apache-maven-VERSION-bin.tar.gz - - FILE=apache-maven-VERSION-bin.tar.gz - - DIR=apache-maven-VERSION/bin - -matrix: - include: - - jdk: openjdk8 - env: MAVEN=3.5.4 - - - jdk: openjdk9 - env: MAVEN=3.5.4 - - - jdk: openjdk11 - env: MAVEN=3.5.4 - - - jdk: openjdk12 - env: MAVEN=3.5.4 - - - env: JDK=14 MAVEN=3.6.3 - install: . ./install-jdk.sh --feature 14 - - - env: JDK='OpenJ9 11' MAVEN=3.6.3 - install: . ./install-jdk.sh --url "https://api.adoptopenjdk.net/v2/binary/releases/openjdk11?openjdk_impl=openj9&os=linux&arch=x64&release=latest&type=jdk&heap_size=normal" - -script: - - wget $(echo -n $BASEURL | sed -e 's#VERSION#'$MAVEN'#g') - - tar -xvzf $(echo -n $FILE | sed -e 's#VERSION#'$MAVEN'#') - - export PATH=$(echo -n $DIR | sed -e 's#VERSION#'$MAVEN'#'):$PATH - - java -version - - mvn -version - - mvn clean install diff --git a/README.md b/README.md index d8e228bb4..f3491d39d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.pitest/pitest/badge.svg?style=flat)](https://maven-badges.herokuapp.com/maven-central/org.pitest/pitest) +![Build Statis](https://github.com/hcoles/pitest/workflows/CI/badge.svg?branch=master) [![Build Status](https://travis-ci.org/hcoles/pitest.png?branch=master)](https://travis-ci.org/hcoles/pitest) [![Build Status](https://dev.azure.com/henrycoles/pitest/_apis/build/status/hcoles.pitest?branchName=master)](https://dev.azure.com/henrycoles/pitest/_build/latest?definitionId=3&branchName=master) From 2bbc6dcfb98f393bc4052ea5aa09aea37fa29f2a Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Fri, 11 Dec 2020 13:04:10 +0000 Subject: [PATCH 06/25] Remove java 8 linux build from azure pipelines Java 8 on linux is already covered by github actions, re-running on azure providse no additional benefit. --- azure-pipelines.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c17310a53..faaf359ee 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -3,8 +3,6 @@ trigger: strategy: matrix: - linux: - imageName: 'Ubuntu-16.04' mac: imageName: 'macos-10.14' windows: From 6e64eb0102fb761fefd6f256782349c264894bc4 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Fri, 11 Dec 2020 13:46:25 +0000 Subject: [PATCH 07/25] remove travis badge --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index f3491d39d..5296543cd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.pitest/pitest/badge.svg?style=flat)](https://maven-badges.herokuapp.com/maven-central/org.pitest/pitest) ![Build Statis](https://github.com/hcoles/pitest/workflows/CI/badge.svg?branch=master) -[![Build Status](https://travis-ci.org/hcoles/pitest.png?branch=master)](https://travis-ci.org/hcoles/pitest) [![Build Status](https://dev.azure.com/henrycoles/pitest/_apis/build/status/hcoles.pitest?branchName=master)](https://dev.azure.com/henrycoles/pitest/_build/latest?definitionId=3&branchName=master) Pitest (aka PIT) is a state of the art mutation testing system for Java and the JVM. From b19db13c25356233584395915b45c4a4a5f1a6e5 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Fri, 18 Dec 2020 16:00:44 +0000 Subject: [PATCH 08/25] Extend feature system to work with listeners --- .../mutationtest/ListenerArguments.java | 34 ++++++++++- .../MutationResultListenerFactory.java | 13 ++++- .../build/CompoundInterceptorFactory.java | 15 ++--- .../config/CompoundListenerFactory.java | 39 ++++++++----- .../mutationtest/config/PluginServices.java | 19 +++++-- .../mutationtest/config/SettingsFactory.java | 56 +++++++++++++------ .../mutationtest/tooling/EntryPoint.java | 16 +++--- .../config/CompoundListenerFactoryTest.java | 32 +++++++---- .../config/PluginServicesTest.java | 17 ++++-- .../config/SettingsFactoryTest.java | 34 +++++++---- .../report/html/HtmlReportFactory.java | 5 +- .../org/pitest/plugin/FeatureSelector.java | 8 +-- .../pitest/plugin/FeatureSelectorTest.java | 16 ++---- 13 files changed, 204 insertions(+), 100 deletions(-) diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java b/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java index 3ded8afc9..146974933 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java @@ -3,8 +3,11 @@ import org.pitest.coverage.CoverageDatabase; import org.pitest.mutationtest.config.ReportOptions; import org.pitest.mutationtest.engine.MutationEngine; +import org.pitest.plugin.FeatureSetting; import org.pitest.util.ResultOutputStrategy; +import java.util.Optional; + /** * Data passed to the listener MutationResultListener factories for use when * constructing listeners. @@ -18,6 +21,7 @@ public class ListenerArguments { private final MutationEngine engine; private final boolean fullMutationMatrix; private final ReportOptions data; + private final FeatureSetting setting; public ListenerArguments(ResultOutputStrategy outputStrategy, CoverageDatabase coverage, @@ -25,7 +29,18 @@ public ListenerArguments(ResultOutputStrategy outputStrategy, MutationEngine engine, long startTime, boolean fullMutationMatrix, - ReportOptions data) { + ReportOptions data) { + this(outputStrategy, coverage, locator, engine, startTime, fullMutationMatrix, data, null); + } + + ListenerArguments(ResultOutputStrategy outputStrategy, + CoverageDatabase coverage, + SourceLocator locator, + MutationEngine engine, + long startTime, + boolean fullMutationMatrix, + ReportOptions data, + FeatureSetting setting) { this.outputStrategy = outputStrategy; this.coverage = coverage; this.locator = locator; @@ -33,6 +48,7 @@ public ListenerArguments(ResultOutputStrategy outputStrategy, this.engine = engine; this.fullMutationMatrix = fullMutationMatrix; this.data = data; + this.setting = setting; } public ResultOutputStrategy getOutputStrategy() { @@ -62,4 +78,20 @@ public boolean isFullMutationMatrix() { public ReportOptions data() { return data; } + + public Optional settings() { + return Optional.ofNullable(setting); + } + + public ListenerArguments withSetting(FeatureSetting setting) { + return new ListenerArguments(outputStrategy, + coverage, + locator, + engine, + startTime, + fullMutationMatrix, + data, + setting); + } + } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/MutationResultListenerFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/MutationResultListenerFactory.java index 4251c4364..9b73aaf48 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/MutationResultListenerFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/MutationResultListenerFactory.java @@ -15,14 +15,23 @@ package org.pitest.mutationtest; +import org.pitest.plugin.Feature; +import org.pitest.plugin.ProvidesFeature; +import org.pitest.plugin.ToolClasspathPlugin; + import java.util.Properties; -import org.pitest.plugin.ToolClasspathPlugin; +public interface MutationResultListenerFactory extends ToolClasspathPlugin, ProvidesFeature { -public interface MutationResultListenerFactory extends ToolClasspathPlugin { + Feature LEGACY_MODE = Feature.named("_internal_activate_by_output_string") + .withOnByDefault(true); MutationResultListener getListener(Properties props, ListenerArguments args); String name(); + default Feature provides() { + return LEGACY_MODE; + } + } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/build/CompoundInterceptorFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/build/CompoundInterceptorFactory.java index 463b2c8bc..6b3755bad 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/build/CompoundInterceptorFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/build/CompoundInterceptorFactory.java @@ -1,15 +1,15 @@ package org.pitest.mutationtest.build; -import java.util.Collection; -import java.util.List; -import java.util.function.Function; - import org.pitest.classinfo.ClassByteArraySource; -import org.pitest.functional.FCollection; import org.pitest.mutationtest.config.ReportOptions; import org.pitest.plugin.FeatureSelector; import org.pitest.plugin.FeatureSetting; +import java.util.Collection; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + public class CompoundInterceptorFactory { private final FeatureSelector features; @@ -22,8 +22,9 @@ public CompoundInterceptorFactory(List features, public MutationInterceptor createInterceptor( ReportOptions data, ClassByteArraySource source) { - final List interceptors = FCollection.map(this.features.getActiveFeatures(), - toInterceptor(this.features, data, source)); + final List interceptors = this.features.getActiveFeatures().stream() + .map(toInterceptor(this.features, data, source)) + .collect(Collectors.toList()); return new CompoundMutationInterceptor(interceptors); } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/config/CompoundListenerFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/config/CompoundListenerFactory.java index dc17d11c7..c0f2f6072 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/config/CompoundListenerFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/config/CompoundListenerFactory.java @@ -14,33 +14,35 @@ */ package org.pitest.mutationtest.config; -import java.util.Properties; -import java.util.function.Function; - -import org.pitest.functional.FCollection; import org.pitest.mutationtest.ListenerArguments; import org.pitest.mutationtest.MutationResultListener; import org.pitest.mutationtest.MutationResultListenerFactory; +import org.pitest.plugin.Feature; +import org.pitest.plugin.FeatureSelector; +import org.pitest.plugin.FeatureSetting; + +import java.util.Collection; +import java.util.List; +import java.util.Properties; +import java.util.function.Function; +import java.util.stream.Collectors; public class CompoundListenerFactory implements MutationResultListenerFactory { - private final Iterable children; + private final FeatureSelector features; - public CompoundListenerFactory( - final Iterable children) { - this.children = children; + public CompoundListenerFactory(List features, final Collection children) { + this.features = new FeatureSelector<>(features, children); } @Override public MutationResultListener getListener(final Properties props, final ListenerArguments args) { - return new CompoundTestListener(FCollection.map(this.children, - factoryToListener(props, args))); - } + final List listeners = this.features.getActiveFeatures().stream() + .map(toListener(props, args)) + .collect(Collectors.toList()); - private Function factoryToListener( - final Properties props, final ListenerArguments args) { - return a -> a.getListener(props, args); + return new CompoundTestListener(listeners); } @Override @@ -53,4 +55,13 @@ public String description() { throw new UnsupportedOperationException(); } + @Override + public Feature provides() { + throw new UnsupportedOperationException(); + } + + private Function toListener(Properties props, + ListenerArguments args) { + return a -> a.getListener(props, args.withSetting(features.getSettingForFeature(a.provides().name()))); + } } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/config/PluginServices.java b/pitest-entry/src/main/java/org/pitest/mutationtest/config/PluginServices.java index d91b65766..b3febb8d2 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/config/PluginServices.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/config/PluginServices.java @@ -1,20 +1,22 @@ package org.pitest.mutationtest.config; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - import org.pitest.mutationtest.MutationEngineFactory; import org.pitest.mutationtest.MutationResultListenerFactory; import org.pitest.mutationtest.build.MutationGrouperFactory; import org.pitest.mutationtest.build.MutationInterceptorFactory; import org.pitest.mutationtest.build.TestPrioritiserFactory; import org.pitest.plugin.ClientClasspathPlugin; +import org.pitest.plugin.ProvidesFeature; import org.pitest.plugin.ToolClasspathPlugin; import org.pitest.testapi.TestPluginFactory; import org.pitest.util.IsolationUtils; import org.pitest.util.ServiceLoader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + public class PluginServices { private final ClassLoader loader; @@ -33,7 +35,7 @@ public static PluginServices makeForContextLoader() { * * @return list of plugins */ - public Iterable findToolClasspathPlugins() { + public Collection findToolClasspathPlugins() { final List l = new ArrayList<>(); l.addAll(findListeners()); l.addAll(findGroupers()); @@ -81,4 +83,11 @@ public Collection findInterceptors() { return ServiceLoader.load(MutationInterceptorFactory.class, this.loader); } + public Collection findFeatures() { + return findToolClasspathPlugins().stream() + .filter(p -> p instanceof ProvidesFeature) + .map(p -> ProvidesFeature.class.cast(p)) + .collect(Collectors.toList()); + } + } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/config/SettingsFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/config/SettingsFactory.java index 3e86bb554..6454c94f6 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/config/SettingsFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/config/SettingsFactory.java @@ -1,14 +1,5 @@ package org.pitest.mutationtest.config; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; - import org.pitest.coverage.CoverageExporter; import org.pitest.coverage.execute.CoverageOptions; import org.pitest.coverage.export.DefaultCoverageExporter; @@ -33,6 +24,17 @@ import org.pitest.util.PitError; import org.pitest.util.ResultOutputStrategy; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + public class SettingsFactory { private final ReportOptions options; @@ -67,7 +69,8 @@ public MutationEngineFactory createEngine() { } public MutationResultListenerFactory createListener() { - return new CompoundListenerFactory(findListeners()); + final FeatureParser parser = new FeatureParser(); + return new CompoundListenerFactory(parser.parseFeatures(this.options.getFeatures()), findListeners()); } public JavaExecutableLocator getJavaExecutable() { @@ -86,7 +89,7 @@ public MutationGrouperFactory getMutationGrouper() { public void describeFeatures(Consumer enabled, Consumer disabled) { final FeatureParser parser = new FeatureParser(); - final Collection available = new ArrayList<>(this.plugins.findInterceptors()); + final Collection available = new ArrayList<>(this.plugins.findFeatures()); final List settings = parser.parseFeatures(this.options.getFeatures()); final FeatureSelector selector = new FeatureSelector<>(settings, available); @@ -104,9 +107,22 @@ public void describeFeatures(Consumer enabled, Consumer disabl .sorted(byName()) .filter(f -> !enabledFeatures.contains(f)) .forEach(disabled); - } + public void checkRequestedFeatures() { + FeatureParser parser = new FeatureParser(); + Set available = this.plugins.findFeatures().stream() + .map(f -> f.provides().name()) + .collect(Collectors.toSet()); + + Optional unknown = parser.parseFeatures(this.options.getFeatures()).stream() + .filter(f -> !available.contains(f.feature())) + .findAny(); + + unknown.ifPresent(setting -> { + throw new IllegalArgumentException("Unknown feature " + setting.feature()); + }); + } public TestPrioritiserFactory getTestPrioritiser() { final Collection testPickers = this.plugins @@ -128,12 +144,7 @@ public CompoundInterceptorFactory getInterceptor() { return new CompoundInterceptorFactory(parser.parseFeatures(this.options.getFeatures()), new ArrayList<>(interceptors)); } - private static Predicate nameMatches( - final Iterable outputFormats) { - return a -> FCollection.contains(outputFormats, equalsIgnoreCase(a.name())); - } - - private Iterable findListeners() { + private Collection findListeners() { final Iterable listeners = this.plugins .findListeners(); final Collection matches = FCollection @@ -145,6 +156,15 @@ private Iterable findListeners() { return matches; } + private static Predicate nameMatches( + final Iterable outputFormats) { + // plugins can be either activated here by name + // or later via the feature mechanism + return a -> FCollection.contains(outputFormats, equalsIgnoreCase(a.name())) + || !a.provides().equals(MutationResultListenerFactory.LEGACY_MODE); + } + + private static Predicate equalsIgnoreCase(final String other) { return a -> a.equalsIgnoreCase(other); } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/EntryPoint.java b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/EntryPoint.java index fce5e7f31..23ac0c60e 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/EntryPoint.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/EntryPoint.java @@ -1,10 +1,5 @@ package org.pitest.mutationtest.tooling; -import java.io.File; -import java.io.IOException; -import java.io.Reader; -import java.util.Map; - import org.pitest.classpath.ClassPath; import org.pitest.classpath.ClassPathByteArraySource; import org.pitest.classpath.CodeSource; @@ -12,9 +7,6 @@ import org.pitest.coverage.CoverageGenerator; import org.pitest.coverage.execute.CoverageOptions; import org.pitest.coverage.execute.DefaultCoverageGenerator; -import java.util.Optional; -import java.util.function.Consumer; - import org.pitest.mutationtest.HistoryStore; import org.pitest.mutationtest.MutationResultListenerFactory; import org.pitest.mutationtest.config.PluginServices; @@ -31,6 +23,13 @@ import org.pitest.util.ResultOutputStrategy; import org.pitest.util.Timings; +import java.io.File; +import java.io.IOException; +import java.io.Reader; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; + public class EntryPoint { /** @@ -72,6 +71,7 @@ public AnalysisResult execute(File baseDir, ReportOptions data, settings.describeFeatures(asInfo("+"), asInfo("-")); Log.getLogger().info("---------------------------------------------------------------------------"); } + settings.checkRequestedFeatures(); checkMatrixMode(data); diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/config/CompoundListenerFactoryTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/config/CompoundListenerFactoryTest.java index 7ca3321c4..a11f50a1f 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/config/CompoundListenerFactoryTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/config/CompoundListenerFactoryTest.java @@ -14,15 +14,6 @@ */ package org.pitest.mutationtest.config; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.Arrays; -import java.util.Properties; - import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -31,6 +22,16 @@ import org.pitest.mutationtest.MutationResultListener; import org.pitest.mutationtest.MutationResultListenerFactory; +import java.util.Properties; + +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + public class CompoundListenerFactoryTest { private CompoundListenerFactory testee; @@ -44,7 +45,11 @@ public class CompoundListenerFactoryTest { @Before public void setUp() { MockitoAnnotations.initMocks(this); - this.testee = new CompoundListenerFactory(Arrays.asList(this.firstChild, + + when(firstChild.provides()).thenReturn(MutationResultListenerFactory.LEGACY_MODE); + when(secondChild.provides()).thenReturn(MutationResultListenerFactory.LEGACY_MODE); + + this.testee = new CompoundListenerFactory(emptyList(),asList(this.firstChild, this.secondChild)); } @@ -58,9 +63,14 @@ public void shouldCreateACombinedListenerForAllChildFactories() { when( this.secondChild.getListener(any(Properties.class), any(ListenerArguments.class))).thenReturn(listenerTwo); - this.testee.getListener(null, null).runStart(); + this.testee.getListener(null, someArgs()).runStart(); verify(listenerOne, times(1)).runStart(); verify(listenerTwo, times(1)).runStart(); } + private ListenerArguments someArgs() { + return new ListenerArguments(null, null, null, null, + 0, false, null); + } + } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/config/PluginServicesTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/config/PluginServicesTest.java index 469a62178..69baf5e71 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/config/PluginServicesTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/config/PluginServicesTest.java @@ -1,15 +1,18 @@ package org.pitest.mutationtest.config; -import static org.junit.Assert.assertTrue; - -import java.util.function.Predicate; - import org.junit.Test; import org.pitest.functional.FCollection; +import org.pitest.mutationtest.MutationResultListenerFactory; +import org.pitest.mutationtest.build.MutationInterceptorFactory; import org.pitest.mutationtest.engine.gregor.config.GregorEngineFactory; import org.pitest.mutationtest.filter.LimitNumberOfMutationsPerClassFilterFactory; import org.pitest.mutationtest.report.csv.CSVReportFactory; +import java.util.function.Predicate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; + public class PluginServicesTest { private final PluginServices testee = PluginServices.makeForContextLoader(); @@ -32,6 +35,12 @@ public void shouldListDefaultMutationFilterAsToolClasspathPlugin() { theClass(LimitNumberOfMutationsPerClassFilterFactory.class))); } + @Test + public void shouldListAllTypesOfFeature() { + assertThat(testee.findFeatures()).hasAtLeastOneElementOfType(MutationInterceptorFactory.class); + assertThat(testee.findFeatures()).hasAtLeastOneElementOfType(MutationResultListenerFactory.class); + } + private static Predicate theClass(final Class clss) { return a -> a.getClass().equals(clss); } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/config/SettingsFactoryTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/config/SettingsFactoryTest.java index 2153503fd..cdd540913 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/config/SettingsFactoryTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/config/SettingsFactoryTest.java @@ -1,17 +1,5 @@ package org.pitest.mutationtest.config; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; - -import java.io.File; -import java.util.Arrays; -import java.util.Collections; -import java.util.function.Consumer; - import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; @@ -22,6 +10,19 @@ import org.pitest.testapi.TestGroupConfig; import org.pitest.util.PitError; +import java.io.File; +import java.util.Arrays; +import java.util.Collections; +import java.util.function.Consumer; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + public class SettingsFactoryTest { private final ReportOptions options = new ReportOptions(); @@ -127,4 +128,13 @@ public void shouldDescribeDisabledFeatures() { verify(disabled).accept(Feature.named("FSTATINIT")); } + @Test + public void shouldErrorWhenUnkownFeatureRequested() { + this.options.setFeatures(Arrays.asList("+UNKOWN")); + + assertThatCode( () ->this.testee.checkRequestedFeatures()) + .hasMessageContaining(("UNKOWN")); + + } + } diff --git a/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/HtmlReportFactory.java b/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/HtmlReportFactory.java index f7d2b13b3..4394869a4 100644 --- a/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/HtmlReportFactory.java +++ b/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/HtmlReportFactory.java @@ -15,12 +15,12 @@ package org.pitest.mutationtest.report.html; -import java.util.Properties; - import org.pitest.mutationtest.ListenerArguments; import org.pitest.mutationtest.MutationResultListener; import org.pitest.mutationtest.MutationResultListenerFactory; +import java.util.Properties; + public class HtmlReportFactory implements MutationResultListenerFactory { @Override @@ -40,4 +40,5 @@ public String name() { public String description() { return "Default html report plugin"; } + } diff --git a/pitest/src/main/java/org/pitest/plugin/FeatureSelector.java b/pitest/src/main/java/org/pitest/plugin/FeatureSelector.java index d9bee99ee..ada938722 100644 --- a/pitest/src/main/java/org/pitest/plugin/FeatureSelector.java +++ b/pitest/src/main/java/org/pitest/plugin/FeatureSelector.java @@ -1,5 +1,7 @@ package org.pitest.plugin; +import org.pitest.functional.FCollection; + import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -7,8 +9,6 @@ import java.util.function.Function; import java.util.function.Predicate; -import org.pitest.functional.FCollection; - public class FeatureSelector { private final Map> settings; @@ -32,7 +32,7 @@ public FeatureSetting getSettingForFeature(String feature) { return conf; } - public List selectFeatures(List features, Collection filters) { + private List selectFeatures(List features, Collection filters) { final List factories = new ArrayList<>(filters); final Map> featureMap = FCollection.bucket(factories, byFeatureName()); @@ -41,7 +41,7 @@ public List selectFeatures(List features, Collection filte for ( final FeatureSetting each : features ) { final Collection providers = featureMap.get(each.feature()); if ((providers == null) || providers.isEmpty()) { - throw new IllegalArgumentException("Pitest and its installed plugins do not recognise the feature " + each.feature()); + continue; } if (each.addsFeature()) { diff --git a/pitest/src/test/java/org/pitest/plugin/FeatureSelectorTest.java b/pitest/src/test/java/org/pitest/plugin/FeatureSelectorTest.java index 285b34d6d..54c082a37 100644 --- a/pitest/src/test/java/org/pitest/plugin/FeatureSelectorTest.java +++ b/pitest/src/test/java/org/pitest/plugin/FeatureSelectorTest.java @@ -1,15 +1,15 @@ package org.pitest.plugin; -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; +import static org.assertj.core.api.Assertions.assertThat; public class FeatureSelectorTest { @@ -52,14 +52,6 @@ public void shouldDisableFeaturesWhenRequested() { assertThat(this.testee.getActiveFeatures()).isEmpty(); } - @Test - public void shouldThrowErrorWhenConfigForUnknownFeatureProvided() { - final FeatureSetting wrong = new FeatureSetting("unknown", ToggleStatus.DEACTIVATE, new HashMap>()); - - this.thrown.expect(IllegalArgumentException.class); - this.testee = new FeatureSelector<>(Arrays.asList(wrong), features(this.onByDefault)); - } - @Test public void shouldProvideConfigurationForFeatureWhenProvided() { final FeatureSetting fooConfig = new FeatureSetting("foo", ToggleStatus.DEACTIVATE, new HashMap>()); From 8e300e8959c2e38fe2660298526304d6f935ade8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Dec 2020 10:30:40 +0000 Subject: [PATCH 09/25] Bump junit Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1) Signed-off-by: dependabot[bot] --- .../src/test/resources/pit-powermock/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pitest-maven-verification/src/test/resources/pit-powermock/pom.xml b/pitest-maven-verification/src/test/resources/pit-powermock/pom.xml index e125e3c09..9734b81d1 100644 --- a/pitest-maven-verification/src/test/resources/pit-powermock/pom.xml +++ b/pitest-maven-verification/src/test/resources/pit-powermock/pom.xml @@ -69,7 +69,7 @@ - 4.12 + 4.13.1 1.7.3 From 21a5bafaed3f50be65d45a1596e94e7612eefe74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Dec 2020 10:30:39 +0000 Subject: [PATCH 10/25] Bump junit Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1) Signed-off-by: dependabot[bot] --- .../src/test/resources/pit-263-yatspec/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pitest-maven-verification/src/test/resources/pit-263-yatspec/pom.xml b/pitest-maven-verification/src/test/resources/pit-263-yatspec/pom.xml index b273c1dc8..f2768c584 100644 --- a/pitest-maven-verification/src/test/resources/pit-263-yatspec/pom.xml +++ b/pitest-maven-verification/src/test/resources/pit-263-yatspec/pom.xml @@ -47,7 +47,7 @@ junit junit - 4.12 + 4.13.1 test From fbe99316dc9159b206c6fa1775f112dc579834fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Dec 2020 10:30:39 +0000 Subject: [PATCH 11/25] Bump junit Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1) Signed-off-by: dependabot[bot] --- .../src/test/resources/pit-junit-categories/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pitest-maven-verification/src/test/resources/pit-junit-categories/pom.xml b/pitest-maven-verification/src/test/resources/pit-junit-categories/pom.xml index 9938e8d09..8060a837e 100644 --- a/pitest-maven-verification/src/test/resources/pit-junit-categories/pom.xml +++ b/pitest-maven-verification/src/test/resources/pit-junit-categories/pom.xml @@ -10,7 +10,7 @@ junit junit - 4.12 + 4.13.1 test From 3399643eac9d00a4268f2c8102e1bb82586569a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Dec 2020 10:30:39 +0000 Subject: [PATCH 12/25] Bump junit Bumps [junit](https://github.com/junit-team/junit4) from 4.8.1 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.13.1.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.8.1...r4.13.1) Signed-off-by: dependabot[bot] --- .../src/test/resources/pit-deterministic-coverage/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pitest-maven-verification/src/test/resources/pit-deterministic-coverage/pom.xml b/pitest-maven-verification/src/test/resources/pit-deterministic-coverage/pom.xml index ca60c0566..6a77356df 100644 --- a/pitest-maven-verification/src/test/resources/pit-deterministic-coverage/pom.xml +++ b/pitest-maven-verification/src/test/resources/pit-deterministic-coverage/pom.xml @@ -41,7 +41,7 @@ - 4.8.1 + 4.13.1 From 6f6f48ac01221995ef42065cb0fcce5cceabc180 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Dec 2020 10:30:38 +0000 Subject: [PATCH 13/25] Bump junit Bumps [junit](https://github.com/junit-team/junit4) from 4.8.1 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.13.1.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.8.1...r4.13.1) Signed-off-by: dependabot[bot] --- .../pit-33-setUserDir/pit-33-setUserDir-subModule/pom.xml | 2 +- .../src/test/resources/pit-33-setUserDir/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pitest-maven-verification/src/test/resources/pit-33-setUserDir/pit-33-setUserDir-subModule/pom.xml b/pitest-maven-verification/src/test/resources/pit-33-setUserDir/pit-33-setUserDir-subModule/pom.xml index bf34832ad..c941dae55 100644 --- a/pitest-maven-verification/src/test/resources/pit-33-setUserDir/pit-33-setUserDir-subModule/pom.xml +++ b/pitest-maven-verification/src/test/resources/pit-33-setUserDir/pit-33-setUserDir-subModule/pom.xml @@ -36,6 +36,6 @@ - 4.8.1 + 4.13.1 \ No newline at end of file diff --git a/pitest-maven-verification/src/test/resources/pit-33-setUserDir/pom.xml b/pitest-maven-verification/src/test/resources/pit-33-setUserDir/pom.xml index 69a28a7bc..f51907c7a 100644 --- a/pitest-maven-verification/src/test/resources/pit-33-setUserDir/pom.xml +++ b/pitest-maven-verification/src/test/resources/pit-33-setUserDir/pom.xml @@ -39,7 +39,7 @@ - 4.8.1 + 4.13.1 pit-33-setUserDir-subModule From 6e3afcbc959995f4791e953b55d29a5d3cd4e48c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Dec 2020 10:30:38 +0000 Subject: [PATCH 14/25] Bump junit Bumps [junit](https://github.com/junit-team/junit4) from 4.8.2 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.13.1.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.8.2...r4.13.1) Signed-off-by: dependabot[bot] --- .../src/test/resources/pit-158-coverage/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pitest-maven-verification/src/test/resources/pit-158-coverage/pom.xml b/pitest-maven-verification/src/test/resources/pit-158-coverage/pom.xml index c6e1912e7..62b649736 100644 --- a/pitest-maven-verification/src/test/resources/pit-158-coverage/pom.xml +++ b/pitest-maven-verification/src/test/resources/pit-158-coverage/pom.xml @@ -22,7 +22,7 @@ junit junit - 4.8.2 + 4.13.1 From 6d58df1b4421e61d14b1e240ad9f9dd02b716f03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Dec 2020 10:30:38 +0000 Subject: [PATCH 15/25] Bump junit Bumps [junit](https://github.com/junit-team/junit4) from 4.8.2 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.13.1.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.8.2...r4.13.1) Signed-off-by: dependabot[bot] --- .../src/test/resources/pit-findOccupiedTestPackages/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pitest-maven-verification/src/test/resources/pit-findOccupiedTestPackages/pom.xml b/pitest-maven-verification/src/test/resources/pit-findOccupiedTestPackages/pom.xml index 7877d7c93..177a3fdc0 100644 --- a/pitest-maven-verification/src/test/resources/pit-findOccupiedTestPackages/pom.xml +++ b/pitest-maven-verification/src/test/resources/pit-findOccupiedTestPackages/pom.xml @@ -16,7 +16,7 @@ junit junit - 4.8.2 + 4.13.1 From 7bfc1d0966843fcd2f0f3cd0cd45668cb5c62d9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Dec 2020 16:42:55 +0000 Subject: [PATCH 16/25] Bump xstream from 1.4.8 to 1.4.15 in /pitest-entry Bumps [xstream](https://github.com/x-stream/xstream) from 1.4.8 to 1.4.15. - [Release notes](https://github.com/x-stream/xstream/releases) - [Commits](https://github.com/x-stream/xstream/commits) Signed-off-by: dependabot[bot] --- pitest-entry/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pitest-entry/pom.xml b/pitest-entry/pom.xml index 126e499a9..d7c644659 100644 --- a/pitest-entry/pom.xml +++ b/pitest-entry/pom.xml @@ -143,7 +143,7 @@ com.thoughtworks.xstream xstream - 1.4.8 + 1.4.15 test From 61323265cefd33ef162ecbf8731d00dc50273186 Mon Sep 17 00:00:00 2001 From: Alexey Elin Date: Fri, 25 Dec 2020 23:31:11 +0300 Subject: [PATCH 17/25] add LambdaParameterName module into checkstyle --- pitest-build-config/src/main/resources/pitest/checkstyle.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pitest-build-config/src/main/resources/pitest/checkstyle.xml b/pitest-build-config/src/main/resources/pitest/checkstyle.xml index f174b5a15..9effbb976 100644 --- a/pitest-build-config/src/main/resources/pitest/checkstyle.xml +++ b/pitest-build-config/src/main/resources/pitest/checkstyle.xml @@ -45,6 +45,7 @@ + From e34ca99d28be2b569c950f710ebebfef21907e91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Dec 2020 16:42:42 +0000 Subject: [PATCH 18/25] Bump xstream from 1.4.8 to 1.4.15 in /pitest Bumps [xstream](https://github.com/x-stream/xstream) from 1.4.8 to 1.4.15. - [Release notes](https://github.com/x-stream/xstream/releases) - [Commits](https://github.com/x-stream/xstream/commits) Signed-off-by: dependabot[bot] --- pitest/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pitest/pom.xml b/pitest/pom.xml index 4880effc9..24af74b71 100644 --- a/pitest/pom.xml +++ b/pitest/pom.xml @@ -226,7 +226,7 @@ com.thoughtworks.xstream xstream - 1.4.8 + 1.4.15 test From 88bd740957362ef07b7f37d57c9f9484d241431c Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Wed, 30 Dec 2020 10:14:10 +0000 Subject: [PATCH 19/25] make feature names case insensitive --- .../java/org/pitest/plugin/FeatureSelector.java | 4 ++-- .../org/pitest/plugin/FeatureSelectorTest.java | 14 +++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/pitest/src/main/java/org/pitest/plugin/FeatureSelector.java b/pitest/src/main/java/org/pitest/plugin/FeatureSelector.java index ada938722..9a0b3c316 100644 --- a/pitest/src/main/java/org/pitest/plugin/FeatureSelector.java +++ b/pitest/src/main/java/org/pitest/plugin/FeatureSelector.java @@ -25,7 +25,7 @@ public List getActiveFeatures() { public FeatureSetting getSettingForFeature(String feature) { FeatureSetting conf = null; - final Collection groupedSettings = this.settings.get(feature); + final Collection groupedSettings = this.settings.get(feature.toLowerCase()); if (groupedSettings != null) { conf = groupedSettings.iterator().next(); } @@ -65,7 +65,7 @@ private Function byFeatureName() { } private Function byFeature() { - return a -> a.feature(); + return a -> a.feature().toLowerCase(); } } \ No newline at end of file diff --git a/pitest/src/test/java/org/pitest/plugin/FeatureSelectorTest.java b/pitest/src/test/java/org/pitest/plugin/FeatureSelectorTest.java index 54c082a37..3c6de733a 100644 --- a/pitest/src/test/java/org/pitest/plugin/FeatureSelectorTest.java +++ b/pitest/src/test/java/org/pitest/plugin/FeatureSelectorTest.java @@ -38,7 +38,7 @@ public void shouldSelectFeaturesThatAreOffByDefault() { @Test public void shouldEnableFeaturesWhenRequested() { - final FeatureSetting enableBar = new FeatureSetting("bar", ToggleStatus.ACTIVATE, new HashMap>()); + final FeatureSetting enableBar = new FeatureSetting("bar", ToggleStatus.ACTIVATE, new HashMap<>()); this.testee = new FeatureSelector<>(Arrays.asList(enableBar), features(this.onByDefault, this.offByDefault)); assertThat(this.testee.getActiveFeatures()).containsOnly(this.offByDefault, this.onByDefault); @@ -46,7 +46,7 @@ public void shouldEnableFeaturesWhenRequested() { @Test public void shouldDisableFeaturesWhenRequested() { - final FeatureSetting disableFoo = new FeatureSetting("foo", ToggleStatus.DEACTIVATE, new HashMap>()); + final FeatureSetting disableFoo = new FeatureSetting("foo", ToggleStatus.DEACTIVATE, new HashMap<>()); this.testee = new FeatureSelector<>(Arrays.asList(disableFoo), features(this.onByDefault)); assertThat(this.testee.getActiveFeatures()).isEmpty(); @@ -54,13 +54,21 @@ public void shouldDisableFeaturesWhenRequested() { @Test public void shouldProvideConfigurationForFeatureWhenProvided() { - final FeatureSetting fooConfig = new FeatureSetting("foo", ToggleStatus.DEACTIVATE, new HashMap>()); + final FeatureSetting fooConfig = new FeatureSetting("foo", ToggleStatus.DEACTIVATE, new HashMap<>()); this.testee = new FeatureSelector<>(Arrays.asList(fooConfig), features(this.onByDefault)); assertThat(this.testee.getSettingForFeature("foo")).isEqualTo(fooConfig); assertThat(this.testee.getSettingForFeature("bar")).isNull(); } + @Test + public void featureNamesAreCaseInsensitive() { + final FeatureSetting fooConfig = new FeatureSetting("foo", ToggleStatus.DEACTIVATE, new HashMap<>()); + this.testee = new FeatureSelector<>(Arrays.asList(fooConfig), features(this.onByDefault)); + + assertThat(this.testee.getSettingForFeature("FOO")).isEqualTo(fooConfig); + } + private List noSettings() { return Collections.emptyList(); } From 28c26c52b3aa8b8f7c77b4dfdf6ede08ea0c2b37 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Wed, 30 Dec 2020 12:44:14 +0000 Subject: [PATCH 20/25] failing test case for #771 --- .gitignore | 2 + .../src/test/java/org/pitest/PitMojoIT.java | 35 +++++++----- .../pit-enum-constructor-npe/pom.xml | 54 +++++++++++++++++++ .../src/main/java/com/example/Test.java | 7 +++ .../test/com/example/NestedClassTest.java | 15 ++++++ 5 files changed, 101 insertions(+), 12 deletions(-) create mode 100644 pitest-maven-verification/src/test/resources/pit-enum-constructor-npe/pom.xml create mode 100644 pitest-maven-verification/src/test/resources/pit-enum-constructor-npe/src/main/java/com/example/Test.java create mode 100644 pitest-maven-verification/src/test/resources/pit-enum-constructor-npe/src/test/java/test/com/example/NestedClassTest.java diff --git a/.gitignore b/.gitignore index b0345ac09..e0d2b0856 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ target/ dependency-reduced-pom.xml .flattened-pom.xml */bin +.DS_Store + diff --git a/pitest-maven-verification/src/test/java/org/pitest/PitMojoIT.java b/pitest-maven-verification/src/test/java/org/pitest/PitMojoIT.java index bfdc8158f..1ccf8f2fd 100755 --- a/pitest-maven-verification/src/test/java/org/pitest/PitMojoIT.java +++ b/pitest-maven-verification/src/test/java/org/pitest/PitMojoIT.java @@ -15,18 +15,6 @@ */ package org.pitest; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeFalse; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - import org.apache.commons.io.FileUtils; import org.apache.maven.it.VerificationException; import org.apache.maven.it.Verifier; @@ -43,6 +31,18 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeFalse; + /** * @author Stefan Penndorf */ @@ -563,4 +563,15 @@ public void shouldFindOccupiedTestPackages() throws IOException, VerificationExc "DiscoveredClass.java"); } + @Test + public void shouldNotNullPointerWhenEnumInitiliazerNotCalled() throws IOException, VerificationException { + File testDir = prepare("/pit-enum-constructor-npe"); + verifier.executeGoal("test"); + verifier.executeGoal("org.pitest:pitest-maven:mutationCoverage"); + + String actual = readResults(testDir); + assertThat(actual).contains( + "DiscoveredClass.java"); + } + } diff --git a/pitest-maven-verification/src/test/resources/pit-enum-constructor-npe/pom.xml b/pitest-maven-verification/src/test/resources/pit-enum-constructor-npe/pom.xml new file mode 100644 index 000000000..d0cb3472c --- /dev/null +++ b/pitest-maven-verification/src/test/resources/pit-enum-constructor-npe/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + com.example + pitest-sample + 0.1-SNAPSHOT + pit #770 npe in constructor + + + UTF-8 + + + + + junit + junit + 4.13.1 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.4 + + 1.7 + 1.7 + + + + org.pitest + pitest-maven + ${pit.version} + + true + + XML + + false + true + + VOID_METHOD_CALLS + + + + + + + diff --git a/pitest-maven-verification/src/test/resources/pit-enum-constructor-npe/src/main/java/com/example/Test.java b/pitest-maven-verification/src/test/resources/pit-enum-constructor-npe/src/main/java/com/example/Test.java new file mode 100644 index 000000000..e101f84fd --- /dev/null +++ b/pitest-maven-verification/src/test/resources/pit-enum-constructor-npe/src/main/java/com/example/Test.java @@ -0,0 +1,7 @@ +package com.example; + +class Test { + public Test() { + System.out.println("I only exist so that pitest thinks there is something to mutate"); + } +} diff --git a/pitest-maven-verification/src/test/resources/pit-enum-constructor-npe/src/test/java/test/com/example/NestedClassTest.java b/pitest-maven-verification/src/test/resources/pit-enum-constructor-npe/src/test/java/test/com/example/NestedClassTest.java new file mode 100644 index 000000000..c4a3b8574 --- /dev/null +++ b/pitest-maven-verification/src/test/resources/pit-enum-constructor-npe/src/test/java/test/com/example/NestedClassTest.java @@ -0,0 +1,15 @@ +package com.example; + +import org.junit.Test; + +public class NestedClassTest { + public static enum MyEnum { + A { } + } + + @Test + public void test() throws ClassNotFoundException { + Class.forName("com.example.NestedClassTest$MyEnum$1"); + } +} + From 5decb6edb110445d6ef190666a308f672a348aa9 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Thu, 31 Dec 2020 12:50:03 +0000 Subject: [PATCH 21/25] Failing test for #770 and #746 Failing test to describe general issue behind coverage bugs - child classes are initialized after their parents, so coverage probe is not initialized when parent refers to child in a static initializer block. --- .../simple/ParentChildInitializationTest.java | 22 +++++++ .../execute/CoverageProcessSystemTest.java | 65 ++++++++++--------- 2 files changed, 55 insertions(+), 32 deletions(-) create mode 100644 pitest-entry/src/test/java/com/example/coverage/execute/samples/simple/ParentChildInitializationTest.java diff --git a/pitest-entry/src/test/java/com/example/coverage/execute/samples/simple/ParentChildInitializationTest.java b/pitest-entry/src/test/java/com/example/coverage/execute/samples/simple/ParentChildInitializationTest.java new file mode 100644 index 000000000..7de72f79a --- /dev/null +++ b/pitest-entry/src/test/java/com/example/coverage/execute/samples/simple/ParentChildInitializationTest.java @@ -0,0 +1,22 @@ +package com.example.coverage.execute.samples.simple; + +import org.junit.Test; + +public class ParentChildInitializationTest { + @Test + public void test() { + new TesteeChild(); + } +} + +class TesteeParent { + static TesteeChild child = new TesteeChild(); +} + +class TesteeChild extends TesteeParent { + final static Object f = "hello"; + + TesteeChild() { + System.out.println(f); + } +} diff --git a/pitest-entry/src/test/java/org/pitest/coverage/execute/CoverageProcessSystemTest.java b/pitest-entry/src/test/java/org/pitest/coverage/execute/CoverageProcessSystemTest.java index 1fe5a1729..d86c06204 100644 --- a/pitest-entry/src/test/java/org/pitest/coverage/execute/CoverageProcessSystemTest.java +++ b/pitest-entry/src/test/java/org/pitest/coverage/execute/CoverageProcessSystemTest.java @@ -7,6 +7,7 @@ import com.example.coverage.execute.samples.exceptions.ThrowsExceptionFromLargeMethodTestee; import com.example.coverage.execute.samples.exceptions.ThrowsExceptionInFinallyBlockTestee; import com.example.coverage.execute.samples.exceptions.ThrowsExceptionTestee; +import com.example.coverage.execute.samples.simple.ParentChildInitializationTest; import com.example.coverage.execute.samples.simple.Testee; import com.example.coverage.execute.samples.simple.Testee2; import com.example.coverage.execute.samples.simple.TesteeWithComplexConstructorsTest; @@ -57,8 +58,7 @@ public class CoverageProcessSystemTest { private final MethodName foo = MethodName.fromString("foo"); @Test - public void shouldRecordSomeCoverage() throws IOException, - InterruptedException, ExecutionException { + public void shouldRecordSomeCoverage() throws Exception { final List coverage = runCoverageForTest(TestsForMultiBlockCoverage.class); assertFalse(coverage.iterator().next().getCoverage().isEmpty()); } @@ -80,8 +80,7 @@ public void shouldCalculateCoverageForSingleBlockMethods() // } @Test - public void shouldCalculateCoverageFor3BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor3BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test3", 2); } @@ -122,22 +121,19 @@ public void shouldCalculateCoverageForBlockMethods() throws IOException, } @Test - public void shouldCalculateCoverageFor7BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor7BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test7", 2); } @Test - public void shouldCalculateCoverageFor8BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor8BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test8", 2); } @Test - public void shouldCalculateCoverageFor9BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor9BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test9", 2); } @@ -150,50 +146,44 @@ public void shouldCalculateCoverageFor10BlockMethods() throws IOException, } @Test - public void shouldCalculateCoverageFor11BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor11BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test11", 2); } @Test - public void shouldCalculateCoverageFor12BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor12BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test12", 2); } @Test - public void shouldCalculateCoverageFor13BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor13BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test13", 2); } @Test - public void shouldCalculateCoverageFor14BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor14BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test14", 2); } @Test - public void shouldCalculateCoverageFor15BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor15BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test15", 2); } @Test - public void shouldCalculateCoverageForLargeBlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageForLargeBlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "testMany", 2); } @Test public void shouldCalculateCoverageForAllRelevantClasses() - throws IOException, InterruptedException, ExecutionException { + throws Exception{ final List coveredClasses = runCoverageForTest(Tests.class); @@ -204,7 +194,7 @@ public void shouldCalculateCoverageForAllRelevantClasses() @Test public void shouldCalculateCoverageForSmallMethodThatThrowsException() - throws IOException, InterruptedException, ExecutionException { + throws Exception { final List coveredClasses = runCoverageForTest(TestsClassWithException.class); assertThat(coveredClasses).anyMatch(coverageFor(CoveredBeforeExceptionTestee.class)); @@ -222,7 +212,7 @@ public void shouldCalculateCoverageForSmallMethodThatThrowsException() @Test public void shouldCalculateCoverageForMethodThatThrowsExceptionWithFinallyBlock() - throws IOException, InterruptedException, ExecutionException { + throws Exception { final List coveredClasses = runCoverageForTest(TestThrowsExceptionInFinallyBlock.class); final ClassName clazz = ClassName @@ -237,7 +227,7 @@ public void shouldCalculateCoverageForMethodThatThrowsExceptionWithFinallyBlock( @Test public void shouldCalculateCoverageForLargeMethodThatThrowsException() - throws IOException, InterruptedException, ExecutionException { + throws IOException, InterruptedException { final List coveredClasses = runCoverageForTest(TestThrowsExceptionFromLargeMethodTestee.class); final ClassName clazz = ClassName @@ -262,7 +252,7 @@ public void testFoo() { @Test public void shouldCalculateCoverageOfClassesRunInDifferentClassLoader() - throws IOException, InterruptedException, ExecutionException { + throws IOException, InterruptedException { final List coveredClasses = runCoverageForTest(TestInDifferentClassLoader.class); assertThat(coveredClasses).anyMatch(coverageFor(Testee2.class)); assertThat(coveredClasses).anyMatch(coverageFor(Testee.class)); @@ -314,6 +304,13 @@ public void shouldFailWithExitCode() throws Exception { assertEquals(ExitCode.JUNIT_ISSUE, exitCode); } + @Test + public void handlesParentChildInitializationOrderIssues() throws Exception { + final List coveredClasses = runCoverageForTest(ParentChildInitializationTest.class); + assertThat(coveredClasses) + .anyMatch(coverageFor(ClassName.fromString("com.example.coverage.execute.samples.simple.TesteeChild"))); + } + private ClassPath classPathWithoutJUnit() { final List cpWithoutJUnit = ClassPath.getClassPathElementsAsFiles().stream() @@ -328,7 +325,7 @@ private Predicate failingTest() { } private List runCoverageForTest(final Class test) - throws IOException, InterruptedException, ExecutionException { + throws IOException, InterruptedException { final List coveredClasses = new ArrayList<>(); @@ -360,16 +357,20 @@ private void runCoverageProcess(final Class test, } } - private Predicate coverageFor(final Class class1) { + private Predicate coverageFor(final Class clazz) { + return coverageFor(ClassName.fromClass(clazz)); + } + + private Predicate coverageFor(ClassName clazz) { return new Predicate() { @Override public boolean test(final CoverageResult a) { - return FCollection.contains(a.getCoverage(), resultFor(class1)); + return FCollection.contains(a.getCoverage(), resultFor(clazz)); } - private Predicate resultFor(final Class class1) { - return a -> a.isFor(ClassName.fromClass(class1)); + private Predicate resultFor(ClassName clazz) { + return a -> a.isFor(clazz); } }; } From 8ff5d90767e7fed546e2bbd65fb6a68590d801ba Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Thu, 31 Dec 2020 14:12:05 +0000 Subject: [PATCH 22/25] Lazily initialise probe field when required Adds a null check when accessing the probe field, initialising it if null. Under most circumstances the probe array will have been assigned in the static initializer, but in the special case of a child class where the parent class constructs the child in a static initializer the child initializer will not have been called. --- .../src/test/java/org/pitest/PitMojoIT.java | 5 ++-- .../pitest/coverage/CoverageClassVisitor.java | 23 +++++++++++++---- .../ArrayProbeCoverageMethodVisitor.java | 25 +++++++++++++++++-- .../java/org/pitest/util/XStreamCloning.java | 2 +- 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/pitest-maven-verification/src/test/java/org/pitest/PitMojoIT.java b/pitest-maven-verification/src/test/java/org/pitest/PitMojoIT.java index 1ccf8f2fd..4601cccb2 100755 --- a/pitest-maven-verification/src/test/java/org/pitest/PitMojoIT.java +++ b/pitest-maven-verification/src/test/java/org/pitest/PitMojoIT.java @@ -564,14 +564,13 @@ public void shouldFindOccupiedTestPackages() throws IOException, VerificationExc } @Test - public void shouldNotNullPointerWhenEnumInitiliazerNotCalled() throws IOException, VerificationException { + public void shouldNotNullPointerWhenEnumInitializerNotCalled() throws IOException, VerificationException { File testDir = prepare("/pit-enum-constructor-npe"); verifier.executeGoal("test"); verifier.executeGoal("org.pitest:pitest-maven:mutationCoverage"); String actual = readResults(testDir); - assertThat(actual).contains( - "DiscoveredClass.java"); + assertThat(actual).isNotEmpty(); } } diff --git a/pitest/src/main/java/org/pitest/coverage/CoverageClassVisitor.java b/pitest/src/main/java/org/pitest/coverage/CoverageClassVisitor.java index 46bf64a4c..0a7f83249 100644 --- a/pitest/src/main/java/org/pitest/coverage/CoverageClassVisitor.java +++ b/pitest/src/main/java/org/pitest/coverage/CoverageClassVisitor.java @@ -40,6 +40,7 @@ public class CoverageClassVisitor extends MethodFilteringAdapter { private String className; private boolean foundClinit; + private boolean isInterface; public CoverageClassVisitor(final int classId, final ClassWriter writer) { super(writer, BridgeMethodFilter.INSTANCE); @@ -55,6 +56,7 @@ public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { super.visit(version, access, name, signature, superName, interfaces); this.className = name; + this.isInterface = (access & Opcodes.ACC_INTERFACE) != 0; } @@ -93,12 +95,10 @@ public void visitEnd() { private void addCoverageProbeField() { - super.visitField(Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC - | Opcodes.ACC_SYNTHETIC, CodeCoverageStore.PROBE_FIELD_NAME, "[Z", null, + super.visitField(fieldModifiers(), CodeCoverageStore.PROBE_FIELD_NAME, "[Z", null, null); - super.visitField(Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC - | Opcodes.ACC_SYNTHETIC, CodeCoverageStore.PROBE_LENGTH_FIELD_NAME, "I", + super.visitField(fieldModifiers(), CodeCoverageStore.PROBE_LENGTH_FIELD_NAME, "I", null, this.probeCount + 1); //If there is no , then generate one that sets the probe field directly @@ -107,7 +107,6 @@ private void addCoverageProbeField() { .visitMethod(Opcodes.ACC_STATIC, "", "()V", null, null); clinitMv.visitCode(); - pushConstant(clinitMv, this.classId); pushConstant(clinitMv, this.probeCount); clinitMv @@ -122,6 +121,20 @@ private void addCoverageProbeField() { } } + private int fieldModifiers() { + // For interfaces field must be final. + // For classes cannot be final as we must cover the corner case of child classes + // referenced in their parent's static initializer. The probe field for these + // must be initialised lazyily outside of the static initializer block. + if (isInterface) { + return Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC + | Opcodes.ACC_SYNTHETIC; + } + + return Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT | Opcodes.ACC_PUBLIC + | Opcodes.ACC_SYNTHETIC; + } + private void pushConstant(MethodVisitor mv, int value) { switch (value) { case 0: diff --git a/pitest/src/main/java/org/pitest/coverage/analysis/ArrayProbeCoverageMethodVisitor.java b/pitest/src/main/java/org/pitest/coverage/analysis/ArrayProbeCoverageMethodVisitor.java index 6307bbd4e..d0733e9b1 100644 --- a/pitest/src/main/java/org/pitest/coverage/analysis/ArrayProbeCoverageMethodVisitor.java +++ b/pitest/src/main/java/org/pitest/coverage/analysis/ArrayProbeCoverageMethodVisitor.java @@ -17,14 +17,15 @@ package org.pitest.coverage.analysis; -import java.util.List; - +import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.pitest.mutationtest.engine.gregor.analysis.InstructionCounter; import sun.pitest.CodeCoverageStore; +import java.util.List; + /** * * Instruments a method adding probes at each block. @@ -100,6 +101,26 @@ void prepare() { this.mv.visitFieldInsn(Opcodes.GETSTATIC, className, CodeCoverageStore.PROBE_FIELD_NAME, "[Z"); + this.mv.visitInsn(DUP); //duplicate array reference, one for null check and one to use + + //Check if PROBE_FIELD_NAME has been initialised + Label notnull = new Label(); + this.mv.visitJumpInsn(Opcodes.IFNONNULL,notnull); + + //if not then initialise + this.mv.visitInsn(POP); //gte rid of null on top of stack + pushConstant(this.classId); + this.mv.visitFieldInsn(Opcodes.GETSTATIC, this.className, CodeCoverageStore.PROBE_LENGTH_FIELD_NAME,"I"); + this.mv + .visitMethodInsn(Opcodes.INVOKESTATIC, CodeCoverageStore.CLASS_NAME, + "getOrRegisterClassProbes", "(II)[Z", false); + this.mv.visitInsn(DUP);//duplicate array reference, one to store and one to use + this.mv.visitFieldInsn(Opcodes.PUTSTATIC, className, + CodeCoverageStore.PROBE_FIELD_NAME, "[Z"); + + //else do nothing + this.mv.visitLabel(notnull); + //Make sure that we recorded that the class was hit this.mv.visitInsn(DUP); this.mv.visitInsn(ICONST_0); diff --git a/pitest/src/test/java/org/pitest/util/XStreamCloning.java b/pitest/src/test/java/org/pitest/util/XStreamCloning.java index eea891ef1..297006f99 100644 --- a/pitest/src/test/java/org/pitest/util/XStreamCloning.java +++ b/pitest/src/test/java/org/pitest/util/XStreamCloning.java @@ -12,7 +12,7 @@ public class XStreamCloning { private static final XStream XSTREAM_INSTANCE = new XStream( - new PitXmlDriver()); + new PitXmlDriver()).set private static final WeakHashMap CACHE = new WeakHashMap<>(); From baa0ba9597093325da6e156cb1a50012ee02a67d Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Thu, 31 Dec 2020 14:44:10 +0000 Subject: [PATCH 23/25] Reduce probe visibility for normal classes --- .../src/main/java/org/pitest/coverage/CoverageClassVisitor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pitest/src/main/java/org/pitest/coverage/CoverageClassVisitor.java b/pitest/src/main/java/org/pitest/coverage/CoverageClassVisitor.java index 0a7f83249..db641e1ec 100644 --- a/pitest/src/main/java/org/pitest/coverage/CoverageClassVisitor.java +++ b/pitest/src/main/java/org/pitest/coverage/CoverageClassVisitor.java @@ -131,7 +131,7 @@ private int fieldModifiers() { | Opcodes.ACC_SYNTHETIC; } - return Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT | Opcodes.ACC_PUBLIC + return Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT | Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC; } From 239b19bb5b834b43d8208496f9cfc0dad76d3487 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Thu, 31 Dec 2020 14:44:36 +0000 Subject: [PATCH 24/25] Remove xstream noise --- pitest/src/test/java/org/pitest/util/PitXmlDriver.java | 9 +++------ .../src/test/java/org/pitest/util/XStreamCloning.java | 10 ++++++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/pitest/src/test/java/org/pitest/util/PitXmlDriver.java b/pitest/src/test/java/org/pitest/util/PitXmlDriver.java index b9814b6e6..3c6cf1acb 100644 --- a/pitest/src/test/java/org/pitest/util/PitXmlDriver.java +++ b/pitest/src/test/java/org/pitest/util/PitXmlDriver.java @@ -14,12 +14,10 @@ */ package org.pitest.util; -import org.xmlpull.mxp1.MXParser; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import com.thoughtworks.xstream.io.xml.AbstractXppDriver; import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; +import org.xmlpull.mxp1.MXParser; +import org.xmlpull.v1.XmlPullParser; /** * Pull parser driver that creates hard coded parser type to avoid clashes with @@ -32,8 +30,7 @@ public PitXmlDriver() { } @Override - protected synchronized XmlPullParser createParser() - throws XmlPullParserException { + protected synchronized XmlPullParser createParser() { return new MXParser(); } } diff --git a/pitest/src/test/java/org/pitest/util/XStreamCloning.java b/pitest/src/test/java/org/pitest/util/XStreamCloning.java index 297006f99..afdaa3f5d 100644 --- a/pitest/src/test/java/org/pitest/util/XStreamCloning.java +++ b/pitest/src/test/java/org/pitest/util/XStreamCloning.java @@ -1,18 +1,18 @@ package org.pitest.util; -import static org.pitest.util.Unchecked.translateCheckedException; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.CompactWriter; import java.io.StringWriter; import java.io.Writer; import java.util.WeakHashMap; -import com.thoughtworks.xstream.XStream; -import com.thoughtworks.xstream.io.xml.CompactWriter; +import static org.pitest.util.Unchecked.translateCheckedException; public class XStreamCloning { private static final XStream XSTREAM_INSTANCE = new XStream( - new PitXmlDriver()).set + new PitXmlDriver()); private static final WeakHashMap CACHE = new WeakHashMap<>(); @@ -32,6 +32,8 @@ private static XStream getXStreamForLoader(final ClassLoader loader) { if (foreginXstream == null) { foreginXstream = new XStream(new PitXmlDriver()); foreginXstream.setClassLoader(loader); + XStream.setupDefaultSecurity(foreginXstream); + foreginXstream.allowTypesByWildcard(new String[] {"**"}); // possible that more than one instance will be created // per loader, but probably better than synchronizing the whole method synchronized (CACHE) { From 96d4bf54b5b337c30604ebf33621d2fb4b716435 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Thu, 31 Dec 2020 14:54:41 +0000 Subject: [PATCH 25/25] install for integration tests --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 857ffc71a..b9e31c74c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,4 +37,5 @@ jobs: key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-maven- - name: 'Test' - run: mvn -B verify \ No newline at end of file + # install rather than verify to ensure correct version used during integration test + run: mvn -B install