class Mutest::Isolation::Fork
Isolation
via the fork(2) systemcall.
We do inject so many globals and common patterns to make this unit specifiable without mocking the globals and more important: Not having mutations that bypass mocks into a real world side effect.
Public Instance Methods
call(&block)
click to toggle source
Call block in isolation
@return [Object]
returns block execution result
@raise [Error]
if block terminates abnormal
# File lib/mutest/isolation/fork.rb, line 21 def call(&block) io.pipe(binmode: true) do |pipes| parent(*pipes, &block) end rescue StandardError => exception raise Error, exception end
child(reader, writer, &block)
click to toggle source
Handle child process
@param [IO] reader @param [IO] writer
@return [undefined]
# File lib/mutest/isolation/fork.rb, line 53 def child(reader, writer, &block) reader.close writer.binmode writer.syswrite(marshal.dump(result(&block))) writer.close end
parent(reader, writer, &block)
click to toggle source
Handle parent process
@param [IO] reader @param [IO] writer
@return [undefined]
# File lib/mutest/isolation/fork.rb, line 35 def parent(reader, writer, &block) pid = process.fork do child(reader, writer, &block) end writer.close marshal.load(reader) ensure process.waitpid(pid) if pid end
result() { || ... }
click to toggle source
The block result computed under silencing
@return [Object]
# File lib/mutest/isolation/fork.rb, line 63 def result devnull.call do |null| stderr.reopen(null) stdout.reopen(null) yield end end