class FuzzBert::Executor
Constants
- DEFAULT_ARGS
- DEFAULT_HANDLER
- DEFAULT_LIMIT
- DEFAULT_POOL_SIZE
- DEFAULT_SLEEP_DELAY
Attributes
handler[R]
limit[R]
pool_size[R]
sleep_delay[R]
Public Class Methods
new(suites, args = DEFAULT_ARGS)
click to toggle source
# File lib/fuzzbert/executor.rb, line 17 def initialize(suites, args = DEFAULT_ARGS) raise ArgumentError.new("No test cases were passed") unless suites args ||= DEFAULT_ARGS @pool_size = args[:pool_size] || DEFAULT_POOL_SIZE @limit = args[:limit] || DEFAULT_LIMIT @handler = args[:handler] || DEFAULT_HANDLER.new @sleep_delay = args[:sleep_delay] || DEFAULT_SLEEP_DELAY @data_cache = {} @n = 0 @exiting = false @producer = DataProducer.new(suites) end
Public Instance Methods
run()
click to toggle source
# File lib/fuzzbert/executor.rb, line 31 def run trap_child_exit trap_interrupt @pool_size.times { run_instance(*@producer.next) } @running = true @limit == -1 ? sleep : conditional_sleep end
Private Instance Methods
conditional_sleep()
click to toggle source
# File lib/fuzzbert/executor.rb, line 125 def conditional_sleep sleep @sleep_delay until !@running end
graceful_exit()
click to toggle source
# File lib/fuzzbert/executor.rb, line 107 def graceful_exit puts "\nExiting...Interrupt again to exit immediately" begin while Process.wait; end rescue Errno::ECHILD end exit 0 end
handle(error_data)
click to toggle source
# File lib/fuzzbert/executor.rb, line 116 def handle(error_data) @handler.handle(error_data) end
interrupted(status)
click to toggle source
# File lib/fuzzbert/executor.rb, line 120 def interrupted(status) return false if status.exited? status.termsig == nil || status.termsig == 2 end
limit_reached?()
click to toggle source
# File lib/fuzzbert/executor.rb, line 95 def limit_reached? @limit == -1 || @n < @limit end
run_instance(description, test, generator)
click to toggle source
# File lib/fuzzbert/executor.rb, line 42 def run_instance(description, test, generator) data = generator.to_data pid = fork do begin test.run(data) rescue StandardError abort end end id = "#{description}/#{generator.description}" @data_cache[pid] = [id, data] end
start_new_child()
click to toggle source
# File lib/fuzzbert/executor.rb, line 86 def start_new_child @n += 1 if limit_reached? run_instance(*@producer.next) else @running = false end end
status_failed?(status)
click to toggle source
# File lib/fuzzbert/executor.rb, line 82 def status_failed?(status) !status.success? && !interrupted(status) end
trap_child_exit()
click to toggle source
# File lib/fuzzbert/executor.rb, line 55 def trap_child_exit trap(:CHLD) do while_child_exits do |exitval| pid = exitval[0] status = exitval[1] data_ary = @data_cache.delete(pid) handle({ id: data_ary[0], data: data_ary[1], pid: pid, status: status }) if status_failed?(status) start_new_child end end end
trap_interrupt()
click to toggle source
# File lib/fuzzbert/executor.rb, line 99 def trap_interrupt trap(:INT) do exit! (1) if @exiting @exiting = true graceful_exit end end
while_child_exits() { |exitval| ... }
click to toggle source
# File lib/fuzzbert/executor.rb, line 74 def while_child_exits while exitval = Process.wait2(-1, Process::WNOHANG) yield exitval end rescue Errno::ECHILD # fine end