Class: Henitai::TimeoutCalibrator

Inherits:
Object
  • Object
show all
Defined in:
lib/henitai/timeout_calibrator.rb,
sig/henitai.rbs

Overview

Derives a per-mutant timeout from measured per-test-file durations.

The calibrated value is multiplier × sum(durations of the selected test files), clamped to a floor so a near-instant baseline doesn't flag normal jitter as a timeout. Returns nil — caller falls back to the static default — when any selected test lacks timing data, so a partially measured run is treated as uncalibratable rather than under-estimated.

Constant Summary collapse

FLOOR_SECONDS =

Returns:

  • (Float)
2.0

Instance Method Summary collapse

Constructor Details

#initialize(timing_source:, multiplier:) ⇒ TimeoutCalibrator

Returns a new instance of TimeoutCalibrator.

Parameters:

  • timing_source (#call)

    returns a Hash of test file path to wall-clock seconds; resolved lazily on first use.

  • multiplier (Numeric)
  • timing_source: (Object)
  • multiplier: (Object)


17
18
19
20
# File 'lib/henitai/timeout_calibrator.rb', line 17

def initialize(timing_source:, multiplier:)
  @timing_source = timing_source
  @multiplier = multiplier
end

Instance Method Details

#durationsHash[String, untyped]

Returns:

  • (Hash[String, untyped])


36
37
38
# File 'lib/henitai/timeout_calibrator.rb', line 36

def durations
  @durations ||= (@timing_source.call || {}).transform_keys { |key| normalize(key) }
end

#normalize(path) ⇒ String

Parameters:

  • (Object)

Returns:

  • (String)


40
41
42
# File 'lib/henitai/timeout_calibrator.rb', line 40

def normalize(path)
  File.expand_path(path.to_s)
end

#timeout_for(test_files) ⇒ Float?

Parameters:

  • test_files (Array<String>)
  • (Object)

Returns:

  • (Float, nil)


24
25
26
27
28
29
30
31
32
# File 'lib/henitai/timeout_calibrator.rb', line 24

def timeout_for(test_files)
  files = Array(test_files)
  return nil if files.empty? || durations.empty?

  baselines = files.map { |file| durations[normalize(file)] }
  return nil if baselines.any?(&:nil?)

  [@multiplier * baselines.sum, FLOOR_SECONDS].max
end