From c7de5b58d85a984459d5b795146568773b1b300d Mon Sep 17 00:00:00 2001 From: Vyom-Yadav Date: Thu, 23 Jun 2022 23:56:55 +0530 Subject: [PATCH] Issue #11665: Create a robust method of surviving mutation suppression --- .ci/jsoref-spellchecker/whitelist.words | 5 + .../pitest-ant-suppressions.xml | 47 ++ .../pitest-coding-1-suppressions.xml | 137 ++++ .../pitest-coding-2-suppressions.xml | 182 +++++ ...coding-require-this-check-suppressions.xml | 92 +++ .../pitest-common-suppressions.xml | 92 +++ .../pitest-header-suppressions.xml | 19 + .../pitest-imports-suppressions.xml | 47 ++ .../pitest-indentation-suppressions.xml | 227 ++++++ .../pitest-javadoc-suppressions.xml | 29 + ...itest.sh => pitest-survival-check-html.sh} | 69 +- .ci/pitest-survival-check-xml.groovy | 408 ++++++++++ .github/workflows/pitest.yml | 710 +----------------- ...checkstyle_non_main_files_suppressions.xml | 5 +- pom.xml | 30 + 15 files changed, 1385 insertions(+), 714 deletions(-) create mode 100644 .ci/pitest-suppressions/pitest-ant-suppressions.xml create mode 100644 .ci/pitest-suppressions/pitest-coding-1-suppressions.xml create mode 100644 .ci/pitest-suppressions/pitest-coding-2-suppressions.xml create mode 100644 .ci/pitest-suppressions/pitest-coding-require-this-check-suppressions.xml create mode 100644 .ci/pitest-suppressions/pitest-common-suppressions.xml create mode 100644 .ci/pitest-suppressions/pitest-header-suppressions.xml create mode 100644 .ci/pitest-suppressions/pitest-imports-suppressions.xml create mode 100644 .ci/pitest-suppressions/pitest-indentation-suppressions.xml create mode 100644 .ci/pitest-suppressions/pitest-javadoc-suppressions.xml rename .ci/{pitest.sh => pitest-survival-check-html.sh} (87%) create mode 100644 .ci/pitest-survival-check-xml.groovy diff --git a/.ci/jsoref-spellchecker/whitelist.words b/.ci/jsoref-spellchecker/whitelist.words index 30db6bc66a85..7285c75041fe 100644 --- a/.ci/jsoref-spellchecker/whitelist.words +++ b/.ci/jsoref-spellchecker/whitelist.words @@ -513,6 +513,7 @@ googleecommon googlegroups googlesource govstrangefolder +GPath gpg gradle gradlew @@ -862,6 +863,7 @@ multiplevariabledeclarations Multiset multithreading mutableexception +mutationtest MVC mvn mvnw @@ -1177,6 +1179,7 @@ scp screenshot Scss sdk +sdkman selfexplanatory Selkin semaphoreci @@ -1204,6 +1207,8 @@ sivakumar Slawinski slf slist +Slurper +slurpersupport Sms smth snyk diff --git a/.ci/pitest-suppressions/pitest-ant-suppressions.xml b/.ci/pitest-suppressions/pitest-ant-suppressions.xml new file mode 100644 index 000000000000..2987c4da44fc --- /dev/null +++ b/.ci/pitest-suppressions/pitest-ant-suppressions.xml @@ -0,0 +1,47 @@ + + + + CheckstyleAntTask.java + com.puppycrawl.tools.checkstyle.ant.CheckstyleAntTask + execute + org.pitest.mutationtest.engine.gregor.mutators.MathMutator + Replaced long subtraction with addition + log("Total execution took " + (endTime - startTime) + TIME_SUFFIX, + + + + CheckstyleAntTask.java + com.puppycrawl.tools.checkstyle.ant.CheckstyleAntTask + processFiles + org.pitest.mutationtest.engine.gregor.mutators.MathMutator + Replaced long subtraction with addition + log("To locate the files took " + (endTime - startTime) + TIME_SUFFIX, + + + + CheckstyleAntTask.java + com.puppycrawl.tools.checkstyle.ant.CheckstyleAntTask + processFiles + org.pitest.mutationtest.engine.gregor.mutators.MathMutator + Replaced long subtraction with addition + log("To process the files took " + (processingEndTime - processingStartTime) + + + + CheckstyleAntTask.java + com.puppycrawl.tools.checkstyle.ant.CheckstyleAntTask$Formatter + createDefaultLogger + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (toFile == null || !useFile) { + + + + CheckstyleAntTask.java + com.puppycrawl.tools.checkstyle.ant.CheckstyleAntTask$Formatter + createXmlLogger + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (toFile == null || !useFile) { + + diff --git a/.ci/pitest-suppressions/pitest-coding-1-suppressions.xml b/.ci/pitest-suppressions/pitest-coding-1-suppressions.xml new file mode 100644 index 000000000000..714ca4c30ca5 --- /dev/null +++ b/.ci/pitest-suppressions/pitest-coding-1-suppressions.xml @@ -0,0 +1,137 @@ + + + + UnnecessaryParenthesesCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.UnnecessaryParenthesesCheck + isLambdaSingleParameterSurrounded + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (firstChild != null && firstChild.getType() == TokenTypes.LPAREN) { + + + + UnnecessaryParenthesesCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.UnnecessaryParenthesesCheck + leaveToken + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + if (type != TokenTypes.ASSIGN + + + + UnnecessaryParenthesesCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.UnnecessaryParenthesesCheck + leaveToken + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + || parent.getType() != TokenTypes.ANNOTATION_MEMBER_VALUE_PAIR) { + + + + UnnecessaryParenthesesCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.UnnecessaryParenthesesCheck + visitToken + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + else if (type != TokenTypes.ASSIGN + + + + UnnecessaryParenthesesCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.UnnecessaryParenthesesCheck + visitToken + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (type == TokenTypes.LAMBDA && isLambdaSingleParameterSurrounded(ast)) { + + + + VariableDeclarationUsageDistanceCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck + calculateDistanceInSingleScope + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + && currentAst.getType() != TokenTypes.RCURLY) { + + + + VariableDeclarationUsageDistanceCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck + calculateDistanceInSingleScope + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + if (!firstUsageFound) { + + + + VariableDeclarationUsageDistanceCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck + getFirstNodeInsideForWhileDoWhileBlocks + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + if (currentNodeType == TokenTypes.SLIST) { + + + + VariableDeclarationUsageDistanceCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck + getFirstNodeInsideIfBlock + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + else if (isChild(currentNode, variable)) { + + + + VariableDeclarationUsageDistanceCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck + getFirstNodeInsideIfBlock + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + if (currentNode.getType() == TokenTypes.LITERAL_IF) { + + + + VariableDeclarationUsageDistanceCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck + getFirstNodeInsideTryCatchFinallyBlocks + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + && currentNode.getType() == TokenTypes.LITERAL_CATCH) { + + + + VariableDeclarationUsageDistanceCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck + isChild + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (curNode.getType() == ast.getType() && curNode.getText().equals(ast.getText())) { + + + + VariableDeclarationUsageDistanceCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck + isInitializationSequence + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + while (result + + + + VariableDeclarationUsageDistanceCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck + isVariableInOperatorExpr + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (!isVarInOperatorDeclaration && operator.getType() == TokenTypes.LITERAL_IF) { + + + + VariableDeclarationUsageDistanceCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.VariableDeclarationUsageDistanceCheck + searchVariableUsageExpressions + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + && currentStatementAst.getType() != TokenTypes.RCURLY) { + + diff --git a/.ci/pitest-suppressions/pitest-coding-2-suppressions.xml b/.ci/pitest-suppressions/pitest-coding-2-suppressions.xml new file mode 100644 index 000000000000..4aea1e541250 --- /dev/null +++ b/.ci/pitest-suppressions/pitest-coding-2-suppressions.xml @@ -0,0 +1,182 @@ + + + + FinalLocalVariableCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck + findLastChildWhichContainsSpecifiedToken + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (astIterator.getType() == childType + + + + FinalLocalVariableCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck + isCaseTokenWithAnotherCaseFollowing + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + result = findLastChildWhichContainsSpecifiedToken( + + + + FinalLocalVariableCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck + isIfTokenWithAnElseFollowing + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + return ast.getType() == TokenTypes.LITERAL_IF + + + + FinalLocalVariableCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck + isInTheSameLoop + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + return loop1 != null && loop1 == loop2; + + + + FinalLocalVariableCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck + updateUninitializedVariables + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + && isSameVariables(storedVariable, variable) + + + + FinalLocalVariableCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck + visitToken + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + == ast.getParent()) { + + + + FinalLocalVariableCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck + visitToken + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (ast.getParent().getType() == TokenTypes.SWITCH_RULE + + + + HiddenFieldCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck + isIgnoredParamOfAbstractMethod + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + && ast.getType() == TokenTypes.PARAMETER_DEF) { + + + + HiddenFieldCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck + isIgnoredParamOfAbstractMethod + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (method.getType() == TokenTypes.METHOD_DEF) { + + + + HiddenFieldCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck + isIgnoredSetterParam + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + && methodAST.getType() == TokenTypes.METHOD_DEF + + + + HiddenFieldCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck + isIgnoredSetterParam + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (ignoreSetter && ast.getType() == TokenTypes.PARAMETER_DEF) { + + + + HiddenFieldCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck + processLambda + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + && firstChild.getType() == TokenTypes.IDENT) { + + + + HiddenFieldCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck + visitOtherTokens + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + if (type == TokenTypes.CLASS_DEF + + + + HiddenFieldCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck + visitOtherTokens + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (type == TokenTypes.CLASS_DEF + + + + IllegalInstantiationCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.IllegalInstantiationCheck + isStandardClass + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + && illegal.startsWith(JAVA_LANG)) { + + + + OneStatementPerLineCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck + checkIfSemicolonIsInDifferentLineThanPrevious + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + && currentStatement.getPreviousSibling().getType() == TokenTypes.RESOURCES; + + + + OneStatementPerLineCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck + checkIfSemicolonIsInDifferentLineThanPrevious + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + currentStatement.getPreviousSibling() != null + + + + OneStatementPerLineCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck + checkIfSemicolonIsInDifferentLineThanPrevious + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (!hasResourcesPrevSibling && isMultilineStatement(currentStatement)) { + + + + OneStatementPerLineCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck + isMultilineStatement + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + multiline = !TokenUtil.areOnSameLine(prevSibling, ast) + + + + OneStatementPerLineCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck + leaveToken + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (countOfSemiInLambda.isEmpty()) { + + diff --git a/.ci/pitest-suppressions/pitest-coding-require-this-check-suppressions.xml b/.ci/pitest-suppressions/pitest-coding-require-this-check-suppressions.xml new file mode 100644 index 000000000000..3bf571976353 --- /dev/null +++ b/.ci/pitest-suppressions/pitest-coding-require-this-check-suppressions.xml @@ -0,0 +1,92 @@ + + + + RequireThisCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck + beginTree + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (toVisit == null) { + + + + RequireThisCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck + canBeReferencedFromStaticContext + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + if (definitionToken.getType() == TokenTypes.STATIC_INIT) { + + + + RequireThisCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck + canBeReferencedFromStaticContext + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (variableDeclarationFrame.getType() == FrameType.CLASS_FRAME) { + + + + RequireThisCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck + collectDeclarations + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + && ast.getParent().getType() != TokenTypes.LITERAL_CATCH) { + + + + RequireThisCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck + endCollectingDeclarations + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + if (isAnonymousClassDef(ast)) { + + + + RequireThisCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck + getCodeBlockDefinitionToken + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + && parent.getType() != TokenTypes.CTOR_DEF + + + + RequireThisCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck + isAnonymousClassDef + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + && lastChild.getType() == TokenTypes.OBJBLOCK; + + + + RequireThisCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck + isAstSimilar + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + return left.getType() == right.getType() && left.getText().equals(right.getText()); + + + + RequireThisCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck + isInsideConstructorFrame + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (fieldUsageFrame.getType() == FrameType.BLOCK_FRAME) { + + + + RequireThisCheck.java + com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck + isOverlappingByLocalVariable + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (sibling != null && isAssignToken(parent.getType())) { + + diff --git a/.ci/pitest-suppressions/pitest-common-suppressions.xml b/.ci/pitest-suppressions/pitest-common-suppressions.xml new file mode 100644 index 000000000000..124e956b306f --- /dev/null +++ b/.ci/pitest-suppressions/pitest-common-suppressions.xml @@ -0,0 +1,92 @@ + + + + Checker.java + com.puppycrawl.tools.checkstyle.Checker + processFiles + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + if (cacheFile != null && cacheFile.isInCache(fileName, timestamp) + + + + Checker.java + com.puppycrawl.tools.checkstyle.Checker + processFiles + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (cacheFile != null && cacheFile.isInCache(fileName, timestamp) + + + + DefaultLogger.java + com.puppycrawl.tools.checkstyle.DefaultLogger + <init> + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + closeError = errorStreamOptions == OutputStreamOptions.CLOSE; + + + + DefaultLogger.java + com.puppycrawl.tools.checkstyle.DefaultLogger + <init> + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + closeInfo = infoStreamOptions == OutputStreamOptions.CLOSE; + + + + DefaultLogger.java + com.puppycrawl.tools.checkstyle.DefaultLogger + addError + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (severityLevel != SeverityLevel.IGNORE) { + + + + DefaultLogger.java + com.puppycrawl.tools.checkstyle.DefaultLogger + closeStreams + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (closeError) { + + + + DefaultLogger.java + com.puppycrawl.tools.checkstyle.DefaultLogger + closeStreams + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (closeInfo) { + + + + PackageObjectFactory.java + com.puppycrawl.tools.checkstyle.PackageObjectFactory + createModule + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (!name.contains(PACKAGE_SEPARATOR)) { + + + + PackageObjectFactory.java + com.puppycrawl.tools.checkstyle.PackageObjectFactory + createModule + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (instance == null + + + + PackageObjectFactory.java + com.puppycrawl.tools.checkstyle.PackageObjectFactory + createModule + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (thirdPartyNameToFullModuleNames == null) { + + diff --git a/.ci/pitest-suppressions/pitest-header-suppressions.xml b/.ci/pitest-suppressions/pitest-header-suppressions.xml new file mode 100644 index 000000000000..af1463a5f84e --- /dev/null +++ b/.ci/pitest-suppressions/pitest-header-suppressions.xml @@ -0,0 +1,19 @@ + + + + RegexpHeaderCheck.java + com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck + processFiltered + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + isMatch = headerLineNo == headerSize + + + RegexpHeaderCheck.java + com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck + processFiltered + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + || isMatch(line, headerLineNo); + + diff --git a/.ci/pitest-suppressions/pitest-imports-suppressions.xml b/.ci/pitest-suppressions/pitest-imports-suppressions.xml new file mode 100644 index 000000000000..9789588e9d0e --- /dev/null +++ b/.ci/pitest-suppressions/pitest-imports-suppressions.xml @@ -0,0 +1,47 @@ + + + + ImportControlLoader.java + com.puppycrawl.tools.checkstyle.checks.imports.ImportControlLoader + startElement + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + else if (ALLOW_ELEMENT_NAME.equals(qName) || "disallow".equals(qName)) { + + + + ImportControlLoader.java + com.puppycrawl.tools.checkstyle.checks.imports.ImportControlLoader + startElement + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + else if (ALLOW_ELEMENT_NAME.equals(qName) || "disallow".equals(qName)) { + + + + PkgImportControl.java + com.puppycrawl.tools.checkstyle.checks.imports.PkgImportControl + <init> + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + if (regex || parent.regex) { + + + + PkgImportControl.java + com.puppycrawl.tools.checkstyle.checks.imports.PkgImportControl + <init> + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_IF + removed conditional - replaced equality check with true + if (regex || parent.regex) { + + + + PkgImportControl.java + com.puppycrawl.tools.checkstyle.checks.imports.PkgImportControl + matchesExactly + org.pitest.mutationtest.engine.gregor.mutators.RemoveConditionalMutator_EQUAL_ELSE + removed conditional - replaced equality check with false + if (regex) { + + diff --git a/.ci/pitest-suppressions/pitest-indentation-suppressions.xml b/.ci/pitest-suppressions/pitest-indentation-suppressions.xml new file mode 100644 index 000000000000..08008b531652 --- /dev/null +++ b/.ci/pitest-suppressions/pitest-indentation-suppressions.xml @@ -0,0 +1,227 @@ + + + + AbstractExpressionHandler.java + com.puppycrawl.tools.checkstyle.checks.indentation.AbstractExpressionHandler + findSubtreeAst + org.pitest.mutationtest.engine.gregor.mutators.ConditionalsBoundaryMutator + changed conditional boundary + if (colNum == null || thisLineColumn < colNum) { + + + + AbstractExpressionHandler.java + com.puppycrawl.tools.checkstyle.checks.indentation.AbstractExpressionHandler + getFirstAstNode + org.pitest.mutationtest.engine.gregor.mutators.ConditionalsBoundaryMutator + changed conditional boundary + && curNode.getColumnNo() < realStart.getColumnNo()) { + + + + AbstractExpressionHandler.java + com.puppycrawl.tools.checkstyle.checks.indentation.AbstractExpressionHandler + getFirstToken + org.pitest.mutationtest.engine.gregor.mutators.ConditionalsBoundaryMutator + changed conditional boundary + if (toTest.getColumnNo() < first.getColumnNo()) { + + + + BlockParentHandler.java + com.puppycrawl.tools.checkstyle.checks.indentation.BlockParentHandler + getLineWrappingIndent + org.pitest.mutationtest.engine.gregor.mutators.ReturnValsMutator + replaced return of integer sized value with (x == 0 ? 1 : 0) + return getIndentCheck().getLineWrappingIndentation(); + + + + CommentsIndentationCheck.java + com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck + findPreviousStatement + org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator + negated conditional + if (root.getFirstChild().getType() == TokenTypes.LITERAL_NEW) { + + + + CommentsIndentationCheck.java + com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck + findPreviousStatement + org.pitest.mutationtest.engine.gregor.mutators.ConditionalsBoundaryMutator + changed conditional boundary + if (root.getLineNo() >= comment.getLineNo()) { + + + + CommentsIndentationCheck.java + com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck + findTokenWhichBeginsTheLine + org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator + negated conditional + if (isUsingOfObjectReferenceToInvokeMethod(root)) { + + + + CommentsIndentationCheck.java + com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck + getPrevStatementWhenCommentIsUnderCase + org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator + negated conditional + if (isUsingOfObjectReferenceToInvokeMethod(blockBody)) { + + + + CommentsIndentationCheck.java + com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck + isUsingOfObjectReferenceToInvokeMethod + org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator + negated conditional + && root.getFirstChild().getFirstChild().getFirstChild().getNextSibling() != null; + + + + CommentsIndentationCheck.java + com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck + isUsingOfObjectReferenceToInvokeMethod + org.pitest.mutationtest.engine.gregor.mutators.ReturnValsMutator + replaced return of integer sized value with (x == 0 ? 1 : 0) + return root.getFirstChild().getFirstChild().getFirstChild() != null + + + + CommentsIndentationCheck.java + com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck + isUsingOfObjectReferenceToInvokeMethod + org.pitest.mutationtest.engine.gregor.mutators.returns.BooleanTrueReturnValsMutator + replaced boolean return with true for com/puppycrawl/tools/checkstyle/checks/indentation/CommentsIndentationCheck::isUsingOfObjectReferenceToInvokeMethod + return root.getFirstChild().getFirstChild().getFirstChild() != null + + + + HandlerFactory.java + com.puppycrawl.tools.checkstyle.checks.indentation.HandlerFactory + <init> + org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator + removed call to com/puppycrawl/tools/checkstyle/checks/indentation/HandlerFactory::register + register(TokenTypes.INDEX_OP, IndexHandler.class); + + + + HandlerFactory.java + com.puppycrawl.tools.checkstyle.checks.indentation.HandlerFactory + clearCreatedHandlers + org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator + removed call to java/util/Map::clear + createdHandlers.clear(); + + + + IndentationCheck.java + com.puppycrawl.tools.checkstyle.checks.indentation.IndentationCheck + beginTree + org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator + removed call to com/puppycrawl/tools/checkstyle/checks/indentation/HandlerFactory::clearCreatedHandlers + handlerFactory.clearCreatedHandlers(); + + + + IndentationCheck.java + com.puppycrawl.tools.checkstyle.checks.indentation.IndentationCheck + beginTree + org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator + removed call to java/util/Deque::clear + handlers.clear(); + + + + IndentationCheck.java + com.puppycrawl.tools.checkstyle.checks.indentation.IndentationCheck + beginTree + org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator + removed call to com/puppycrawl/tools/checkstyle/checks/indentation/PrimordialHandler::checkIndentation + primordialHandler.checkIndentation(); + + + + MethodDefHandler.java + com.puppycrawl.tools.checkstyle.checks.indentation.MethodDefHandler + getMethodDefLineStart + org.pitest.mutationtest.engine.gregor.mutators.ConditionalsBoundaryMutator + changed conditional boundary + if (node.getLineNo() < lineStart) { + + + + NewHandler.java + com.puppycrawl.tools.checkstyle.checks.indentation.NewHandler + shouldIncreaseIndent + org.pitest.mutationtest.engine.gregor.mutators.ReturnValsMutator + replaced return of integer sized value with (x == 0 ? 1 : 0) + return false; + + + + NewHandler.java + com.puppycrawl.tools.checkstyle.checks.indentation.NewHandler + shouldIncreaseIndent + org.pitest.mutationtest.engine.gregor.mutators.returns.BooleanTrueReturnValsMutator + replaced boolean return with true for com/puppycrawl/tools/checkstyle/checks/indentation/NewHandler::shouldIncreaseIndent + return false; + + + + SwitchHandler.java + com.puppycrawl.tools.checkstyle.checks.indentation.SwitchHandler + checkIndentation + org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator + removed call to com/puppycrawl/tools/checkstyle/checks/indentation/SwitchHandler::checkSwitchExpr + checkSwitchExpr(); + + + + SwitchHandler.java + com.puppycrawl.tools.checkstyle.checks.indentation.SwitchHandler + checkSwitchExpr + org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator + removed call to com/puppycrawl/tools/checkstyle/checks/indentation/SwitchHandler::checkExpressionSubtree + checkExpressionSubtree( + + + + SynchronizedHandler.java + com.puppycrawl.tools.checkstyle.checks.indentation.SynchronizedHandler + checkIndentation + org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator + removed call to com/puppycrawl/tools/checkstyle/checks/indentation/SynchronizedHandler::checkSynchronizedExpr + checkSynchronizedExpr(); + + + + SynchronizedHandler.java + com.puppycrawl.tools.checkstyle.checks.indentation.SynchronizedHandler + checkIndentation + org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator + removed call to com/puppycrawl/tools/checkstyle/checks/indentation/SynchronizedHandler::checkWrappingIndentation + checkWrappingIndentation(getMainAst(), + + + + SynchronizedHandler.java + com.puppycrawl.tools.checkstyle.checks.indentation.SynchronizedHandler + checkSynchronizedExpr + org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator + removed call to com/puppycrawl/tools/checkstyle/checks/indentation/SynchronizedHandler::checkExpressionSubtree + checkExpressionSubtree(syncAst, expected, false, false); + + + + TryHandler.java + com.puppycrawl.tools.checkstyle.checks.indentation.TryHandler + checkIndentation + org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator + removed call to com/puppycrawl/tools/checkstyle/checks/indentation/TryHandler::checkTryResParen + checkTryResParen(getTryResLparen(), "lparen"); + + diff --git a/.ci/pitest-suppressions/pitest-javadoc-suppressions.xml b/.ci/pitest-suppressions/pitest-javadoc-suppressions.xml new file mode 100644 index 000000000000..819839ecc9ca --- /dev/null +++ b/.ci/pitest-suppressions/pitest-javadoc-suppressions.xml @@ -0,0 +1,29 @@ + + + + AbstractJavadocCheck.java + com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck + processTree + org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator + removed call to com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck::beginJavadocTree + beginJavadocTree(root); + + + + AbstractJavadocCheck.java + com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck + processTree + org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator + removed call to com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck::finishJavadocTree + finishJavadocTree(root); + + + + TagParser.java + com.puppycrawl.tools.checkstyle.checks.javadoc.TagParser + getNextCharPos + org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator + negated conditional + while (column < currentLineLength + + diff --git a/.ci/pitest.sh b/.ci/pitest-survival-check-html.sh similarity index 87% rename from .ci/pitest.sh rename to .ci/pitest-survival-check-html.sh index 41c086adb4ed..f1337603dc56 100755 --- a/.ci/pitest.sh +++ b/.ci/pitest-survival-check-html.sh @@ -7,32 +7,38 @@ function checkPitestReport() { local -n ignored=$1 fail=0 SEARCH_REGEXP="(span class='survived'|class='uncovered'>
)"
-  grep -irE "$SEARCH_REGEXP" target/pit-reports \
-     | sed -E 's/.*\/([A-Za-z]+.java.html)/\1/' | LC_ALL=C sort > target/actual.txt
-  printf "%s\n" "${ignored[@]}" | sed '/^$/d' | LC_ALL=C sort > target/ignored.txt
-  if [ -n "$2" ] ; then
-      local -n unstableMutations=$2
-      printf "%s\n" "${unstableMutations[@]}" | sed '/^$/d' | LC_ALL=C sort > target/unstable.txt
-      if grep -Fxf target/unstable.txt target/actual.txt > target/unstableMatching.txt ; then
-          echo "Following unstable mutations were encountered:"
-          cat target/unstableMatching.txt
-          grep -xvFf target/unstableMatching.txt target/actual.txt > target/tempActual.txt
-          cat target/tempActual.txt > target/actual.txt
-      fi;
-  fi;
-  if [ "$(diff --unified -w target/ignored.txt target/actual.txt)" != "" ] ; then
-      fail=1
-      echo "Actual:" ;
-      grep -irE "$SEARCH_REGEXP" target/pit-reports \
-         | sed -E 's/.*\/([A-Za-z]+.java.html)/\1/' | sort
-      echo "Ignore:" ;
-      printf '%s\n' "${ignored[@]}"
-      echo "Diff:"
-      diff --unified -w target/ignored.txt target/actual.txt | cat
-  fi;
-  if [ "$fail" -ne "0" ]; then
-    echo "Difference between 'Actual' and 'Ignore' lists is detected, lists should be equal."
-    echo "build will be failed."
+  PIT_REPORTS_DIRECTORY="target/pit-reports"
+  if [ -d "$PIT_REPORTS_DIRECTORY" ]; then
+    grep -irE "$SEARCH_REGEXP" "$PIT_REPORTS_DIRECTORY" \
+       | sed -E 's/.*\/([A-Za-z]+.java.html)/\1/' | LC_ALL=C sort > target/actual.txt
+    printf "%s\n" "${ignored[@]}" | sed '/^$/d' | LC_ALL=C sort > target/ignored.txt
+    if [ -n "$2" ] ; then
+        local -n unstableMutations=$2
+        printf "%s\n" "${unstableMutations[@]}" | sed '/^$/d' | LC_ALL=C sort > target/unstable.txt
+        if grep -Fxf target/unstable.txt target/actual.txt > target/unstableMatching.txt ; then
+            echo "Following unstable mutations were encountered:"
+            cat target/unstableMatching.txt
+            grep -xvFf target/unstableMatching.txt target/actual.txt > target/tempActual.txt
+            cat target/tempActual.txt > target/actual.txt
+        fi;
+    fi;
+    if [ "$(diff --unified -w target/ignored.txt target/actual.txt)" != "" ] ; then
+        fail=1
+        echo "Actual:" ;
+        grep -irE "$SEARCH_REGEXP" "$PIT_REPORTS_DIRECTORY" \
+           | sed -E 's/.*\/([A-Za-z]+.java.html)/\1/' | sort
+        echo "Ignore:" ;
+        printf '%s\n' "${ignored[@]}"
+        echo "Diff:"
+        diff --unified -w target/ignored.txt target/actual.txt | cat
+    fi;
+    if [ "$fail" -ne "0" ]; then
+      echo "Difference between 'Actual' and 'Ignore' lists is detected, lists should be equal."
+      echo "build will be failed."
+    fi
+  else
+    fail=1
+    echo "No pit-reports directory found"
   fi
   sleep 5s
   exit $fail
