Module: Henitai::Integration::MutantRunSupport

Included in:
Minitest, Rspec
Defined in:
lib/henitai/integration/mutant_run_support.rb,
sig/henitai.rbs

Overview

Framework-agnostic orchestration for running a single mutant in a child process and turning the captured child output into a ScenarioExecutionResult.

The framework-specific test invocation is delegated to #run_tests, which including classes must implement.

Instance Method Summary collapse

Instance Method Details

#build_result(wait_result, log_paths) ⇒ ScenarioExecutionResult

Parameters:

  • (Object)
  • (Hash[Symbol, String])

Returns:



32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/henitai/integration/mutant_run_support.rb', line 32

def build_result(wait_result, log_paths)
  stdout = scenario_log_support.read_log_file(log_paths[:stdout_path])
  stderr = scenario_log_support.read_log_file(log_paths[:stderr_path])
  scenario_log_support.write_combined_log(log_paths[:log_path], stdout, stderr)

  ScenarioExecutionResult.build(
    wait_result:,
    stdout:,
    stderr:,
    log_path: log_paths[:log_path]
  )
end

#mutant_log_name(mutant) ⇒ String

Parameters:

Returns:

  • (String)


57
58
59
# File 'lib/henitai/integration/mutant_run_support.rb', line 57

def mutant_log_name(mutant)
  "mutant-#{mutant.id}"
end

#run_child_activation_and_tests(mutant:, test_files:, log_paths:) ⇒ Integer

Parameters:

  • mutant: (Mutant)
  • test_files: (Array[String])
  • log_paths: (Hash[Symbol, String])

Returns:

  • (Integer)


63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/henitai/integration/mutant_run_support.rb', line 63

def run_child_activation_and_tests(mutant:, test_files:, log_paths:)
  scenario_log_support.with_coverage_dir(mutant.id) do
    scenario_log_support.capture_child_output(log_paths) do
      debug_child_mutant_meta(mutant) if debug_child?
      debug_child_activation_start(mutant.id)
      activation_result = Mutant::Activator.activate!(mutant)
      debug_child_activation_check if debug_child?
      debug_child_activation_end(activation_result, test_files:)
      activation_result == :compile_error ? 2 : run_tests(test_files)
    end
  end
end

#run_in_child(mutant:, test_files:, log_paths:) ⇒ Integer

Parameters:

  • mutant: (Mutant)
  • test_files: (Array[String])
  • log_paths: (Hash[Symbol, String])

Returns:

  • (Integer)


45
46
47
48
49
50
51
52
53
54
55
# File 'lib/henitai/integration/mutant_run_support.rb', line 45

def run_in_child(mutant:, test_files:, log_paths:)
  Thread.report_on_exception = false
  with_subprocess_env do
    suppress_simplecov!
    suppress_coverage!
    install_debug_timeout_trap if debug_child?
    with_non_interactive_stdin do
      run_child_activation_and_tests(mutant:, test_files:, log_paths:)
    end
  end
end

#run_mutant(mutant:, test_files:, timeout:) ⇒ ScenarioExecutionResult

Parameters:

  • mutant: (Mutant)
  • test_files: (Array[String])
  • timeout: (Float)

Returns:



18
19
20
# File 'lib/henitai/integration/mutant_run_support.rb', line 18

def run_mutant(mutant:, test_files:, timeout:)
  RspecProcessRunner.new.run_mutant(self, mutant:, test_files:, timeout:)
end

#scenario_log_paths(name) ⇒ Hash[Symbol, String]

Parameters:

  • (String)

Returns:

  • (Hash[Symbol, String])


22
23
24
25
26
27
28
29
30
# File 'lib/henitai/integration/mutant_run_support.rb', line 22

def scenario_log_paths(name)
  reports_dir = ENV.fetch("HENITAI_REPORTS_DIR", "reports")
  log_dir = File.join(reports_dir, "mutation-logs")
  {
    stdout_path: File.join(log_dir, "#{name}.stdout.log"),
    stderr_path: File.join(log_dir, "#{name}.stderr.log"),
    log_path: File.join(log_dir, "#{name}.log")
  }
end

#spawn_mutant(mutant:, test_files:) ⇒ ChildHandle

Parameters:

  • mutant: (Mutant)
  • test_files: (Array[String])

Returns:



13
14
15
16
# File 'lib/henitai/integration/mutant_run_support.rb', line 13

def spawn_mutant(mutant:, test_files:)
  log_paths = scenario_log_paths(mutant_log_name(mutant))
  RspecProcessRunner.new.spawn_mutant(self, mutant:, test_files:, log_paths:)
end