lib/test_queue/iterator.rb in test-queue-0.2.13 vs lib/test_queue/iterator.rb in test-queue-0.3.0
- old
+ new
@@ -1,54 +1,74 @@
module TestQueue
class Iterator
- attr_reader :stats, :sock
+ attr_reader :sock
- def initialize(sock, suites, filter=nil)
+ def initialize(test_framework, sock, filter=nil, early_failure_limit: nil)
+ @test_framework = test_framework
@done = false
- @stats = {}
+ @suite_stats = []
@procline = $0
@sock = sock
- @suites = suites
@filter = filter
if @sock =~ /^(.+):(\d+)$/
@tcp_address = $1
@tcp_port = $2.to_i
end
+ @failures = 0
+ @early_failure_limit = early_failure_limit
end
def each
fail "already used this iterator. previous caller: #@done" if @done
while true
- client = connect_to_master('POP')
+ # If we've hit too many failures in one worker, assume the entire
+ # test suite is broken, and notify master so the run
+ # can be immediately halted.
+ if @early_failure_limit && @failures >= @early_failure_limit
+ connect_to_master("KABOOM")
+ break
+ else
+ client = connect_to_master('POP')
+ end
break if client.nil?
- r, w, e = IO.select([client], nil, [client], nil)
+ _r, _w, e = IO.select([client], nil, [client], nil)
break if !e.empty?
if data = client.read(65536)
client.close
item = Marshal.load(data)
break if item.nil? || item.empty?
- suite = @suites[item]
+ if item == "WAIT"
+ $0 = "#{@procline} - Waiting for work"
+ sleep 0.1
+ next
+ end
+ suite_name, path = item
+ suite = load_suite(suite_name, path)
+ # Maybe we were told to load a suite that doesn't exist anymore.
+ next unless suite
+
$0 = "#{@procline} - #{suite.respond_to?(:description) ? suite.description : suite}"
start = Time.now
if @filter
@filter.call(suite){ yield suite }
else
yield suite
end
- @stats[suite.to_s] = Time.now - start
+ @suite_stats << TestQueue::Stats::Suite.new(suite_name, path, Time.now - start, Time.now)
+ @failures += suite.failure_count if suite.respond_to? :failure_count
else
break
end
end
rescue Errno::ENOENT, Errno::ECONNRESET, Errno::ECONNREFUSED
ensure
@done = caller.first
- File.open("/tmp/test_queue_worker_#{$$}_stats", "wb") do |f|
- f.write Marshal.dump(@stats)
+ File.open("/tmp/test_queue_worker_#{$$}_suites", "wb") do |f|
+ Marshal.dump(@suite_stats, f)
end
end
def connect_to_master(cmd)
sock =
@@ -65,8 +85,19 @@
include Enumerable
def empty?
false
+ end
+
+ def load_suite(suite_name, path)
+ @loaded_suites ||= {}
+ suite = @loaded_suites[suite_name]
+ return suite if suite
+
+ @test_framework.suites_from_file(path).each do |name, suite|
+ @loaded_suites[name] = suite
+ end
+ @loaded_suites[suite_name]
end
end
end