-
-
Notifications
You must be signed in to change notification settings - Fork 152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add timeout as configurable coverage criteria #1118
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ module Mutant | |
# to current environment is being represented by the Mutant::Env object. | ||
class Config | ||
include Adamantium::Flat, Anima.new( | ||
:coverage_criteria, | ||
:expression_parser, | ||
:fail_fast, | ||
:includes, | ||
|
@@ -24,32 +25,6 @@ class Config | |
define_method(:"#{name}?") { public_send(name) } | ||
end | ||
|
||
boolean = Transform::Boolean.new | ||
float = Transform::Primitive.new(Float) | ||
integer = Transform::Primitive.new(Integer) | ||
string = Transform::Primitive.new(String) | ||
|
||
string_array = Transform::Array.new(string) | ||
|
||
TRANSFORM = Transform::Sequence.new( | ||
[ | ||
Transform::Exception.new(SystemCallError, :read.to_proc), | ||
Transform::Exception.new(YAML::SyntaxError, YAML.method(:safe_load)), | ||
Transform::Hash.new( | ||
optional: [ | ||
Transform::Hash::Key.new('fail_fast', boolean), | ||
Transform::Hash::Key.new('includes', string_array), | ||
Transform::Hash::Key.new('integration', string), | ||
Transform::Hash::Key.new('jobs', integer), | ||
Transform::Hash::Key.new('mutation_timeout', float), | ||
Transform::Hash::Key.new('requires', string_array) | ||
], | ||
required: [] | ||
), | ||
Transform::Hash::Symbolize.new | ||
] | ||
) | ||
|
||
MORE_THAN_ONE_CONFIG_FILE = <<~'MESSAGE' | ||
Found more than one candidate for use as implicit config file: %s | ||
MESSAGE | ||
|
@@ -60,6 +35,32 @@ class Config | |
mutant.yml | ||
].freeze | ||
|
||
private_constant(*constants(false)) | ||
|
||
class CoverageCriteria | ||
include Anima.new(:timeout, :test_result) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dgollahon The next step is to allow to configure the coverage criteria per subject in the config file an in-line. Same for the mutation timeout. The ideal setting than is a global "high" timeout with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also there are more possible criteria like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And the most important criteria for @pawelpacana counting ruby aborts as killed. Next major feature for 0.10.8. The infrastructure exists now. Per subject config will be added in 0.10.9 possibly also in-line configuration. |
||
|
||
DEFAULT = new( | ||
timeout: false, | ||
test_result: true | ||
) | ||
|
||
TRANSFORM = | ||
Transform::Sequence.new( | ||
[ | ||
Transform::Hash.new( | ||
optional: [ | ||
Transform::Hash::Key.new('timeout', Transform::BOOLEAN), | ||
Transform::Hash::Key.new('test_result', Transform::BOOLEAN) | ||
], | ||
required: [] | ||
), | ||
Transform::Hash::Symbolize.new, | ||
->(value) { Either::Right.new(DEFAULT.with(**value)) } | ||
] | ||
) | ||
end # CoverageCriteria | ||
|
||
# Merge with other config | ||
# | ||
# @param [Config] other | ||
|
@@ -68,18 +69,16 @@ class Config | |
def merge(other) | ||
other.with( | ||
fail_fast: fail_fast || other.fail_fast, | ||
includes: includes + other.includes, | ||
includes: other.includes + includes, | ||
jobs: other.jobs || jobs, | ||
integration: other.integration || integration, | ||
mutation_timeout: other.mutation_timeout || mutation_timeout, | ||
matcher: matcher.merge(other.matcher), | ||
requires: requires + other.requires, | ||
requires: other.requires + requires, | ||
zombie: zombie || other.zombie | ||
) | ||
end | ||
|
||
private_constant(*constants(false)) | ||
|
||
# Load config file | ||
# | ||
# @param [World] world | ||
|
@@ -113,5 +112,27 @@ def self.load_contents(path) | |
def self.env | ||
DEFAULT.with(jobs: Etc.nprocessors) | ||
end | ||
|
||
TRANSFORM = Transform::Sequence.new( | ||
[ | ||
Transform::Exception.new(SystemCallError, :read.to_proc), | ||
Transform::Exception.new(YAML::SyntaxError, YAML.method(:safe_load)), | ||
Transform::Hash.new( | ||
optional: [ | ||
Transform::Hash::Key.new('coverage_criteria', CoverageCriteria::TRANSFORM), | ||
Transform::Hash::Key.new('fail_fast', Transform::BOOLEAN), | ||
Transform::Hash::Key.new('includes', Transform::STRING_ARRAY), | ||
Transform::Hash::Key.new('integration', Transform::STRING), | ||
Transform::Hash::Key.new('jobs', Transform::INTEGER), | ||
Transform::Hash::Key.new('mutation_timeout', Transform::FLOAT), | ||
Transform::Hash::Key.new('requires', Transform::STRING_ARRAY) | ||
], | ||
required: [] | ||
), | ||
Transform::Hash::Symbolize.new | ||
] | ||
) | ||
|
||
private_constant(:TRANSFORM) | ||
end # Config | ||
end # Mutant |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# frozen_string_literal: true | ||
|
||
module Mutant | ||
class Reporter | ||
class CLI | ||
class Printer | ||
# Reporter for mutation coverage results | ||
class CoverageResult < self | ||
# Run report printer | ||
# | ||
# @return [undefined] | ||
def run | ||
visit(MutationResult, object.mutation_result) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a pass through ATM, I could evision a verbose mode where we show covered mutations, and tell why they where killed. |
||
end | ||
end # Printer | ||
end # Coverage | ||
end # CLI | ||
end # Reporter | ||
end # Mutant |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ class Printer | |
# Subject result printer | ||
class SubjectResult < self | ||
|
||
delegate :subject, :alive_mutation_results, :tests | ||
delegate :subject, :uncovered_results, :tests | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm slowly moving the wording away from "alive" and "killed" to "uncovered" and "covered". |
||
|
||
# Run report printer | ||
# | ||
|
@@ -17,7 +17,7 @@ def run | |
tests.each do |test| | ||
puts("- #{test.identification}") | ||
end | ||
visit_collection(MutationResult, alive_mutation_results) | ||
visit_collection(CoverageResult, uncovered_results) | ||
end | ||
|
||
end # SubjectResult | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to set this via CLI flag? Once we have per-subject / per file config then customizing it that way would be good but I am thinking of doing something like having the fork abort coverage off in my local config (so I can find and report bugs) but considering it as a kill in CI so that PRs are never gated by segfaults.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allowing to configure each subject separately is the next step.
But: Its unlikely it makes sense in the CLI, simply because the CLI would become very long. My next initiative would be to support inheriting (prefix match) based per subject configuration in the code, and use the config file as input.
Than the overnext step to support it from in-line code comments.
Only after that I'll consider making CLI (per subject) support for these.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, yeah, I think that makes sense. Looking forward to it 👍