Skip to content

Commit

Permalink
Add support for not covered mutants
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexDenisov committed Jan 9, 2021
1 parent f30e421 commit c67178e
Show file tree
Hide file tree
Showing 48 changed files with 199 additions and 84 deletions.
2 changes: 2 additions & 0 deletions docs/generated/CLIOptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@

--coverage-info string Path to the coverage info file (LLVM's profdata)

--include-not-covered Include (but do not run) not covered mutants. Disabled by default

--include-path regex File/directory paths to whitelist (supports regex)

--exclude-path regex File/directory paths to ignore (supports regex)
Expand Down
1 change: 1 addition & 0 deletions include/mull/Config/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ struct Configuration {
bool captureTestOutput;
bool captureMutantOutput;
bool skipSanityCheckRun;
bool includeNotCovered;

int timeout;
unsigned linkerTimeout;
Expand Down
5 changes: 4 additions & 1 deletion include/mull/ExecutionResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ enum ExecutionStatus {
Crashed = 4,
AbnormalExit = 5,
DryRun = 6,
FailFast = 7
FailFast = 7,
NotCovered = 8
};

static std::string executionStatusAsString(ExecutionStatus status) {
Expand All @@ -34,6 +35,8 @@ static std::string executionStatusAsString(ExecutionStatus status) {
return "DryRun";
case FailFast:
return "FailFast";
case NotCovered:
return "NotCovered";
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ class Bitcode;

class FunctionUnderTest {
public:
explicit FunctionUnderTest(llvm::Function *function, Bitcode *bitcode);
FunctionUnderTest(llvm::Function *function, Bitcode *bitcode, bool covered = true);
llvm::Function *getFunction() const;
Bitcode *getBitcode() const;
const std::vector<llvm::Instruction *> &getSelectedInstructions() const;
bool isCovered() const;
void selectInstructions(const std::vector<InstructionFilter *> &filters);

private:
llvm::Function *function;
Bitcode *bitcode;
bool covered;
std::vector<llvm::Instruction *> selectedInstructions;
};

Expand Down
1 change: 1 addition & 0 deletions include/mull/Mutant.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Mutant {
const std::string &getDiagnostics() const;
const std::string &getReplacement() const;
const std::string &getMutatorIdentifier() const;
bool isCovered() const;

private:
std::string identifier;
Expand Down
4 changes: 4 additions & 0 deletions include/mull/MutationPoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,17 @@ class MutationPoint {
const SourceLocation sourceLocation;
irm::IRMutation *irMutator;
std::string userIdentifier;
bool covered;

public:
MutationPoint(Mutator *mutator, irm::IRMutation *irMutator, llvm::Instruction *instruction,
std::string replacement, Bitcode *m, std::string diagnostics);

~MutationPoint() = default;

void setCovered(bool isCovered);
bool isCovered();

Mutator *getMutator();
Mutator *getMutator() const;

Expand Down
2 changes: 1 addition & 1 deletion include/mull/MutationsFinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#include <map>
#include <vector>

#include "FunctionUnderTest.h"
#include "MutationPoint.h"
#include "ReachableFunction.h"
#include "mull/Mutators/Mutator.h"

namespace mull {
Expand Down
2 changes: 1 addition & 1 deletion include/mull/Mutators/CXX/TrivialCXXMutator.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "mull/Mutators/Mutator.h"
#include <irm/irm.h>
#include <memory>
#include <mull/ReachableFunction.h>
#include <mull/FunctionUnderTest.h>
#include <vector>

namespace mull {
Expand Down
2 changes: 1 addition & 1 deletion include/mull/Mutators/NegateConditionMutator.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "Mutator.h"
#include <irm/irm.h>
#include <memory>
#include <mull/ReachableFunction.h>
#include <mull/FunctionUnderTest.h>
#include <vector>

namespace llvm {
Expand Down
2 changes: 1 addition & 1 deletion include/mull/Mutators/RemoveVoidFunctionMutator.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "Mutator.h"
#include <irm/irm.h>
#include <memory>
#include <mull/ReachableFunction.h>
#include <mull/FunctionUnderTest.h>
#include <vector>

namespace llvm {
Expand Down
2 changes: 1 addition & 1 deletion include/mull/Mutators/ReplaceCallMutator.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "Mutator.h"
#include <irm/irm.h>
#include <memory>
#include <mull/ReachableFunction.h>
#include <mull/FunctionUnderTest.h>
#include <vector>

namespace mull {
Expand Down
2 changes: 1 addition & 1 deletion include/mull/Mutators/ScalarValueMutator.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "Mutator.h"
#include <irm/irm.h>
#include <memory>
#include <mull/ReachableFunction.h>
#include <mull/FunctionUnderTest.h>
#include <vector>

namespace llvm {
Expand Down
2 changes: 1 addition & 1 deletion include/mull/Parallelization/Tasks/FunctionFilterTask.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "mull/ReachableFunction.h"
#include "mull/FunctionUnderTest.h"
#include <vector>

namespace mull {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "mull/ReachableFunction.h"
#include "mull/FunctionUnderTest.h"
#include <vector>

namespace mull {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#pragma once

#include "mull/FunctionUnderTest.h"
#include "mull/MutationPoint.h"
#include "mull/Mutators/Mutator.h"
#include "mull/ReachableFunction.h"

namespace mull {

Expand Down
2 changes: 1 addition & 1 deletion lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ set(mull_sources

Bitcode.cpp
MutationPoint.cpp
ReachableFunction.cpp
FunctionUnderTest.cpp

IDEDiagnostics.cpp

Expand Down
2 changes: 1 addition & 1 deletion lib/Config/Configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ unsigned MullDefaultLinkerTimeoutMilliseconds = 30000;

Configuration::Configuration()
: debugEnabled(false), dryRunEnabled(false), captureTestOutput(true), captureMutantOutput(true),
skipSanityCheckRun(false), timeout(MullDefaultTimeoutMilliseconds),
skipSanityCheckRun(false), includeNotCovered(false), timeout(MullDefaultTimeoutMilliseconds),
linkerTimeout(MullDefaultLinkerTimeoutMilliseconds), diagnostics(IDEDiagnosticsKind::None),
parallelization(singleThreadParallelization()) {}

Expand Down
7 changes: 6 additions & 1 deletion lib/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
#include "mull/Diagnostics/Diagnostics.h"
#include "mull/Filters/Filters.h"
#include "mull/Filters/FunctionFilter.h"
#include "mull/FunctionUnderTest.h"
#include "mull/Mutant.h"
#include "mull/MutationResult.h"
#include "mull/MutationsFinder.h"
#include "mull/Parallelization/Parallelization.h"
#include "mull/Program/Program.h"
#include "mull/ReachableFunction.h"
#include "mull/Result.h"
#include "mull/Toolchain/Runner.h"

Expand Down Expand Up @@ -334,10 +334,15 @@ std::vector<FunctionUnderTest> Driver::getFunctionsUnderTest() {
}
if (covered) {
functionsUnderTest.emplace_back(&function, bitcode.get());
} else if (config.includeNotCovered) {
functionsUnderTest.emplace_back(&function, bitcode.get(), false);
}
}
}
} else {
if (config.includeNotCovered) {
diagnostics.warning("-include-not-covered is enabled, but there is no coverage info!");
}
for (auto &bitcode : program.bitcode()) {
for (llvm::Function &function : *bitcode->getModule()) {
functionsUnderTest.emplace_back(&function, bitcode.get());
Expand Down
10 changes: 7 additions & 3 deletions lib/ReachableFunction.cpp → lib/FunctionUnderTest.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#include "mull/ReachableFunction.h"
#include "mull/FunctionUnderTest.h"
#include "mull/Filters/InstructionFilter.h"

#include <llvm/IR/InstIterator.h>

using namespace mull;

FunctionUnderTest::FunctionUnderTest(llvm::Function *function, Bitcode *bitcode)
: function(function), bitcode(bitcode) {}
FunctionUnderTest::FunctionUnderTest(llvm::Function *function, Bitcode *bitcode, bool covered)
: function(function), bitcode(bitcode), covered(covered) {}

llvm::Function *FunctionUnderTest::getFunction() const {
return function;
Expand All @@ -20,6 +20,10 @@ const std::vector<llvm::Instruction *> &FunctionUnderTest::getSelectedInstructio
return selectedInstructions;
}

bool FunctionUnderTest::isCovered() const {
return covered;
}

void FunctionUnderTest::selectInstructions(const std::vector<InstructionFilter *> &filters) {
for (llvm::Instruction &instruction : llvm::instructions(function)) {
bool selected = true;
Expand Down
10 changes: 10 additions & 0 deletions lib/Mutant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ const std::string &Mutant::getReplacement() const {
return points.front()->getReplacement();
}

bool Mutant::isCovered() const {
for (MutationPoint *point : points) {
/// Consider a mutant covered if at least one of the mutation points is covered
if (point->isCovered()) {
return true;
}
}
return false;
}

bool MutantComparator::operator()(std::unique_ptr<Mutant> &lhs, std::unique_ptr<Mutant> &rhs) {
return operator()(*lhs, *rhs);
}
Expand Down
8 changes: 8 additions & 0 deletions lib/MutationPoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ MutationPoint::MutationPoint(Mutator *mutator, irm::IRMutation *irMutator,
std::to_string(sourceLocation.column);
}

void MutationPoint::setCovered(bool isCovered) {
covered = isCovered;
}

bool MutationPoint::isCovered() {
return covered;
}

Mutator *MutationPoint::getMutator() {
return mutator;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/MutationsFinder.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "mull/MutationsFinder.h"

#include "mull/Config/Configuration.h"
#include "mull/FunctionUnderTest.h"
#include "mull/Parallelization/Parallelization.h"
#include "mull/Program/Program.h"
#include "mull/ReachableFunction.h"

using namespace mull;
using namespace llvm;
Expand Down
2 changes: 1 addition & 1 deletion lib/Mutators/CXX/LogicalAndToOr.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "mull/Mutators/CXX/LogicalAndToOr.h"

#include "mull/FunctionUnderTest.h"
#include "mull/MutationPoint.h"
#include "mull/ReachableFunction.h"
#include "mull/SourceLocation.h"

#include <iterator>
Expand Down
2 changes: 1 addition & 1 deletion lib/Mutators/CXX/LogicalOrToAnd.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "mull/Mutators/CXX/LogicalOrToAnd.h"

#include "mull/FunctionUnderTest.h"
#include "mull/MutationPoint.h"
#include "mull/ReachableFunction.h"
#include "mull/SourceLocation.h"

#include <iterator>
Expand Down
2 changes: 1 addition & 1 deletion lib/Mutators/CXX/TrivialCXXMutator.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "mull/Mutators/CXX/TrivialCXXMutator.h"
#include "mull/FunctionUnderTest.h"
#include "mull/MutationPoint.h"
#include "mull/ReachableFunction.h"
#include <irm/irm.h>

using namespace mull;
Expand Down
2 changes: 1 addition & 1 deletion lib/Mutators/NegateConditionMutator.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "mull/Mutators/NegateConditionMutator.h"
#include "mull/FunctionUnderTest.h"
#include "mull/MutationPoint.h"
#include "mull/ReachableFunction.h"
#include <cassert>
#include <irm/irm.h>
#include <sstream>
Expand Down
2 changes: 1 addition & 1 deletion lib/Mutators/RemoveVoidFunctionMutator.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "mull/Mutators/RemoveVoidFunctionMutator.h"
#include "mull/FunctionUnderTest.h"
#include "mull/MutationPoint.h"
#include "mull/ReachableFunction.h"
#include <irm/irm.h>
#include <llvm/IR/Instructions.h>
#include <sstream>
Expand Down
2 changes: 1 addition & 1 deletion lib/Mutators/ReplaceCallMutator.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "mull/Mutators/ReplaceCallMutator.h"
#include "mull/FunctionUnderTest.h"
#include "mull/MutationPoint.h"
#include "mull/ReachableFunction.h"
#include <cassert>
#include <irm/irm.h>
#include <llvm/IR/Instructions.h>
Expand Down
2 changes: 1 addition & 1 deletion lib/Mutators/ScalarValueMutator.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "mull/Mutators/ScalarValueMutator.h"
#include "mull/FunctionUnderTest.h"
#include "mull/MutationPoint.h"
#include "mull/ReachableFunction.h"
#include <irm/irm.h>

using namespace llvm;
Expand Down
4 changes: 3 additions & 1 deletion lib/Parallelization/Tasks/ApplyMutationTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ void ApplyMutationTask::operator()(iterator begin, iterator end, Out &storage,
progress_counter &counter) {
for (auto it = begin; it != end; ++it, counter.increment()) {
auto point = *it;
point->applyMutation();
if (point->isCovered()) {
point->applyMutation();
}
}
}
2 changes: 1 addition & 1 deletion lib/Parallelization/Tasks/InstructionSelectionTask.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "mull/Parallelization/Tasks/InstructionSelectionTask.h"
#include "mull/FunctionUnderTest.h"
#include "mull/Parallelization/Progress.h"
#include "mull/ReachableFunction.h"
#include <cassert>

using namespace mull;
Expand Down
16 changes: 10 additions & 6 deletions lib/Parallelization/Tasks/MutantExecutionTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@ void MutantExecutionTask::operator()(iterator begin, iterator end, Out &storage,
Runner runner(diagnostics);
for (auto it = begin; it != end; ++it, counter.increment()) {
auto &mutant = *it;
ExecutionResult result = runner.runProgram(executable,
{},
{ mutant->getIdentifier() },
baseline.runningTime * 10,
configuration.captureMutantOutput);

ExecutionResult result;
if (mutant->isCovered()) {
result = runner.runProgram(executable,
{},
{ mutant->getIdentifier() },
baseline.runningTime * 10,
configuration.captureMutantOutput);
} else {
result.status = NotCovered;
}
storage.push_back(std::make_unique<MutationResult>(result, mutant.get()));
}
}
Loading

0 comments on commit c67178e

Please sign in to comment.