Skip to content

Commit 9e81784

Browse files
committed
Fail runner when test run is expired
1 parent d674e82 commit 9e81784

File tree

4 files changed

+65
-1
lines changed

4 files changed

+65
-1
lines changed

ruby/lib/ci/queue/redis/base.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module Redis
55
class Base
66
include Common
77

8+
TEN_MINUTES = 60 * 10
89
CONNECTION_ERRORS = [
910
::Redis::BaseConnectionError,
1011
::SocketError, # https://github.com/redis/redis-rb/pull/631
@@ -20,6 +21,15 @@ def exhausted?
2021
queue_initialized? && size == 0
2122
end
2223

24+
def expired?
25+
if (created_at = redis.get(key('master-created-at')))
26+
(created_at.to_f + config.redis_ttl + TEN_MINUTES) < Time.now.to_f
27+
else
28+
# if there is no created at set anymore we assume queue is expired
29+
true
30+
end
31+
end
32+
2333
def size
2434
redis.multi do |transaction|
2535
transaction.llen(key('queue'))

ruby/lib/ci/queue/redis/worker.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,12 @@ def push(tests)
202202
transaction.lpush(key('queue'), tests) unless tests.empty?
203203
transaction.set(key('total'), @total)
204204
transaction.set(key('master-status'), 'ready')
205+
transaction.set(key('master-created-at'), Time.now.to_f)
205206

206207
transaction.expire(key('queue'), config.redis_ttl)
207208
transaction.expire(key('total'), config.redis_ttl)
208209
transaction.expire(key('master-status'), config.redis_ttl)
210+
transaction.expire(key('master-created-at'), config.redis_ttl)
209211
end
210212
end
211213
register

ruby/lib/minitest/queue/runner.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ def retry_command
4747
end
4848

4949
def run_command
50-
if queue.retrying?
50+
if queue.retrying? || retry?
51+
if queue.expired?
52+
abort! "The test run is too old and can't be retried"
53+
end
5154
reset_counters
5255
retry_queue = queue.retry_queue
5356
if retry_queue.exhausted?
@@ -546,6 +549,11 @@ def abort!(message)
546549
puts red(message)
547550
exit! 1 # exit! is required to avoid minitest at_exit callback
548551
end
552+
553+
def retry?
554+
ENV["BUILDKITE_RETRY_COUNT"].to_i > 0 ||
555+
ENV["SEMAPHORE_PIPELINE_RERUN"] == "true"
556+
end
549557
end
550558
end
551559
end

ruby/test/integration/minitest_redis_test.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,50 @@ def test_retry_success
217217
assert_equal 'All tests were ran already', output
218218
end
219219

220+
def test_retry_fails_when_test_run_is_expired
221+
out, err = capture_subprocess_io do
222+
system(
223+
@exe, 'run',
224+
'--queue', @redis_url,
225+
'--seed', 'foobar',
226+
'--build', '1',
227+
'--worker', '1',
228+
'--timeout', '1',
229+
'--max-requeues', '1',
230+
'--requeue-tolerance', '1',
231+
'-Itest',
232+
'test/passing_test.rb',
233+
chdir: 'test/fixtures/',
234+
)
235+
end
236+
assert_empty err
237+
output = normalize(out.lines.last.strip)
238+
assert_equal 'Ran 100 tests, 100 assertions, 0 failures, 0 errors, 0 skips, 0 requeues in X.XXs', output
239+
240+
one_day = 60 * 60 * 24
241+
key = ['build', "1", "master-created-at"].join(':')
242+
@redis.set(key, Time.now - one_day)
243+
244+
out, err = capture_subprocess_io do
245+
system(
246+
@exe, 'run',
247+
'--queue', @redis_url,
248+
'--seed', 'foobar',
249+
'--build', '1',
250+
'--worker', '1',
251+
'--timeout', '1',
252+
'--max-requeues', '1',
253+
'--requeue-tolerance', '1',
254+
'-Itest',
255+
'test/passing_test.rb',
256+
chdir: 'test/fixtures/',
257+
)
258+
end
259+
assert_empty err
260+
output = normalize(out.lines.last.strip)
261+
assert_equal "The test run is too old and can't be retried", output
262+
end
263+
220264
def test_retry_report
221265
# Run first worker, failing all tests
222266
out, err = capture_subprocess_io do

0 commit comments

Comments
 (0)