Class: Henitai::Integration::ChildDebugLog
- Inherits:
-
Object
- Object
- Henitai::Integration::ChildDebugLog
- Defined in:
- lib/henitai/integration/child_debug_log.rb,
sig/henitai.rbs
Overview
Diagnostics writer for the mutant child process, gated on
HENITAI_DEBUG_CHILD=1.
Every method gates on #enabled? itself rather than trusting call sites, so no unguarded caller can leak debug lines into every child log by default.
Constant Summary collapse
- PREFIX =
"[henitai-debug-child]"
Instance Method Summary collapse
-
#activation_check ⇒ void
Reports where Runner#resolve_subjects was loaded from, which is how a child that activated a mutant on Henitai's own source is identified.
- #activation_end(activation_result, test_files:) ⇒ void
- #activation_start(mutant_id) ⇒ void
- #dump_thread(thread, index) ⇒ void
- #enabled? ⇒ Boolean
- #example_count(stage) ⇒ void
-
#initialize(io: nil, loaded_features: LoadedFeatures.new) ⇒ ChildDebugLog
constructor
A new instance of ChildDebugLog.
-
#io ⇒ IO
Resolved per call, never memoized: ScenarioLogSupport#capture_child_output reassigns $stdout inside the child after this object is built, so a captured-at-construction stream would send every debug line to the parent's terminal instead of the child's log file.
-
#location_of(mutant) ⇒ String?
Deliberately
.inspectinside the ternary, not on the result: a mutant without #location must render as empty, not as the string "nil". - #mutant_meta(mutant) ⇒ void
- #rspec_exit(status) ⇒ void
- #rspec_trace(test_files:, rspec_options:, rspec_argv:) ⇒ Object
- #rspec_world_example_count ⇒ Integer?
- #subject_expression_of(mutant) ⇒ String?
- #thread_dump(reason) ⇒ void
- #timeout_signal_sent(pid) ⇒ void
- #value_of(mutant, name) ⇒ Object
- #write(message) ⇒ void
Constructor Details
#initialize(io: nil, loaded_features: LoadedFeatures.new) ⇒ ChildDebugLog
Returns a new instance of ChildDebugLog.
16 17 18 19 |
# File 'lib/henitai/integration/child_debug_log.rb', line 16 def initialize(io: nil, loaded_features: LoadedFeatures.new) @io = io @loaded_features = loaded_features end |
Instance Method Details
#activation_check ⇒ void
This method returns an undefined value.
Reports where Runner#resolve_subjects was loaded from, which is how a child that activated a mutant on Henitai's own source is identified.
77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/henitai/integration/child_debug_log.rb', line 77 def activation_check return unless enabled? location = begin Henitai::Runner.instance_method(:resolve_subjects).source_location&.join(":") # henitai:disable rescue StandardError nil end write("#{PREFIX} activation_check resolve_subjects_location=#{location}\n") end |
#activation_end(activation_result, test_files:) ⇒ void
This method returns an undefined value.
57 58 59 60 61 62 |
# File 'lib/henitai/integration/child_debug_log.rb', line 57 def activation_end(activation_result, test_files:) write( "#{PREFIX} activate_end result=#{activation_result.inspect}\n" \ "#{PREFIX} run_tests_start test_files=#{test_files.inspect}" ) end |
#activation_start(mutant_id) ⇒ void
This method returns an undefined value.
53 54 55 |
# File 'lib/henitai/integration/child_debug_log.rb', line 53 def activation_start(mutant_id) write("#{PREFIX} activate_start mutant=#{mutant_id}") end |
#dump_thread(thread, index) ⇒ void
This method returns an undefined value.
108 109 110 111 112 113 114 |
# File 'lib/henitai/integration/child_debug_log.rb', line 108 def dump_thread(thread, index) write( "#{PREFIX} thread index=#{index} id=#{thread.object_id} " \ "status=#{thread.status.inspect}" ) Array(thread.backtrace).each { |line| write("#{PREFIX} #{line}") } end |
#enabled? ⇒ Boolean
21 |
# File 'lib/henitai/integration/child_debug_log.rb', line 21 def enabled? = ENV["HENITAI_DEBUG_CHILD"] == "1" |
#example_count(stage) ⇒ void
This method returns an undefined value.
47 48 49 50 51 |
# File 'lib/henitai/integration/child_debug_log.rb', line 47 def example_count(stage) return unless enabled? write("#{PREFIX} rspec_world_example_count_#{stage}=#{rspec_world_example_count.inspect}") end |
#io ⇒ IO
Resolved per call, never memoized: ScenarioLogSupport#capture_child_output reassigns $stdout inside the child after this object is built, so a captured-at-construction stream would send every debug line to the parent's terminal instead of the child's log file.
132 |
# File 'lib/henitai/integration/child_debug_log.rb', line 132 def io = @io || $stdout |
#location_of(mutant) ⇒ String?
Deliberately .inspect inside the ternary, not on the result: a mutant
without #location must render as empty, not as the string "nil".
120 |
# File 'lib/henitai/integration/child_debug_log.rb', line 120 def location_of(mutant) = mutant.respond_to?(:location) ? mutant.location.inspect : nil |
#mutant_meta(mutant) ⇒ void
This method returns an undefined value.
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/henitai/integration/child_debug_log.rb', line 64 def (mutant) return unless enabled? write( "#{PREFIX} mutant_meta stableId=#{value_of(mutant, :stable_id)}\n" \ "#{PREFIX} mutant_meta operator=#{value_of(mutant, :operator)}\n" \ "#{PREFIX} mutant_meta subject=#{subject_expression_of(mutant)}\n" \ "#{PREFIX} mutant_meta location=#{location_of(mutant)}\n" ) end |
#rspec_exit(status) ⇒ void
This method returns an undefined value.
43 44 45 |
# File 'lib/henitai/integration/child_debug_log.rb', line 43 def rspec_exit(status) write("#{PREFIX} RSpec result=#{status.inspect}") end |
#rspec_trace(test_files:, rspec_options:, rspec_argv:) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/henitai/integration/child_debug_log.rb', line 30 def rspec_trace(test_files:, rspec_options:, rspec_argv:) return unless enabled? write( "#{PREFIX} cwd=#{Dir.pwd}\n" \ "#{PREFIX} files_exist=#{test_files.map { |file| [file, File.exist?(file)] }.inspect}\n" \ "#{PREFIX} loaded_features_check=#{@loaded_features.map(test_files).inspect}\n" \ "#{PREFIX} test_files=#{test_files.inspect}\n" \ "#{PREFIX} rspec_options=#{.inspect}\n" \ "#{PREFIX} rspec_argv=#{rspec_argv.inspect}" ) end |
#rspec_world_example_count ⇒ Integer?
100 101 102 103 104 |
# File 'lib/henitai/integration/child_debug_log.rb', line 100 def rspec_world_example_count ::RSpec.world.example_count rescue StandardError nil end |
#subject_expression_of(mutant) ⇒ String?
122 123 124 125 126 |
# File 'lib/henitai/integration/child_debug_log.rb', line 122 def subject_expression_of(mutant) return nil unless mutant.respond_to?(:subject) && mutant.subject.respond_to?(:expression) mutant.subject.expression end |
#thread_dump(reason) ⇒ void
This method returns an undefined value.
93 94 95 96 97 98 |
# File 'lib/henitai/integration/child_debug_log.rb', line 93 def thread_dump(reason) return unless enabled? write("#{PREFIX} thread_dump reason=#{reason}") Thread.list.each_with_index { |thread, index| dump_thread(thread, index) } end |
#timeout_signal_sent(pid) ⇒ void
This method returns an undefined value.
89 90 91 |
# File 'lib/henitai/integration/child_debug_log.rb', line 89 def timeout_signal_sent(pid) write("#{PREFIX} timeout_signal_sent pid=#{pid}") end |
#value_of(mutant, name) ⇒ Object
116 |
# File 'lib/henitai/integration/child_debug_log.rb', line 116 def value_of(mutant, name) = mutant.respond_to?(name) ? mutant.public_send(name) : nil |
#write(message) ⇒ void
This method returns an undefined value.
23 24 25 26 27 28 |
# File 'lib/henitai/integration/child_debug_log.rb', line 23 def write() return unless enabled? io.puts() io.flush end |