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.
15 16 17 |
# File 'lib/evilution/isolation/fork.rb', line 15 def initialize(hooks: nil) @hooks = hooks end |
Instance Method Details
#call(mutation:, test_command:, timeout:) ⇒ Object
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 54 55 |
# File 'lib/evilution/isolation/fork.rb', line 19 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 FileUtils.rm_rf(sandbox_dir) if sandbox_dir end |