@@ -53,13 +59,11 @@ pitest-annotation|pitest-design \
 |pitest-tree-walker \
 |pitest-utils \
 |pitest-java-ast-visitor)
-  mvn -e --no-transfer-progress -P"$1" clean test-compile org.pitest:pitest-maven:mutationCoverage;
   declare -a ignoredItems=();
   checkPitestReport ignoredItems
   ;;
 
 pitest-main)
-  mvn -e --no-transfer-progress -P"$1" clean test-compile org.pitest:pitest-maven:mutationCoverage;
   declare -a ignoredItems=(
   "Main.java.html:
        }
" ); @@ -67,7 +71,6 @@ pitest-main) ;; pitest-header) - mvn -e --no-transfer-progress -P"$1" clean test-compile org.pitest:pitest-maven:mutationCoverage; declare -a ignoredItems=( "RegexpHeaderCheck.java.html:
                    isMatch = headerLineNo == headerSize
" "RegexpHeaderCheck.java.html:
                            || isMatch(line, headerLineNo);
" @@ -76,7 +79,6 @@ pitest-header) ;; pitest-imports) - mvn -e --no-transfer-progress -P"$1" clean test-compile org.pitest:pitest-maven:mutationCoverage; declare -a ignoredItems=( "ImportControlLoader.java.html:
        else if (ALLOW_ELEMENT_NAME.equals(qName) || "disallow".equals(qName)) {
" "PkgImportControl.java.html:
        if (regex || parent.regex) {
" @@ -86,7 +88,6 @@ pitest-imports) ;; pitest-common) - mvn -e --no-transfer-progress -P"$1" clean test-compile org.pitest:pitest-maven:mutationCoverage; declare -a ignoredItems=( "Checker.java.html:
                if (cacheFile != null && cacheFile.isInCache(fileName, timestamp)
" "DefaultLogger.java.html:
        closeError = errorStreamOptions == OutputStreamOptions.CLOSE;
" @@ -103,7 +104,6 @@ pitest-common) pitest-ant) - mvn -e --no-transfer-progress -P"$1" clean test-compile org.pitest:pitest-maven:mutationCoverage; declare -a ignoredItems=( "CheckstyleAntTask.java.html:
            if (toFile == null || !useFile) {
" "CheckstyleAntTask.java.html:
            if (toFile == null || !useFile) {
" @@ -115,7 +115,6 @@ pitest-ant) ;; pitest-indentation) - mvn -e --no-transfer-progress -P"$1" clean test-compile org.pitest:pitest-maven:mutationCoverage; declare -a ignoredItems=( "AbstractExpressionHandler.java.html:
                    && curNode.getColumnNo() < realStart.getColumnNo()) {
" "AbstractExpressionHandler.java.html:
            if (colNum == null || thisLineColumn < colNum) {
" @@ -145,7 +144,6 @@ pitest-indentation) ;; pitest-javadoc) - mvn -e --no-transfer-progress -P"$1" clean test-compile org.pitest:pitest-maven:mutationCoverage; declare -a ignoredItems=( "AbstractJavadocCheck.java.html:
        beginJavadocTree(root);
" "AbstractJavadocCheck.java.html:
        finishJavadocTree(root);
" @@ -155,7 +153,6 @@ pitest-javadoc) ;; pitest-coding-1) - mvn -e --no-transfer-progress -P"$1" clean test-compile org.pitest:pitest-maven:mutationCoverage; declare -a ignoredItems=( "UnnecessaryParenthesesCheck.java.html:
            || parent.getType() != TokenTypes.ANNOTATION_MEMBER_VALUE_PAIR) {
" "UnnecessaryParenthesesCheck.java.html:
        else if (type != TokenTypes.ASSIGN
" @@ -177,7 +174,6 @@ pitest-coding-1) ;; pitest-coding-2) - mvn -e --no-transfer-progress -P"$1" clean test-compile org.pitest:pitest-maven:mutationCoverage; declare -a ignoredItems=( "FinalLocalVariableCheck.java.html:
                            && isSameVariables(storedVariable, variable)
" "FinalLocalVariableCheck.java.html:
                        == ast.getParent()) {
" @@ -203,7 +199,6 @@ pitest-coding-2) ;; pitest-coding-require-this-check) - mvn -e --no-transfer-progress -P"$1" clean test-compile org.pitest:pitest-maven:mutationCoverage; declare -a ignoredItems=( "RequireThisCheck.java.html:
                        && ast.getParent().getType() != TokenTypes.LITERAL_CATCH) {
" "RequireThisCheck.java.html:
                if (isAnonymousClassDef(ast)) {
" diff --git a/.ci/pitest-survival-check-xml.groovy b/.ci/pitest-survival-check-xml.groovy new file mode 100644 index 000000000000..ace13515a4e8 --- /dev/null +++ b/.ci/pitest-survival-check-xml.groovy @@ -0,0 +1,408 @@ +import groovy.io.FileType +import groovy.transform.EqualsAndHashCode +import groovy.transform.Field +import groovy.xml.XmlParser +import groovy.xml.XmlSlurper +import groovy.xml.XmlUtil +import groovy.xml.slurpersupport.GPathResult +import groovy.xml.slurpersupport.NodeChildren + +@Field final static String SEPARATOR = System.getProperty("file.separator") + +final int exitCode +if (args.length == 2) { + exitCode = parseArgumentAndExecute(args[0], args[1]) +} +else { + exitCode = parseArgumentAndExecute(args[0], null) +} +System.exit(exitCode) + +/** + * Parse the command line arguments passed in and execute the branch based on the arguments. + * + * @param argument command line argument + * @return {@code 0} if command executes successfully, {@code 1} otherwise + */ +private int parseArgumentAndExecute(String argument, String flag) { + final Set profiles = getPitestProfiles() + final String usageString = """ + Usage groovy ./.ci/pitest-survival-check-xml.groovy [profile] [-g | --generate-suppression] + To see the full list of supported profiles run 'groovy ./.ci/pitest-survival-check-xml.groovy --list' + """.stripIndent() + + final int exitCode + if (profiles.contains(argument)) { + if (flag != null && flag != "-g" && flag != "--generate-suppression") { + final String exceptionMessage = "\nUnexpected flag: ${flag}" + usageString + throw new IllegalArgumentException(exceptionMessage) + } + exitCode = checkPitestReport(argument, flag) + + } + else if (argument == "--list") { + println "Supported profiles:" + profiles.each { println it } + exitCode = 0 + } + else { + final String exceptionMessage = "\nUnexpected argument: ${argument}" + usageString + throw new IllegalArgumentException(exceptionMessage) + } + return exitCode +} + +/** + * Parse the pom.xml file to get all the available pitest profiles. + * + * @return A set of all available pitest profiles + */ +private static Set getPitestProfiles() { + final GPathResult mainNode = new XmlSlurper().parse(".${SEPARATOR}pom.xml") + final NodeChildren ids = mainNode.profiles.profile.id as NodeChildren + final Set profiles = new HashSet<>() + ids.each { node -> + final GPathResult id = node as GPathResult + final String idText = id.text() + if (idText.startsWith("pitest-")) { + profiles.add(idText) + } + } + return profiles +} + +/** + * Check the generated pitest report. Parse the surviving and suppressed mutations and compare + * them. + * + * @param profile the pitest profile to execute + * @param flag command line argument flag to determine output format + * @return {@code 0} if pitest report is as expected, {@code 1} otherwise + */ +private static int checkPitestReport(String profile, String flag) { + final XmlParser xmlParser = new XmlParser() + File mutationReportFile = null + final String suppressedMutationFileUri = + ".${SEPARATOR}.ci${SEPARATOR}pitest-suppressions${SEPARATOR}${profile}-suppressions.xml" + + final File pitReports = new File(".${SEPARATOR}target${SEPARATOR}pit-reports") + + if (!pitReports.exists()) { + throw new IllegalStateException( + "Pitest report directory does not exist, generate pitest report first") + } + + pitReports.eachFileRecurse(FileType.FILES) { + if (it.name == 'mutations.xml') { + mutationReportFile = it + } + } + final Node mutationReportNode = xmlParser.parse(mutationReportFile) + final Set survivingMutations = getSurvivingMutations(mutationReportNode) + + final File suppressionFile = new File(suppressedMutationFileUri) + Set suppressedMutations = Collections.emptySet() + if (suppressionFile.exists()) { + final Node suppressedMutationNode = xmlParser.parse(suppressedMutationFileUri) + suppressedMutations = getSuppressedMutations(suppressedMutationNode) + } + return compareMutations(survivingMutations, suppressedMutations, flag) +} + +/** + * Get the surviving mutations. All child nodes of the main {@code mutations} node + * are parsed. + * + * @param mainNode the main {@code mutations} node + * @return A set of surviving mutations + */ +private static Set getSurvivingMutations(Node mainNode) { + + final def children = mainNode.children() + final Set survivingMutations = new TreeSet<>() + + children.each { node -> + final Node mutationNode = node as Node + + final String mutationStatus = mutationNode.attribute("status") + + if (mutationStatus == "SURVIVED" || mutationStatus == "NO_COVERAGE") { + survivingMutations.add(getMutation(mutationNode)) + } + } + return survivingMutations +} + +/** + * Get the suppressed mutations. All child nodes of the main {@code suppressedMutations} node + * are parsed. + * + * @param mainNode the main {@code suppressedMutations} node + * @return A set of suppressed mutations + */ +private static Set getSuppressedMutations(Node mainNode) { + final def children = mainNode.children() + final Set suppressedMutations = new TreeSet<>() + + children.each { node -> + final Node mutationNode = node as Node + suppressedMutations.add(getMutation(mutationNode)) + } + return suppressedMutations +} + +/** + * Construct the {@link Mutation} object from the {@code mutation} XML node. + * The {@code mutations.xml} file is parsed to get the {@code mutationNode}. + * + * @param mutationNode the {@code mutation} XML node + * @return {@link Mutation} object represented by the {@code mutation} XML node + */ +private static Mutation getMutation(Node mutationNode) { + final List childNodes = mutationNode.children() + + String sourceFile = null + String mutatedClass = null + String mutatedMethod = null + String mutator = null + String lineContent = null + String description = null + String mutationClassPackage = null + int lineNumber = 0 + childNodes.each { + final Node childNode = it as Node + final String text = childNode.name() + + final String childNodeText = XmlUtil.escapeXml(childNode.text()) + switch (text) { + case "sourceFile": + sourceFile = childNodeText + break + case "mutatedClass": + mutatedClass = childNodeText + mutationClassPackage = mutatedClass.split("[A-Z]")[0] + break + case "mutatedMethod": + mutatedMethod = childNodeText + break + case "mutator": + mutator = childNodeText + break + case "description": + description = childNodeText + break + case "lineNumber": + lineNumber = Integer.parseInt(childNodeText) + break + case "lineContent": + lineContent = childNodeText + break + } + } + if (lineContent == null) { + final String mutationFileName = mutationClassPackage + sourceFile + final String startingPath = ".${SEPARATOR}src${SEPARATOR}main${SEPARATOR}java${SEPARATOR}" + final String javaExtension = ".java" + final String mutationFilePath = startingPath + mutationFileName + .substring(0, mutationFileName.length() - javaExtension.length()) + .replaceAll("\\.", SEPARATOR) + javaExtension + + final File file = new File(mutationFilePath) + lineContent = XmlUtil.escapeXml(file.readLines().get(lineNumber - 1).trim()) + } + if (lineNumber == 0) { + lineNumber = -1 + } + + final String unstableAttributeValue = mutationNode.attribute("unstable") + final boolean isUnstable = Boolean.parseBoolean(unstableAttributeValue) + + return new Mutation(sourceFile, mutatedClass, mutatedMethod, mutator, description, + lineContent, lineNumber, isUnstable) +} + +/** + * Compare surviving and suppressed mutations. The comparison passes successfully (i.e. returns 0) + * when: + *
    + *
  1. Surviving and suppressed mutations are equal.
  2. + *
  3. There are extra suppressed mutations but they are unstable + * i.e. {@code unstable="true"}.
  4. + *
+ * The comparison fails (i.e. returns 1) when: + *
    + *
  1. Surviving mutations are not present in the suppressed list.
  2. + *
  3. There are mutations in the suppression list that are not there is surviving list.
  4. + *
+ * + * @param survivingMutations A set of surviving mutations + * @param suppressedMutations A set of suppressed mutations + * @param flag command line argument flag to determine output format + * @return {@code 0} if comparison passes successfully + */ +private static int compareMutations(Set survivingMutations, + Set suppressedMutations, + String flag) { + final Set survivingUnsuppressedMutations = + setDifference(survivingMutations, suppressedMutations) + final Set extraSuppressions = + setDifference(suppressedMutations, survivingMutations) + + final int exitCode + if (survivingMutations == suppressedMutations) { + exitCode = 0 + } + else if (survivingUnsuppressedMutations.isEmpty() + && !hasOnlyStableMutations(extraSuppressions)) { + exitCode = 0 + } + else { + if (!survivingUnsuppressedMutations.isEmpty()) { + println "Surviving mutation(s) found:" + survivingUnsuppressedMutations.each { + printMutation(flag, it) + } + } + if (!extraSuppressions.isEmpty() + && extraSuppressions.any { !it.isUnstable() }) { + println "\nUnnecessary suppressed mutation(s) found:" + extraSuppressions.each { + if (!it.isUnstable()) { + printMutation(flag, it) + } + } + } + exitCode = 1 + } + return exitCode +} + +/** + * Whether a set has only stable mutations. + * + * @param mutations A set of mutations + * @return {@code true} if a set has only stable mutations + */ +private static boolean hasOnlyStableMutations(Set mutations) { + return mutations.every { !it.isUnstable() } +} + +/** + * Prints the mutation according to the nature of the flag. + * + * @param flag command line argument flag to determine output format + * @param mutation mutation to print + */ +private static void printMutation(String flag, Mutation mutation) { + if (flag != null) { + println mutation.toXmlString() + } + else { + println mutation + } +} + +/** + * Determine the difference between 2 sets. The result is {@code setOne - setTwo}. + * + * @param setOne The first set in the difference + * @param setTwo The second set in the difference + * @return {@code setOne - setTwo} + */ +private static Set setDifference(final Set setOne, + final Set setTwo) { + final Set result = new HashSet(setOne) + result.removeIf(mutation -> setTwo.contains(mutation)) + return result +} + +/** + * A class to represent the XML {@code mutation} node. + */ +@EqualsAndHashCode(excludes = ["lineNumber"]) +record Mutation(String sourceFile, String mutatedClass, + String mutatedMethod, String mutator, + String description, String lineContent, int lineNumber, + boolean isUnstable) + implements Comparable { + + /** + * Mutation nodes present in suppressions file do not have a {@code lineNumber}. + * The {@code lineNumber} is set to {@code -1} for such mutations. + */ + private static final int LINE_NUMBER_NOT_PRESENT_VALUE = -1 + + @Override + String toString() { + String toString = """ + Source File: "${sourceFile()}" + Class: "${mutatedClass()}" + Method: "${mutatedMethod()}" + Line Contents: "${lineContent()}" + Mutator: "${mutator()}" + Description: "${description()}" + """.stripIndent() + if (lineNumber() != LINE_NUMBER_NOT_PRESENT_VALUE) { + toString += 'Line Number: ' + lineNumber() + } + return toString + } + + @Override + int compareTo(Mutation other) { + int i = sourceFile() <=> other.sourceFile() + if (i != 0) { + return i + } + + i = mutatedClass() <=> other.mutatedClass() + if (i != 0) { + return i + } + + i = mutatedMethod() <=> other.mutatedMethod() + if (i != 0) { + return i + } + + i = lineContent() <=> other.lineContent() + if (i != 0) { + return i + } + + i = mutator() <=> other.mutator() + if (i != 0) { + return i + } + + return description() <=> other.description() + } + + /** + * XML format of the mutation. + * + * @return XML format of the mutation + */ + String toXmlString() { + return """ + + ${sourceFile()} + ${mutatedClass()} + ${mutatedMethod()} + ${mutator()} + ${description()} + ${lineContent()} + + """.stripIndent(10) + } + + /** + * Whether the mutation is unstable. + * + * @return {@code true} if the mutation is unstable + */ + boolean isUnstable() { + return isUnstable + } + +} diff --git a/.github/workflows/pitest.yml b/.github/workflows/pitest.yml index f41f83722bc8..0d456bde0807 100644 --- a/.github/workflows/pitest.yml +++ b/.github/workflows/pitest.yml @@ -7,638 +7,36 @@ on: pull_request: jobs: - pitest-annotation: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-annotation - run: | - ./.ci/pitest.sh pitest-annotation - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-annotation-coverage-report - path: staging - retention-days: 7 - - pitest-ant: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-ant - run: | - ./.ci/pitest.sh pitest-ant - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-ant-coverage-report - path: staging - retention-days: 7 - - pitest-api: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-api - run: | - ./.ci/pitest.sh pitest-api - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-api-coverage-report - path: staging - retention-days: 7 - - pitest-blocks: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-blocks - run: | - ./.ci/pitest.sh pitest-blocks - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-blocks-coverage-report - path: staging - retention-days: 7 - - pitest-coding-1: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-Coding-1 - run: | - ./.ci/pitest.sh pitest-coding-1 - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-coding-1-coverage-report - path: staging - retention-days: 7 - - pitest-coding-2: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-Coding-2 - run: | - ./.ci/pitest.sh pitest-coding-2 - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-coding-2-coverage-report - path: staging - retention-days: 7 - - pitest-coding-require-this-check: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-Coding-require-this-check - run: | - ./.ci/pitest.sh pitest-coding-require-this-check - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-coding-require-this-check-coverage-report - path: staging - retention-days: 7 - - pitest-common: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-common - run: | - ./.ci/pitest.sh pitest-common - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-common-coverage-report - path: staging - retention-days: 7 - - pitest-common-2: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-common-2 - run: | - ./.ci/pitest.sh pitest-common-2 - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-common-2-coverage-report - path: staging - retention-days: 7 - - pitest-design: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-design - run: | - ./.ci/pitest.sh pitest-design - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-design-coverage-report - path: staging - retention-days: 7 - - pitest-filters: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-filters - run: | - ./.ci/pitest.sh pitest-filters - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-filters-coverage-report - path: staging - retention-days: 7 - - pitest-header: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-header - run: | - ./.ci/pitest.sh pitest-header - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-header-coverage-report - path: staging - retention-days: 7 - - pitest-imports: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-imports - run: | - ./.ci/pitest.sh pitest-imports - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-imports-coverage-report - path: staging - retention-days: 7 - - pitest-indentation: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-indentation - run: | - ./.ci/pitest.sh pitest-indentation - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-indentation-coverage-report - path: staging - retention-days: 7 - - pitest-javadoc: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-javadoc - run: | - ./.ci/pitest.sh pitest-javadoc - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-javadoc-coverage-report - path: staging - retention-days: 7 - - pitest-main: - runs-on: ubuntu-latest + pitest: + strategy: + matrix: + profile: [ pitest-annotation, pitest-ant, pitest-api, pitest-blocks, pitest-coding-1, + pitest-coding-2,pitest-coding-require-this-check, pitest-common, + pitest-common-2, pitest-design, pitest-filters, pitest-header, pitest-imports, + pitest-indentation, pitest-javadoc, pitest-main, pitest-metrics, pitest-misc, + pitest-modifier, pitest-naming, pitest-packagenamesloader, pitest-regexp, + pitest-sizes, pitest-tree-walker, pitest-utils, pitest-whitespace, + pitest-xpath, pitest-java-ast-visitor ] + runs-on: ubuntu-latest + continue-on-error: true steps: - name: Set up JDK 11 uses: actions/setup-java@v1 with: java-version: 11 - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-main - run: | - ./.ci/pitest.sh pitest-main - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-main-coverage-report - path: staging - retention-days: 7 - - pitest-metrics: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-metrics - run: | - ./.ci/pitest.sh pitest-metrics - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-metrics-coverage-report - path: staging - retention-days: 7 - - pitest-misc: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-misc - run: | - ./.ci/pitest.sh pitest-misc - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-misc-coverage-report - path: staging - retention-days: 7 - - pitest-modifier: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-modifier - run: | - ./.ci/pitest.sh pitest-modifier - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-modifier-coverage-report - path: staging - retention-days: 7 - - pitest-naming: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-naming - run: | - ./.ci/pitest.sh pitest-naming - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-naming-coverage-report - path: staging - retention-days: 7 - - pitest-packagenamesloader: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-packagenamesloader - run: | - ./.ci/pitest.sh pitest-packagenamesloader - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-packagenamesloader-coverage-report - path: staging - retention-days: 7 - - pitest-regexp: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-regexp - run: | - ./.ci/pitest.sh pitest-regexp - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-regexp-coverage-report - path: staging - retention-days: 7 - - pitest-sizes: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-sizes - run: | - ./.ci/pitest.sh pitest-sizes - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-sizes-coverage-report - path: staging - retention-days: 7 - - pitest-tree-walker: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-tree-walker - run: | - ./.ci/pitest.sh pitest-tree-walker - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-tree-walker-coverage-report - path: staging - retention-days: 7 - - pitest-utils: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 + - name: Download Groovy 4.0.3 + uses: sdkman/sdkman-action@master + id: sdkman with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-utils - run: | - ./.ci/pitest.sh pitest-utils - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' + candidate: groovy + version: 4.0.3 + - name: Set up Groovy 4.0.3 run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-utils-coverage-report - path: staging - retention-days: 7 - - pitest-whitespace: - runs-on: ubuntu-latest - steps: + unzip ${{ steps.sdkman.outputs.file }} -d ${{ runner.temp }}; + mv ${{ runner.temp }}/groovy-4.0.3 ${{ runner.temp }}/groovy + GROOVY_HOME=${{ runner.temp }}/groovy + echo "GROOVY_HOME=${{ runner.temp }}/groovy" >> $GITHUB_ENV + echo "$GROOVY_HOME/bin" >> $GITHUB_PATH - name: Setup local maven cache uses: actions/cache@v2 with: @@ -646,34 +44,19 @@ jobs: key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - name: Checkout uses: actions/checkout@v2 - - name: pitest-whitespace + - name: Generate ${{ matrix.profile }} report run: | - ./.ci/pitest.sh pitest-whitespace - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' + mvn -e --no-transfer-progress -P"${{ matrix.profile }}" clean test-compile \ + org.pitest:pitest-maven:mutationCoverage + - name: Check ${{ matrix.profile }} with XML report + id: pitest-xml-model run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-whitespace-coverage-report - path: staging - retention-days: 7 - - pitest-xpath: - runs-on: ubuntu-latest - steps: - - name: Setup local maven cache - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: checkstyle-maven-cache-${{ hashFiles('**/pom.xml') }} - - name: Checkout - uses: actions/checkout@v2 - - name: pitest-xpath + groovy ./.ci/pitest-survival-check-xml.groovy ${{ matrix.profile }} + - name: Check ${{ matrix.profile }} with HTML report + id: pitest-html-model + if: steps.pitest-xml-model.outcome == 'failure' || steps.pitest-xml-model.outcome == 'success' run: | - ./.ci/pitest.sh pitest-xpath + ./.ci/pitest-survival-check-html.sh ${{ matrix.profile }} - name: Stage results if: failure() || github.ref == 'refs/heads/master' run: | @@ -682,31 +65,6 @@ jobs: if: failure() || github.ref == 'refs/heads/master' uses: actions/upload-artifact@v2 with: - name: pitest-xpath-coverage-report + name: ${{ matrix.profile }}-coverage-report path: staging retention-days: 7 - - pitest-java-ast-visitor: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: ${{ github.event.pull_request.head.sha }} - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - java-version: 11 - - - name: Generate pitest report - run: ./.ci/pitest.sh pitest-java-ast-visitor - - name: Stage results - if: failure() || github.ref == 'refs/heads/master' - run: | - mkdir staging && cp -r target/pit-reports/ staging - - name: Archive code coverage results - if: failure() || github.ref == 'refs/heads/master' - uses: actions/upload-artifact@v2 - with: - name: pitest-report-java-ast-visitor - path: staging - retention-days: 7 diff --git a/config/checkstyle_non_main_files_suppressions.xml b/config/checkstyle_non_main_files_suppressions.xml index 1fa3e6ec94b2..6f37259dc4d8 100644 --- a/config/checkstyle_non_main_files_suppressions.xml +++ b/config/checkstyle_non_main_files_suppressions.xml @@ -76,7 +76,7 @@ + files=".ci[\\/]pitest-survival-check-html.sh"/> @@ -87,6 +87,9 @@ + + + diff --git a/pom.xml b/pom.xml index 4081c73f37aa..78a4d43e44c0 100644 --- a/pom.xml +++ b/pom.xml @@ -216,6 +216,7 @@ 11 1.8.0 10 + HTML,XML 50000 4 0.16 @@ -2384,6 +2385,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -2428,6 +2430,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -2472,6 +2475,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -2561,6 +2565,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -2663,6 +2668,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -2707,6 +2713,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -2751,6 +2758,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -2795,6 +2803,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -2839,6 +2848,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -2884,6 +2894,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -2938,6 +2949,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -2982,6 +2994,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3026,6 +3039,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3070,6 +3084,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3114,6 +3129,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3158,6 +3174,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3202,6 +3219,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3247,6 +3265,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3288,6 +3307,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3373,6 +3393,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3435,6 +3456,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3476,6 +3498,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3569,6 +3592,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3626,6 +3650,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3672,6 +3697,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3781,6 +3807,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3825,6 +3852,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3899,6 +3927,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats} @@ -3944,6 +3973,7 @@ ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} + ${pitest.plugin.output.formats}