free_mutant/lib/mutant/isolation.rb

66 lines
1.4 KiB
Ruby
Raw Normal View History

2014-06-08 13:55:13 -04:00
module Mutant
# Module providing isolation
2014-06-08 13:55:13 -04:00
module Isolation
Error = Class.new(RuntimeError)
module None
# Call block in isolation
#
# @return [Object]
#
# @raise [Error]
# if block terminates abnormal
#
# @api private
#
def self.call(&block)
block.call
rescue => exception
2014-12-21 20:28:30 -05:00
raise Error, exception
end
2014-06-08 13:55:13 -04:00
end
module Fork
# Call block in isolation
#
# This isolation implements the fork strategy.
# Future strategies will probably use a process pool that can
# handle multiple mutation kills, in-isolation at once.
#
# @return [Object]
# returns block execution result
#
# @raise [Error]
# if block terminates abnormal
#
# @api private
#
2014-12-21 20:28:30 -05:00
# rubocop:disable MethodLength
#
def self.call(&block)
2014-12-08 17:57:53 -05:00
reader, writer = IO.pipe.map(&:binmode)
pid = Process.fork do
File.open('/dev/null', 'w') do |file|
$stderr.reopen(file)
reader.close
writer.write(Marshal.dump(block.call))
writer.close
end
end
writer.close
2014-10-23 07:37:53 -04:00
Marshal.load(reader.read)
rescue => exception
2014-12-21 20:28:30 -05:00
raise Error, exception
ensure
Process.waitpid(pid) if pid
end
end # Fork
2014-06-08 13:55:13 -04:00
end # Isolator
end # Mutant