free_mutant/lib/mutant/runner.rb

188 lines
3.6 KiB
Ruby
Raw Normal View History

2012-08-14 16:45:34 -04:00
module Mutant
2013-04-20 14:50:36 -04:00
# Runner baseclass
2012-08-14 16:45:34 -04:00
class Runner
2014-07-17 09:59:25 -04:00
include Adamantium::Flat, Concord.new(:env), Procto.call(:result)
# Initialize object
#
# @return [undefined]
#
# @api private
#
def initialize(env)
super
2014-07-17 09:59:25 -04:00
@collector = Collector.new(env)
@mutex = Mutex.new
@mutations = env.mutations.dup
config.integration.setup
config.reporter.start(env)
2014-07-17 09:59:25 -04:00
run
2014-07-17 09:59:25 -04:00
@result = @collector.result.update(done: true)
config.reporter.report(result)
end
# Return result
#
# @return [Result::Env]
#
# @api private
#
attr_reader :result
private
2014-07-17 09:59:25 -04:00
# Run mutation analysis
2012-08-16 13:26:15 -04:00
#
# @return [Report::Subject]
2012-08-16 13:26:15 -04:00
#
# @api private
#
2014-07-17 09:59:25 -04:00
def run
Parallel.map(
@mutations,
in_threads: config.jobs,
finish: method(:finish),
start: method(:start),
2014-07-17 09:59:25 -04:00
&method(:run_mutation)
)
end
# Handle started mutation
#
# @param [Mutation] mutation
# @param [Fixnum] _index
#
# @return [undefined]
#
# @api private
#
def start(mutation, _index)
@mutex.synchronize do
@collector.start(mutation)
end
2013-01-15 17:46:05 -05:00
end
2014-07-17 09:59:25 -04:00
# Handle finished mutation
#
# @param [Mutation] mutation
# @param [Fixnum] index
# @param [Object] result
#
# @return [undefined]
#
# @api private
#
def finish(mutation, index, result)
return unless result.kind_of?(Mutant::Result::Mutation)
test_results = result.test_results.zip(mutation.subject.tests).map do |test_result, test|
test_result.update(test: test, mutation: mutation) if test_result
end.compact
@mutex.synchronize do
process_result(result.update(index: index, mutation: mutation, test_results: test_results))
end
end
# Process result
#
# @param [Result::Mutation] result
#
# @return [undefined]
#
# @api private
#
def process_result(result)
@collector.finish(result)
config.reporter.progress(@collector)
handle_exit(result)
end
# Handle exit if needed
#
2014-08-12 19:20:34 -04:00
# @param [Result::Mutation] result
2014-07-17 09:59:25 -04:00
#
# @return [undefined]
#
# @api private
#
def handle_exit(result)
return if !config.fail_fast || result.success?
@mutations.clear
end
# Run mutation
#
2014-07-17 09:59:25 -04:00
# @param [Mutation] mutation
#
# @return [Report::Mutation]
#
2013-07-15 04:47:44 -04:00
# @api private
#
def run_mutation(mutation)
Result::Mutation.compute do
{
2014-07-17 09:59:25 -04:00
index: nil,
mutation: nil,
test_results: kill_mutation(mutation)
}
end
end
# Kill mutation
#
# @param [Mutation] mutation
#
# @return [Array<Result::Test>]
#
# @api private
#
def kill_mutation(mutation)
mutation.subject.tests.each_with_object([]) do |test, results|
2014-07-17 09:59:25 -04:00
results << result = run_mutation_test(mutation, test)
return results if mutation.killed_by?(result)
end
end
# Return config
#
# @return [Config]
#
# @api private
#
def config
env.config
end
# Return test result
#
# @return [Report::Test]
#
# @api private
#
def run_mutation_test(mutation, test)
time = Time.now
config.isolation.call do
mutation.insert
test.run
2014-07-17 09:59:25 -04:00
end
rescue Isolation::Error => exception
Result::Test.new(
2014-07-17 09:59:25 -04:00
test: nil,
mutation: nil,
runtime: Time.now - time,
output: exception.message,
passed: false
)
end
2013-06-14 14:54:02 -04:00
end # Runner
end # Mutant