Class: Evilution::Isolation::Fork
- Inherits:
-
Object
- Object
- Evilution::Isolation::Fork
- Defined in:
- lib/evilution/isolation/fork.rb
Constant Summary collapse
- GRACE_PERIOD =
2
Instance Method Summary collapse
- #call(mutation:, test_command:, timeout:) ⇒ Object
-
#initialize(hooks: nil) ⇒ Fork
constructor
A new instance of Fork.
Constructor Details
#initialize(hooks: nil) ⇒ Fork
Returns a new instance of Fork.
13 14 15 |
# File 'lib/evilution/isolation/fork.rb', line 13 def initialize(hooks: nil) @hooks = hooks end |
Instance Method Details
#call(mutation:, test_command:, timeout:) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/evilution/isolation/fork.rb', line 17 def call(mutation:, test_command:, timeout:) pid = nil sandbox_dir = Dir.mktmpdir("evilution-run") start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) parent_rss = Evilution::Memory.rss_kb read_io, write_io = IO.pipe # Marshal result payload is ASCII-8BIT; pipes default to text mode and may # transcode according to their external/internal encodings (influenced by # Encoding.default_external and/or Encoding.default_internal — Rails sets # the latter to UTF-8), failing on bytes with no mapping. Force binmode on # both ends. read_io.binmode write_io.binmode pid = ::Process.fork do ENV["TMPDIR"] = sandbox_dir read_io.close suppress_child_output @hooks.fire(:worker_process_start, mutation: mutation) if @hooks result = execute_in_child(mutation, test_command) Marshal.dump(result, write_io) write_io.close exit!(result[:passed] ? 0 : 1) end write_io.close result = wait_for_result(pid, read_io, timeout) duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time build_mutation_result(mutation, result, duration, parent_rss) ensure read_io&.close write_io&.close ensure_reaped(pid) restore_original_source(mutation) FileUtils.rm_rf(sandbox_dir) if sandbox_dir end |